Skip to main content

Overview

By default, each /chat/completions request is stateless. Send store: true and OkraPDF creates a server-side session that accumulates message history. Follow-up requests only need the new user message — prior context is loaded automatically.
OpenAI-compatible. store and metadata are both official OpenAI fields. No invented parameters.

How it works

Step 1: Start a session

Send "store": true to create a session. The response includes metadata.session_id.
curl https://api.okrapdf.com/document/$DOC_ID/chat/completions \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{"role": "user", "content": "Summarize this document in 2 sentences."}],
    "store": true
  }'
{
  "id": "chatcmpl-abc123",
  "metadata": { "session_id": "sess_b3dc7753bac57dc633010d48" },
  "choices": [{
    "message": { "role": "assistant", "content": "This is IRS Form W-9..." },
    "finish_reason": "stop"
  }]
}

Step 2: Follow up

Pass the session_id in metadata. Only send the new user message — the server prepends prior history.
curl https://api.okrapdf.com/document/$DOC_ID/chat/completions \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{"role": "user", "content": "What certifications does the signer make?"}],
    "metadata": { "session_id": "sess_b3dc7753bac57dc633010d48" }
  }'
The assistant now has full context from turn 1 and answers accordingly.

Step 3: Manage sessions

# List all sessions for this document
curl https://api.okrapdf.com/document/$DOC_ID/sessions \
  -H "Authorization: Bearer $OKRA_API_KEY"

# Get session metadata
curl https://api.okrapdf.com/document/$DOC_ID/sessions/sess_xxx \
  -H "Authorization: Bearer $OKRA_API_KEY"

# Delete a session
curl -X DELETE https://api.okrapdf.com/document/$DOC_ID/sessions/sess_xxx \
  -H "Authorization: Bearer $OKRA_API_KEY"

With the OpenAI SDK

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: `https://api.okrapdf.com/document/${docId}`,
  apiKey: process.env.OKRA_API_KEY,
});

// Turn 1: start session
const turn1 = await client.chat.completions.create({
  model: "kimi-k2p5",
  store: true,
  messages: [{ role: "user", content: "Summarize this document." }],
});

const sessionId = (turn1 as any).metadata?.session_id;

// Turn 2: follow up (server loads prior context)
const turn2 = await client.chat.completions.create({
  model: "kimi-k2p5",
  messages: [{ role: "user", content: "What tables are on page 3?" }],
  metadata: { session_id: sessionId },
} as any);

Behavior matrix

metadata.session_idstoremessagesBehavior
absentabsent/falserequiredStateless (default, unchanged)
absenttruerequiredAuto-create session, return session_id
present1 messageResume: prepend history, append new message
presentfull arrayReplace: use provided messages, update session

Security

  • Sessions are scoped to the API key’s user_id — you cannot load another user’s session
  • Session data is never exposed to the LLM’s query_sql tool
  • Sessions expire after 24 hours of inactivity (lazy GC)
  • DELETE /sessions/:id immediately removes all stored messages