Skip to main content

Overview

Branching creates a zero-copy fork of a document. The branch is a fully independent document with its own ID, nodes, and lifecycle — mutations on the branch never affect the original. Think of it like git branch: fork, experiment, compare.

Create a branch

curl -X POST https://api.okrapdf.com/v1/documents/$DOC_ID/branch \
  -H "Authorization: Bearer $OKRA_API_KEY"
Response (201 Created):
{
  "id": "doc-a1b2c3d4...",
  "branched_from": "doc-original-id",
  "phase": "complete",
  "urls": {
    "status": "https://api.okrapdf.com/document/doc-a1b2c3d4.../status",
    "markdown": "https://res.okrapdf.com/v1/documents/doc-a1b2c3d4.../full.md",
    "chat": "https://api.okrapdf.com/document/doc-a1b2c3d4.../chat/completions"
  },
  "row_counts": {
    "meta": 26,
    "nodes": 380,
    "edges": 379,
    "page_ledger": 190,
    "vendor_log": 12,
    "document_log": 419
  }
}
The branch is immediately queryable — same phase, same nodes as the original. Typical branch time is ~2s regardless of document size.

List branches

List all branches of a document using the branched_from filter:
curl "https://api.okrapdf.com/v1/documents?branched_from=$DOC_ID" \
  -H "Authorization: Bearer $OKRA_API_KEY"
Response:
{
  "data": [
    {
      "id": "doc-branch-1...",
      "status": "completed",
      "file_name": "boeing-10k.pdf",
      "branched_from": "doc-original-id",
      "total_pages": 190,
      "inserted_at": "2025-03-01T12:00:00.000Z",
      "updated_at": "2025-03-01T12:00:05.000Z"
    },
    {
      "id": "doc-branch-2...",
      "status": "completed",
      "file_name": "boeing-10k.pdf",
      "branched_from": "doc-original-id",
      "total_pages": 190,
      "inserted_at": "2025-03-02T08:30:00.000Z",
      "updated_at": "2025-03-02T08:30:03.000Z"
    }
  ],
  "has_more": false
}
Standard cursor pagination applies (limit, after, before, order).

Delete a branch

Branches are regular documents. Delete them the same way:
curl -X DELETE https://api.okrapdf.com/document/$BRANCH_ID \
  -H "Authorization: Bearer $OKRA_API_KEY"
Deleting a branch does not affect the original document.

Branch + Ingest (replace)

The most common workflow: branch a document, push corrected data with mode: "replace", then compare completions.
# 1. Branch
BRANCH_ID=$(curl -s -X POST https://api.okrapdf.com/v1/documents/$DOC_ID/branch \
  -H "Authorization: Bearer $OKRA_API_KEY" | jq -r '.id')

# 2. Ingest corrected data (replace mode)
curl -X POST https://api.okrapdf.com/document/$BRANCH_ID/ingest \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor": "canonical",
    "mode": "replace",
    "data": {
      "pages": [{
        "pageNumber": 77,
        "blocks": [{
          "type": "table",
          "value": "corrected table content here",
          "children": [...]
        }]
      }]
    }
  }'

# 3. Wait for processing
while [ "$(curl -s https://api.okrapdf.com/document/$BRANCH_ID/status \
  -H "Authorization: Bearer $OKRA_API_KEY" | jq -r '.phase')" != "complete" ]; do
  sleep 2
done

# 4. Query the branch
curl -X POST https://api.okrapdf.com/document/$BRANCH_ID/chat/completions \
  -H "Authorization: Bearer $OKRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"role": "user", "content": "Your question here"}]}'
See Branch + Replace for a full worked example with grading.

Git semantics

GitOkraPDFEndpoint
git branch featureCreate branchPOST /v1/documents/:id/branch
git branchList branchesGET /v1/documents?branched_from=:id
git branch -d featureDelete branchDELETE /document/:id
git merge featureMerge branchComing soon