> ## 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.

# Branching

> Create independent forks of documents for safe experimentation, A/B testing, and correction workflows.

## 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

```bash theme={null}
curl -X POST https://api.okrapdf.com/v1/documents/$DOC_ID/branch \
  -H "Authorization: Bearer $OKRA_API_KEY"
```

Response (`201 Created`):

```json theme={null}
{
  "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:

```bash theme={null}
curl "https://api.okrapdf.com/v1/documents?branched_from=$DOC_ID" \
  -H "Authorization: Bearer $OKRA_API_KEY"
```

Response:

```json theme={null}
{
  "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](/api-reference/documents/list-documents) applies (`limit`, `after`, `before`, `order`).

## Delete a branch

Branches are regular documents. Delete them the same way:

```bash theme={null}
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.

```bash theme={null}
# 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](/cookbook/branch-and-replace) for a full worked example with grading.

## Git semantics

| Git                     | OkraPDF       | Endpoint                              |
| ----------------------- | ------------- | ------------------------------------- |
| `git branch feature`    | Create branch | `POST /v1/documents/:id/branch`       |
| `git branch`            | List branches | `GET /v1/documents?branched_from=:id` |
| `git branch -d feature` | Delete branch | `DELETE /document/:id`                |
| `git merge feature`     | Merge branch  | *Coming soon*                         |

## Related

<CardGroup cols={2}>
  <Card title="Branch + Replace" icon="code-branch" href="/cookbook/branch-and-replace">
    Fork a doc, replace bad OCR, compare completions.
  </Card>

  <Card title="Ingest API" icon="upload" href="/features/ingest-api">
    Push pre-parsed vendor output into OkraPDF.
  </Card>
</CardGroup>
