> ## Documentation Index
> Fetch the complete documentation index at: https://zarna.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Reports API

> AI-powered report generation with real-time streaming

## Overview

The Reports API generates comprehensive AI-powered reports with real-time streaming using Server-Sent Events (SSE).

**Base Path**: `/api/reports`

## Endpoints

### Generate Report (Streaming)

Generate a report with real-time streaming.

```bash theme={null}
POST /api/reports/generate
```

**Request Body**:

```json theme={null}
{
  "company_id": "550e8400-e29b-41d4-a716-446655440000",
  "report_type": "due_diligence",
  "sections": [
    "company_overview",
    "financial_analysis",
    "market_analysis",
    "risk_assessment",
    "recommendations"
  ],
  "include_comparisons": true,
  "time_period": "2024"
}
```

**Report Types**:

* `due_diligence` - Complete DD report
* `financial_analysis` - Financial deep dive
* `market_analysis` - Market and competitive analysis
* `executive_summary` - High-level overview
* `investment_memo` - Investment committee memo

**Example Request**:

```bash theme={null}
curl -X POST \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "company_id": "550e8400-e29b-41d4-a716-446655440000",
    "report_type": "due_diligence"
  }' \
  "http://localhost:8000/api/reports/generate"
```

**Response** (Server-Sent Events):

```
data: {"type": "start", "report_id": "aa0e8400-e29b-41d4-a716-446655440555", "timestamp": "2024-01-22T10:30:00Z"}

data: {"type": "section_start", "section": "company_overview"}

data: {"type": "chunk", "content": "# Company Overview\n\nAcme Corp is a leading technology"}

data: {"type": "chunk", "content": " company specializing in enterprise SaaS solutions."}

data: {"type": "section_complete", "section": "company_overview"}

data: {"type": "section_start", "section": "financial_analysis"}

data: {"type": "chunk", "content": "# Financial Analysis\n\nRevenue for 2024: $15M"}

data: {"type": "chunk", "content": "\nEBITDA: $4.5M (30% margin)"}

data: {"type": "section_complete", "section": "financial_analysis"}

data: {"type": "complete", "report_id": "aa0e8400-e29b-41d4-a716-446655440555", "total_time": 12.5}
```

### Get Report

Retrieve a previously generated report.

```bash theme={null}
GET /api/reports/{report_id}
```

**Example Request**:

```bash theme={null}
curl -H "Authorization: Bearer TOKEN" \
  "http://localhost:8000/api/reports/aa0e8400-e29b-41d4-a716-446655440555"
```

**Response**:

```json theme={null}
{
  "id": "aa0e8400-e29b-41d4-a716-446655440555",
  "company_id": "550e8400-e29b-41d4-a716-446655440000",
  "company_name": "Acme Corp",
  "report_type": "due_diligence",
  "status": "completed",
  "content": "# Due Diligence Report\n\n## Company Overview\n\nAcme Corp...",
  "sections": {
    "company_overview": "...",
    "financial_analysis": "...",
    "market_analysis": "...",
    "risk_assessment": "...",
    "recommendations": "..."
  },
  "metadata": {
    "pages": 45,
    "word_count": 12500,
    "generated_at": "2024-01-22T10:30:00Z",
    "generation_time": 12.5
  },
  "created_at": "2024-01-22T10:30:00Z"
}
```

### List Reports

Get a list of all generated reports.

```bash theme={null}
GET /api/reports
```

**Query Parameters**:

| Parameter     | Type    | Description           |
| ------------- | ------- | --------------------- |
| `page`        | integer | Page number           |
| `page_size`   | integer | Items per page        |
| `company_id`  | UUID    | Filter by company     |
| `report_type` | string  | Filter by report type |
| `status`      | string  | Filter by status      |

**Response**:

```json theme={null}
{
  "data": [
    {
      "id": "aa0e8400-e29b-41d4-a716-446655440555",
      "company_name": "Acme Corp",
      "report_type": "due_diligence",
      "status": "completed",
      "created_at": "2024-01-22T10:30:00Z"
    }
  ],
  "total": 15,
  "page": 1,
  "page_size": 20
}
```

### Export Report

