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

# Web report integration

# Web Report Integration Guide

This guide explains how to integrate the Deep Research API's **Web Report** feature into your Next.js frontend.

## Authentication

The Deep Research API requires an API key for all analysis endpoints.

### Required Header

```
X-API-Key: your-api-key-here
```

### Environment Variable

Add to your `.env.local`:

```bash theme={null}
NEXT_PUBLIC_SILVIA_DEEP_RESEARCH_API_KEY=your-api-key-here
```

## Overview

The Deep Research API generates two report formats:

| Format | File | Purpose |
| - | - | - |
| **Web Report** | `report_web.md` | Markdown with S3 URLs for images - render natively in React |
| **PDF Report** | `report.pdf` | Professional PDF - offer as download |

## API Endpoint

**Note:** The API endpoint is **synchronous** but long-running (can take 2-5 minutes).\
**Recommended Pattern:** Start the analysis via API, then track progress via Supabase Realtime.

### Start Analysis

`POST https://research.cfosilvia.com/api/analysis`

#### Request Body

```json theme={null}
{
  "question": "Analyze my portfolio risks",
  "clerk_id": "user_2q...",
  "session_id": "optional-custom-session-id" 
}
```

*Tip: Generate `session_id` on the client to subscribe to updates immediately.*

#### Response (Success)

Returned after analysis completes (2-5 mins).

```json theme={null}
{
  "session_id": "abc123",
  "planner_calls": 3,
  "executor_calls": 45,
  "web_report_calls": 2,
  "report_calls": 5,
  "total_calls": 55,
  "web_report_path": "s3://...",
  "report_path": "s3://...",
  "cache_stats": { ... },
  "estimated_savings": 0.45
}
```

## Integration Flow

1. **Client** generates a unique `session_id`.
2. **Client** subscribes to Supabase `research_sessions` table for this ID.
3. **Client** calls `POST /api/analysis` with the `session_id`.
4. **API** creates the session record and starts processing.
5. **Client** receives live progress updates via Supabase (Phases: Planner → Executor → Web Report → PDF).
6. **API** updates `s3_key` in Supabase when the Web Report is ready (approx. 75% progress).
7. **Client** fetches and renders the markdown report.

## Frontend Implementation (Next.js)

### 1. Start Analysis & Track Progress

```tsx theme={null}
// hooks/useAnalysis.ts
import { useState, useCallback } from "react";
import { v4 as uuidv4 } from 'uuid';
import { supabase } from "@/lib/supabase"; // Your supabase client

export function useAnalysis() {
  const [sessionId, setSessionId] = useState<string | null>(null);
  const [status, setStatus] = useState("idle");
  const [error, setError] = useState<string | null>(null);

  const startAnalysis = useCallback(async (question: string, clerkId: string) => {
    // 1. Generate ID client-side
    const newSessionId = uuidv4().replace(/-/g, '').slice(0, 8); // 8-char hex
    setSessionId(newSessionId);
    setStatus("starting");
    setError(null);

    try {
      // 2. Start API request (Don't await response if you want to unblock UI)
      // We rely on Supabase for the actual completion state
      fetch("https://research.cfosilvia.com/api/analysis", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-API-Key": process.env.NEXT_PUBLIC_SILVIA_DEEP_RESEARCH_API_KEY!,
        },
        body: JSON.stringify({ 
          question, 
          clerk_id: clerkId,
          session_id: newSessionId 
        }),
      }).catch(err => {
        // Handle network errors (timeouts are expected and okay if using Supabase)
        console.warn("API Request completed or timed out:", err);
      });

      setStatus("running");
      
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to start analysis");
      setStatus("error");
    }
  }, []);

  return { startAnalysis, sessionId, status, error };
}
```

### 2. Fetch Report Content

Once Supabase shows `s3_key` is present (see [Supabase Session Tracking](supabase-session-tracking.md)), fetch the markdown content.

**Note:** You should create a secure API route in your Next.js app to proxy S3 requests, rather than exposing AWS credentials on the client.

```tsx theme={null}
// app/api/report/content/route.ts
import { NextResponse } from "next/server";
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({ 
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  }
});

export async function POST(req: Request) {
  const { s3Key } = await req.json();
  
  // s3Key format: "{env}/{clerk_id}/{date}/{session_id}/data/report_web.md"
  // or full path. Adjust logic to extract Key.
  
  // Assuming s3Key is the Key and bucket is in env
  const bucket = process.env.S3_BUCKET_NAME;

  try {
    const command = new GetObjectCommand({
      Bucket: bucket,
      Key: s3Key, 
    });
    
    const response = await s3.send(command);
    const str = await response.Body?.transformToString();
    
    return NextResponse.json({ content: str });
  } catch (e) {
    return NextResponse.json({ error: "Failed to fetch report" }, { status: 500 });
  }
}
```

### 3. Render Markdown

Use `react-markdown` to render the report. The API automatically converts image paths to accessible S3 URLs.

```tsx theme={null}
// components/ReportView.tsx
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

export function ReportView({ markdown }: { markdown: string }) {
  return (
    <article className="prose prose-slate max-w-none dark:prose-invert">
      <ReactMarkdown 
        remarkPlugins={[remarkGfm]}
        components={{
          img: ({node, ...props}) => (
            <img {...props} className="rounded-lg shadow-lg my-6" loading="lazy" />
          ),
          table: ({children}) => (
             <div className="overflow-x-auto my-4">
               <table className="min-w-full border-collapse">{children}</table>
             </div>
          )
        }}
      >
        {markdown}
      </ReactMarkdown>
    </article>
  );
}
```

## Image URLs

The Web Report Agent transforms the raw analysis to include full S3 URLs for charts.

**Example Transformation:**

* **Original:** `![Chart](charts/portfolio.png)`
* **Web Report:** `![Chart](https://prod-deep-research.s3.us-east-1.amazonaws.com/prod/user_123/.../charts/portfolio.png)`

This ensures images render correctly without any extra client-side logic.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.