> ## 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.

# TypeScript SDK

> Session-first SDK + curl-first contract for document chat and extraction.

## Install

```bash theme={null}
npm install @okrapdf/runtime
```

## Minimal Surface

`@okrapdf/runtime` intentionally exposes a small API:

* `createOkra(...)` -> returns `okra.sessions`
* `doc(...)` -> deterministic URL builder

No class constructor is required in normal usage.

## Identity model

* `documentId` is the durable identity.
* `workflowId` represents a processing run (upload/reparse execution).
* Sessions are document-scoped handles; they are not per-run handles.

See [Document + Run Model](/developers/document-run-model).

## Quick Start

```ts theme={null}
import { createOkra } from '@okrapdf/runtime';

const okra = createOkra({ apiKey: process.env.OKRA_API_KEY });

const session = await okra.sessions.create('./report.pdf', {
  wait: true,
  model: 'kimi-k2p5',
});

const { answer } = await session.prompt('What is total revenue?');
console.log(answer);
```

## Attach Existing Document

```ts theme={null}
const session = okra.sessions.from('ocr_existing_doc_id', {
  model: 'kimi-k2p5',
});

const { answer } = await session.prompt('Summarize key risks');
```

## Structured Output (Zod)

```ts theme={null}
import { z } from 'zod';

const Invoice = z.object({
  vendor: z.string(),
  total: z.number(),
  currency: z.string().optional(),
});

const result = await session.prompt('Extract invoice fields', {
  schema: Invoice,
});

console.log(result.data?.vendor, result.data?.total);
```

## Streaming

```ts theme={null}
for await (const event of session.stream('Summarize in 3 bullets')) {
  if (event.type === 'text_delta') process.stdout.write(event.text);
  if (event.type === 'done') console.log('\nfinal:', event.answer);
}
```

## Share Links (Viewer vs Admin)

```ts theme={null}
const viewer = await session.shareLink({
  role: 'viewer',
  expiresInMs: 24 * 60 * 60 * 1000,
});

const admin = await session.shareLink({
  role: 'admin',
  expiresInMs: 24 * 60 * 60 * 1000,
});

console.log(viewer.links.markdown, viewer.links.pdf);
console.log(admin.links.markdown, admin.links.pdf);
```

`viewer` links apply redacted/public view policies.
`admin` links provide full-access lens for authorized operators.

## Deterministic URL Builder

```ts theme={null}
import { doc } from '@okrapdf/runtime';

const d = doc(session.id, { fileName: 'report.pdf' });

console.log(d.pg[1].png());                          // page 1 as PNG
console.log(d.pg[1].md());                            // page 1 as markdown
console.log(d.entities.tables[0].url({ format: 'csv' }));
```

## Curl-First Workflow (Reference Contract)

Use this when validating pipelines before wiring app code.

### 1) Upload by URL

```bash theme={null}
curl -X POST "https://api.okrapdf.com/document/ocr-demo/upload-url" \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/report.pdf",
    "visibility": "private",
    "redact": {
      "pii": {
        "preset": "hipaa",
        "patterns": ["SSN", "EMAIL", "PHONE_US"]
      }
    }
  }'
```

### 2) Poll status

```bash theme={null}
curl "https://api.okrapdf.com/document/ocr-demo/status" \
  -H "Authorization: Bearer $OKRA_API_KEY"
```

Wait until `phase` is `complete` (or `awaiting_review`).

### 3) Ask question

```bash theme={null}
curl -X POST "https://api.okrapdf.com/document/ocr-demo/completion" \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "What is total revenue?",
    "model": "kimi-k2p5"
  }'
```

### 4) Stream response

```bash theme={null}
curl -N -X POST "https://api.okrapdf.com/document/ocr-demo/completion" \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Summarize in 3 bullets",
    "stream": true,
    "model": "kimi-k2p5"
  }'
```

### 5) Create scoped share link

```bash theme={null}
curl -X POST "https://api.okrapdf.com/document/ocr-demo/share-link" \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "viewer",
    "expiresInMs": 86400000
  }'
```

Use `"role":"admin"` for full-access links.

## API Reference

```ts theme={null}
createOkra({ apiKey, baseUrl?, sharedSecret?, fetch? }) => okra

okra.sessions.create(sourceOrDocId, { wait?, model?, upload?, waitOptions? }) => session
okra.sessions.from(docId, { model? }) => session

session.id
session.model
session.modelEndpoint
session.state()
session.setModel(model)
session.status()
session.wait()
session.pages()
session.page(n)
session.entities()
session.query(sql)
session.prompt(query)
session.prompt(query, { schema })
session.stream(query)
session.publish()
session.shareLink({ role, expiresInMs, maxViews, label })
```