Export report in various formats.

```bash theme={null}
GET /api/reports/{report_id}/export?format={format}
```

**Formats**:

* `pdf` - PDF document
* `docx` - Word document
* `html` - HTML page
* `json` - Structured JSON

**Example Request**:

```bash theme={null}
curl -H "Authorization: Bearer TOKEN" \
  "http://localhost:8000/api/reports/aa0e8400-e29b-41d4-a716-446655440555/export?format=pdf" \
  -O report.pdf
```

## Streaming Integration

### Frontend (TypeScript)

```typescript theme={null}
async function streamReport(companyId: string) {
  const response = await fetch('http://localhost:8000/api/reports/generate', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      'Accept': 'text/event-stream'
    },
    body: JSON.stringify({
      company_id: companyId,
      report_type: 'due_diligence'
    })
  })

  const reader = response.body!.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    const chunk = decoder.decode(value)
    const lines = chunk.split('\n')

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = JSON.parse(line.slice(6))

        if (data.type === 'chunk') {
          // Append content to UI
          setReportContent(prev => prev + data.content)
        } else if (data.type === 'complete') {
          // Report generation complete
          console.log(`Report completed in ${data.total_time}s`)
        }
      }
    }
  }
}
```

### React Hook

```typescript theme={null}
import { useState, useEffect } from 'react'

export function useReportStream(companyId: string, reportType: string) {
  const [content, setContent] = useState('')
  const [isStreaming, setIsStreaming] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const startStream = async () => {
    setIsStreaming(true)
    setContent('')
    setError(null)

    try {
      const response = await fetch('/api/reports/generate', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
          'Accept': 'text/event-stream'
        },
        body: JSON.stringify({
          company_id: companyId,
          report_type: reportType
        })
      })

      const reader = response.body!.getReader()
      const decoder = new TextDecoder()

      while (true) {
        const { done, value } = await reader.read()
        if (done) break

        const chunk = decoder.decode(value)
        const lines = chunk.split('\n')

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = JSON.parse(line.slice(6))

            if (data.type === 'chunk') {
              setContent(prev => prev + data.content)
            } else if (data.type === 'complete') {
              setIsStreaming(false)
            } else if (data.type === 'error') {
              setError(data.message)
              setIsStreaming(false)
            }
          }
        }
      }
    } catch (err) {
      setError('Failed to generate report')
      setIsStreaming(false)
    }
  }

  return { content, isStreaming, error, startStream }
}
```

## Event Types

| Event Type         | Description                | Data                            |
| ------------------ | -------------------------- | ------------------------------- |
| `start`            | Report generation started  | `{type, report_id, timestamp}`  |
| `section_start`    | Section generation started | `{type, section}`               |
| `chunk`            | Content chunk              | `{type, content}`               |
| `section_complete` | Section finished           | `{type, section}`               |
| `complete`         | Report finished            | `{type, report_id, total_time}` |
| `error`            | Error occurred             | `{type, message, error_code}`   |

## Examples

### Python

```python theme={null}
import requests
import json

def stream_report(company_id: str, token: str):
    response = requests.post(
        'http://localhost:8000/api/reports/generate',
        headers={
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json',
            'Accept': 'text/event-stream'
        },
        json={
            'company_id': company_id,
            'report_type': 'due_diligence'
        },
        stream=True
    )

    for line in response.iter_lines():
        if line:
            line = line.decode('utf-8')
            if line.startswith('data: '):
                data = json.loads(line[6:])

                if data['type'] == 'chunk':
                    print(data['content'], end='', flush=True)
                elif data['type'] == 'complete':
                    print(f"\n\nReport completed in {data['total_time']}s")
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Report Generation Service" icon="gear" href="/backend/services/report-generation">
    Learn about the report generation pipeline
  </Card>

  <Card title="Companies API" icon="building" href="/api-reference/companies">
    Company endpoints for report generation
  </Card>

  <Card title="Agentic Chat" icon="messages" href="/api-reference/agentic-chat">
    AI chat system
  </Card>

  <Card title="Files API" icon="file" href="/api-reference/files">
    Process documents for reports
  </Card>
</CardGroup>
