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

# Public Completion API

> Turn any document into a shareable Q&A endpoint with a clean URL -- no auth needed for consumers

## Turn documents into APIs

Extract a PDF and get a clean REST endpoint anyone can POST questions to. No API keys, no auth headers, no tokens in query strings.

```bash theme={null}
curl 'https://api.okrapdf.com/v1/documents/amcor-q4-2023-a3f8b2/completion' \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"What was total revenue?"}'
```

```json theme={null}
{
  "answer": "Total revenue for fiscal 2023 was $14,694 million...",
  "usage": { "costUsd": 0.0015 }
}
```

That's it. A normal REST endpoint backed by your extracted document.

## How it works

<Steps>
  <Step title="Extract your document">
    Upload via web app, CLI, or SDK. OkraPDF extracts all text, tables, and figures into a queryable store.
  </Step>

  <Step title="Create a public link">
    Generate a share link with `role: 'ask'`. OkraPDF creates a human-readable slug from your filename.

    ```typescript theme={null}
    const session = okra.sessions.from(docId);
    const link = await session.shareLink({
      role: 'ask',
      maxViews: 1000,
    });
    // link.completionUrl =>
    // https://api.okrapdf.com/v1/documents/quarterly-report-a3f8b2/completion
    ```
  </Step>

  <Step title="Share the URL">
    Give the URL to anyone -- embed it in your app, share with clients, use in demos. No API key needed to call it.
  </Step>
</Steps>

## Clean, shareable URLs

Every ask link gets a human-readable slug derived from the document filename:

| Document                    | Public endpoint                                           |
| --------------------------- | --------------------------------------------------------- |
| `amcor-2023q4-earnings.pdf` | `.../v1/documents/amcor-2023q4-earning-a3f8b2/completion` |
| `NVIDIA 10-K Report.pdf`    | `.../v1/documents/nvidia-10-k-report-c7d1e4/completion`   |
| `invoice-march.pdf`         | `.../v1/documents/invoice-march-8b3f2a/completion`        |

No tokens in the URL. The slug IS the credential. Revoke a link and its slug stops working instantly.

## Access controls

You stay in control of every endpoint you create:

<CardGroup cols={2}>
  <Card title="Usage limits" icon="gauge">
    Set `maxViews` to cap total requests. Link expires automatically when the limit is reached.
  </Card>

  <Card title="Kill switch" icon="power-off">
    Revoke any link instantly. Returns `410 Gone` on the next request.
  </Card>

  <Card title="TTL" icon="clock">
    Set `expiresInMs` for time-limited access. Demo for a client call, then it's gone.
  </Card>

  <Card title="Rate limiting" icon="shield">
    10 requests per minute per slug, built in. No configuration needed.
  </Card>
</CardGroup>

Additional controls: password protection, IP lock (bind to first requester), and campaign labels for analytics grouping.

## Analytics

Track usage per link:

```bash theme={null}
curl 'https://api.okrapdf.com/document/ocr-abc123/analytics?period=7d' \
  -H 'Authorization: Bearer okra_...'
```

```json theme={null}
{
  "askRequests": 47,
  "totalCostUsd": 0.23,
  "byLink": [
    { "tokenHint": "sig_xxx...", "campaign": "blog-post", "count": 32 },
    { "tokenHint": "sig_yyy...", "campaign": "demo", "count": 15 }
  ]
}
```

Create multiple links per document with different campaigns to track which channel drives usage.

## Use cases

<AccordionGroup>
  <Accordion title="Embed Q&A in your product">
    Your backend creates the link once. Your frontend calls it directly -- CORS is set to `*`.

    ```typescript theme={null}
    const res = await fetch(link.completionUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ prompt: userQuestion }),
    });
    const { answer } = await res.json();
    ```
  </Accordion>

  <Accordion title="Demo endpoint for sales calls">
    Create a link with `maxViews: 50` and `expiresInMs: 86400000` (24h). Share the curl command in the meeting. It stops working after the call.
  </Accordion>

  <Accordion title="Client-facing document chatbot">
    Upload a client's report, create an ask link, share the URL. They can ask questions about their own document without needing an OkraPDF account.
  </Accordion>

  <Accordion title="Internal knowledge base">
    Upload policy documents, create ask links, embed them in Slack bots or internal tools. Employees query documents with plain HTTP.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Cookbook: full walkthrough" icon="book" href="/cookbook/public-completion">
    Step-by-step code with SDK examples
  </Card>

  <Card title="SDK reference" icon="code" href="/developers/sdk">
    session-first API reference
  </Card>
</CardGroup>
