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

# Exporting Artifacts to PDF

> Enable users to download generated reports and slides as PDF files

C1 provides a dedicated API endpoint to convert any generated artifact into a downloadable PDF file. This guide covers the end-to-end process, which involves creating an API route on your backend and connecting it to the C1 frontend components.

### How it Works

The PDF export process involves two main steps and is designed to keep your API keys secure:

1. **Frontend Trigger:** The user initiates the export from the UI. The `<C1Component>` provides a `exportParams` string to a callback function in your code.
2. **Backend Endpoint:** Your frontend sends these `exportParams` to a dedicated endpoint on your own backend. Your backend then securely calls the C1 PDF Export API with your API key and streams the resulting PDF file back to the user's browser for download.

<Note>
  You must create a backend endpoint. The C1 PDF Export API cannot be called directly from the frontend as it would expose your secret API key.
</Note>

### Implement the Backend Endpoint

Your backend needs an API route that will receive the request from your frontend, call the C1 API, and forward the PDF response.

**PDF Export API Endpoint:** `POST /v1/artifact/pdf/export`

<CodeGroup dropdown>
  ```typescript app/api/export-pdf/route.ts (Next.js App Router) theme={null}
  import { NextRequest, NextResponse } from 'next/server';

  export async function POST(req: NextRequest) {
    const { exportParams } = await req.json();

    try {
      const pdfResponse = await fetch('https://api.thesys.dev/v1/artifact/pdf/export', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.THESYS_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ exportParams }),
      });

      if (!pdfResponse.ok) {
        throw new Error(`Failed to export PDF: ${pdfResponse.statusText}`);
      }

      // Stream the PDF back to the client
      return new NextResponse(pdfResponse.body, {
        headers: {
          'Content-Type': 'application/pdf',
          'Content-Disposition': 'attachment; filename="artifact.pdf"',
        },
      });

    } catch (error) {
      const message = error instanceof Error ? error.message : 'An unknown error occurred';
      return NextResponse.json({ error: message }, { status: 500 });
    }
  }
  ```

  ```python main.py (FastAPI) theme={null}
  import os
  import httpx
  from fastapi import FastAPI, Request, HTTPException
  from fastapi.responses import StreamingResponse

  app = FastAPI()

  @app.post("/api/export-pdf")
  async def export_artifact_as_pdf(request: Request):
      data = await request.json()
      export_params = data.get("exportParams")

      if not export_params:
          raise HTTPException(status_code=400, detail="exportParams not provided")

      headers = {
          "Authorization": f"Bearer {os.getenv('THESYS_API_KEY')}",
          "Content-Type": "application/json",
      }
      
      async with httpx.AsyncClient() as client:
          # Use a streaming request to handle large files
          async with client.stream(
              "POST",
              "https://api.thesys.dev/v1/artifact/pdf/export",
              headers=headers,
              json={"exportParams": export_params},
          ) as response:
              response.raise_for_status()
              
              # Stream the PDF content back to the client
              return StreamingResponse(
                  response.aiter_bytes(),
                  media_type="application/pdf",
                  headers={"Content-Disposition": "attachment; filename=artifact.pdf"}
              )
  ```
</CodeGroup>

### Implement the Frontend Handler

The `<C1Component>` provides an `exportAsPdf` prop, which accepts a function. This function is called when the user clicks the export button in the artifact's UI. It receives the `exportParams` and a suggested `title` for the file.

Your implementation should call your backend endpoint and use the response to trigger a file download in the browser.

```tsx theme={null}
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";

function ArtifactWithExport({ c1Response }: { c1Response: string }) {
  return (
    <ThemeProvider>
      <C1Component
        c1Response={c1Response}
        exportAsPdf={handleExport}
      />
    </ThemeProvider>
  );
}

const handleExport = async ({ exportParams, title }: { exportParams: string, title: string }) => {
    try {
      // 1. Call your backend endpoint with the exportParams
      const response = await fetch("/api/export-pdf", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ exportParams }),
      });

      if (!response.ok) {
        throw new Error("Failed to download PDF.");
      }

      // 2. Get the PDF data as a blob
      const blob = await response.blob();

      // 3. Create a temporary URL and trigger the download
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      const filename = (title || 'artifact').replace(/\.pdf$/i, '');
      a.download = `${filename}.pdf`;
      document.body.appendChild(a);
      a.click();
      
      // 4. Clean up the temporary URL
      window.URL.revokeObjectURL(url);
      a.remove();

    } catch (error) {
      console.error("Export failed:", error);
      // Handle error, e.g., show a notification to the user
    }
  };
```

#### Usage with `<C1Chat>`

You can also enable PDF export in a conversational context. The `exportAsPdf` function can be passed via the `customizeC1` prop to either `<C1Chat>` or the `useThreadManager` hook.

```tsx theme={null}
<C1Chat
  apiUrl="/api/chat"
  customizeC1={{
    exportAsPdf: handleExport, // Use the same handler function
  }}
/>
```
