Skip to main content

Install

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.

Quick Start

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

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

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

Structured Output (Zod)

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

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);
}
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

import { doc } from '@okrapdf/runtime';

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

console.log(d.thumbnail.url());
console.log(d.pages[1].image.url());
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

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

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

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

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"
  }'
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

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 })