Page {page.pageNumber ?? page.page}
{page.markdown ?? page.content}
{status.error.message}
; if (!documentId) returnResolving document...
; return ({status.data?.phase ?? 'loading'}
{pages.data.map((page) => ({page.markdown ?? page.content}
{JSON.stringify(data, null, 2)} : null}
{phase ?? document.state?.phase ?? 'connecting'}
; } ``` # TypeScript SDK Source: https://docs.okrapdf.com/developers/sdk Use @okrapdf/sdk for document sessions, files, collections, and workflows. ## Install ```bash theme={null} npm install @okrapdf/sdk ``` ```ts theme={null} import { createOkra, OkraClient } from '@okrapdf/sdk'; import { doc } from '@okrapdf/sdk/doc'; ``` `createOkra(...)` returns an `OkraClient`. Use it when you want workflow defaults or middleware-style options. Use `new OkraClient(...)` when you want the direct class. ## Upload and ask ```ts theme={null} import { createOkra } from '@okrapdf/sdk'; const okra = createOkra({ apiKey: process.env.OKRA_API_KEY }); const session = await okra.sessions.create('./report.pdf', { wait: true, model: 'anthropic/claude-haiku-4.5', }); const { answer, sources } = await session.prompt('What is total revenue?'); console.log(answer); console.log(sources); ``` `sessions.create(...)` accepts local file paths in Node, URLs, `Blob`, `ArrayBuffer`, or `Uint8Array`. Use `sessions.from(documentId)` to attach to an existing document. ## Read pages and entities ```ts theme={null} const status = await session.status(); const pages = await session.pages({ range: '1-3' }); const tables = await session.entities({ type: 'table' }); console.log(status.phase, pages.length, tables.nodes.length); ``` ## Structured output ```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); ``` ## 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); } ``` ## Passive file assets Use `files.upload(...)` when you want to store a PDF first and decide later whether to parse, host, or run a workflow. ```ts theme={null} const file = await okra.files.upload('./invoice.pdf'); console.log(file.id); console.log(file.urls.bytes); ``` ## Host and URL building The SDK exports a deterministic URL builder for document-derived assets: ```ts theme={null} const d = doc(session.id, { fileName: 'report.pdf' }); console.log(d.pg[1].png()); console.log(d.pg[1].md()); console.log(d.full.md()); ``` For clean hosted PDF deployments, call the REST [Host API](/api-reference/host/create-hosted-pdf) or upload through `files.upload(...)` and publish with `/v1/host`. ## Invoice extraction workflow ```ts theme={null} const file = await okra.files.upload('./invoice.pdf'); const run = await okra.runInvoiceExtraction({ inputs: [file.id], quality: 'standard', }); console.log(run.runId, run.exports.csvUrl, run.exports.jsonUrl); ``` ## Dynamic agent workflows The stable SDK surface currently exposes built-in workflows such as invoice extraction. Custom workflow authoring lives in the MCP and REST workflow surfaces: * Use [MCP](/mcp/overview) when an agent should draft, run, and inspect a workflow. * Use `POST /v1/workflows` and `POST /v1/runs` when your app wants to create and run a workflow directly. ## Collections ```ts theme={null} const stream = okra.collections.query( 'col-abc123', 'Extract revenue, net income, and EPS.', ); for await (const event of stream) { console.log(event); } ``` ## API surface ```ts theme={null} createOkra({ apiKey, baseUrl?, sharedSecret?, fetch?, workflow? }) => OkraClient okra.sessions.create(sourceOrDocId, { wait?, model?, upload?, waitOptions? }) => session okra.sessions.from(documentId, { model? }) => session okra.files.upload(input, options?) okra.files.get(fileId) okra.files.list(options?) okra.files.delete(fileId) session.status() session.wait() session.pages({ range? }) session.page(pageNumber) session.entities({ type?, limit?, offset? }) session.prompt(query, { schema?, model? }) session.stream(query, options?) session.publish() session.shareLink({ role, expiresInMs, maxViews, label }) ``` # FAQ Source: https://docs.okrapdf.com/faq Common questions about okraPDF ## Getting Started