LedgerBox

API

Use the API to extract rows from financial documents. The TypeScript SDK uploads each file and returns the result. API access is available on every plan.

0
Runtime dependencies
11
Document types
8
Signed event types
npm install @ledgerbox/sdk
import { LedgerBox } from "@ledgerbox/sdk"
import { extractFile } from "@ledgerbox/sdk/node"

const lb = new LedgerBox({ apiKey, organizationId, workspaceId })

const { records } = await extractFile(lb, "statement.pdf")

Upload a document with the SDK

The SDK sends each API request in the required order. You can also call each method separately.

  1. Hashes the file The SDK calculates a SHA-256 hash for the file.
  2. Creates a batch The SDK sends POST /v1/batches with an idempotency key.
  3. Uploads the file The SDK uploads the file to the temporary URL from the API.
  4. Starts extraction The SDK completes the upload and receives a document ID.
  5. Reads the result The SDK polls the document until the API returns the extracted rows.

Call the API with curl

https://api.ledgerbox.io

KEY="lb_..."        # Settings, API keys
ORG="..."           # shown beside the key
WORKSPACE="..."     # shown beside the key

curl "https://api.ledgerbox.io/v1/documents?limit=1" \
  -H "x-api-key: $KEY" \
  -H "x-organization-id: $ORG" \
  -H "x-workspace-id: $WORKSPACE"

Use LedgerBox through MCP

The @ledgerbox/mcp server connects the API to Claude Desktop, Cursor, and other MCP clients. The server returns extracted rows, the document state, and open flags.

The server tells the client that flagged rows are not verified. Review these rows before your application uses them.

convert_document
Uploads a PDF or image and returns its state, flags, and up to 500 rows.
get_document
Returns the state, summary, and open flag count for a document.
list_records
Returns the extracted rows for a document.

claude_desktop_config.json

npx -y @ledgerbox/mcp

{
  "mcpServers": {
    "ledgerbox": {
      "command": "npx",
      "args": ["-y", "@ledgerbox/mcp"],
      "env": {
        "LEDGERBOX_API_KEY": "lbx_...",
        "LEDGERBOX_ORGANIZATION_ID": "org_...",
        "LEDGERBOX_WORKSPACE_ID": "ws_..."
      }
    }
  }
}

Webhook events

Send all events to one webhook URL, or select specific events. Webhooks require Pro and up. API requests work on every plan.

Document lifecycle

  • document_processed Processing finished and results are ready to review.
  • flags_created Extraction raised review flags on a document.
  • document_approved A reviewer approved the extracted data.
  • export_generated An export file was created for a document.
  • posting_completed A document was sent to an accounting system.
  • batch_completed Every document in one upload finished processing.

Housekeeping

  • artifact_expired A stored file passed its retention window.
  • purge_completed A requested deletion finished purging its files.

Webhook signatures and retries

Each delivery is a POST request with a JSON body. Verify the signature before you parse the body. Reject a request with an invalid signature.

Example delivery

document_processed

POST /hooks/ledgerbox HTTP/1.1
content-type: application/json
user-agent: LedgerBox-Webhooks/1.0
ledgerbox-event: document_processed
ledgerbox-delivery: f0c2a739-8e14-4b5d-9036-2a7c8e1f4b60
ledgerbox-timestamp: 1774343643
ledgerbox-signature: v1=4e1b9c...

{
  "id": "9c1f4a2e-6b70-4c5a-9f83-1d0e2b7a45c1",
  "deliveryId": "f0c2a739-8e14-4b5d-9036-2a7c8e1f4b60",
  "type": "document_processed",
  "createdAt": "2026-07-24T09:14:03.271Z",
  "data": {
    "eventId": "9c1f4a2e-6b70-4c5a-9f83-1d0e2b7a45c1",
    "eventType": "document_processed",
    "documentId": "3f6b21d8-9a54-4e07-b1c2-8d5f7e04a9b3",
    "processingRunId": "c4d8e5f1-2a37-4b96-8c0d-5e1f3a7b2d64",
    "state": "succeeded",
    "derivedState": "needs_review"
  }
}
ledgerbox-event
The event type. A test send arrives as test.
ledgerbox-delivery
The delivery id, stable across retries of the same event. Treat it as an opaque string.
ledgerbox-timestamp
Unix seconds, regenerated on every attempt.
ledgerbox-signature
v1= followed by the hex digest.

How the signature is built

Prefix the hex HMAC-SHA256 value with v1=. Calculate the value from the timestamp, a full stop, and the raw body. Use the endpoint secret.

Verify the signature

Node · HMAC-SHA256

import { createHmac, timingSafeEqual } from "node:crypto"

export function verifyLedgerBox(rawBody, headers, secret) {
  const timestamp = headers["ledgerbox-timestamp"]
  const signature = headers["ledgerbox-signature"]
  if (!timestamp || !signature) return false
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false
  const expected =
    "v1=" +
    createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex")
  const a = Buffer.from(expected)
  const b = Buffer.from(signature)
  return a.length === b.length && timingSafeEqual(a, b)
}

When your endpoint is down

LedgerBox tries a delivery up to 8 times. The last retry occurs after 12 hours. The delivery ID stays the same for all attempts. You can pause an endpoint while you repair it.

API reference

The reference lists each endpoint, parameter, and response schema.

Open the API reference

API questions

Does LedgerBox work with Claude Desktop and other MCP clients?

Yes. The @ledgerbox/mcp server provides convert_document, get_document, and list_records to MCP clients. It uses environment variables for its settings. Each response includes the document state and flags.

Which plan does the API need?

The API works on every plan. Webhooks require Pro and up. The free trial includes both, so you can build against them before paying. LedgerBox returns subscription_required when an API key has no active subscription.

Is the SDK open source?

Yes. @ledgerbox/sdk uses the Apache-2.0 license and has no runtime dependencies. The SDK calls the public LedgerBox API.

Are there rate limits?

Yes. LedgerBox applies separate per-minute limits to reads, writes, and exports for each organization. Each response includes the rate limit headers. A refused request returns 429 and Retry-After.

Where are API keys created?

Create an API key in Settings, API keys. LedgerBox shows the key once with the required organization and workspace IDs. Each key has scopes for its allowed actions.

How do I verify a webhook signature?

Calculate HMAC-SHA256 from the timestamp, a full stop, and the raw body. Use the endpoint secret. Compare the result in constant time. Reject old timestamps.

What happens when my endpoint is down?

LedgerBox tries each delivery up to 8 times. The delivery ID stays the same for each attempt. You can pause the endpoint while you repair it.

Can events be replayed?

Yes. Replay a delivery from Settings, Integrations. A replay uses a new delivery ID and keeps the original event ID. Use the event ID to reject duplicates.

View the fields for each document type View the QuickBooks integration

Extract a document through the API

Create an API key and upload a document. You do not need a credit card.

Create an API key