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.
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);
}
Share Links (Viewer vs Admin)
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.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
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"
}'
5) Create scoped share link
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 })