Partner Bookkeeping API
Connect once at the firm level, list companies, pull bookkeeping data, and post accounting transactions.
The LedgerHQ Partner Bookkeeping API is the recommended REST surface for
external apps. It is QBO-inspired, but uses cleaner company-scoped URLs:
connect once to the firm with OAuth, list available companies, then read or
post bookkeeping data with /companies/{companyId}/... routes.
https://ledgerhq.pro/api/v1Use this guide for new third-party integrations. Older organization-scoped
routes with x-organization-id remain available for compatibility, but
company-path routes are easier for partner apps to reason about.
What You Can Do
| Area | Endpoints |
|---|---|
| Company discovery | GET /companies, GET /companies/{companyId} |
| Accounting data | GET /companies/{companyId}/accounts, /journal-entries, /journal-lines |
| Banking data | GET /companies/{companyId}/bank-accounts, /bank-transactions, /reconciliations |
| Reports | /reports/profit-and-loss, /reports/balance-sheet, /reports/trial-balance, /reports/general-ledger |
| Posting | POST /purchases, /deposits, /transfers, /bill-payments, /journal-entries under a company |
Money fields are integer cents. Dates are YYYY-MM-DD; timestamps are ISO
strings.
What Is Not Included
V1 does not include webhooks, change-data-capture endpoints, selected-company OAuth consent, update/delete endpoints for existing accounting records, payroll, inventory, CRM, projects, broad approval workflows, statement OCR, billing settings, or admin/company-management mutations.
Authentication
Partner apps should use OAuth with Authorization Code + PKCE. The connected LedgerHQ user must be a firm owner or admin.
Register the OAuth client
POST /api/oauth/register
Content-Type: application/json
{
"client_name": "Example Partner App",
"redirect_uris": ["https://partner.example.com/oauth/callback"]
}LedgerHQ returns a client_id. No static API key or client secret is
required for the public PKCE flow.
Send the firm user through OAuth
GET /api/oauth/authorize
POST /api/oauth/tokenRequest the scopes your app needs, such as companies:read accounts:read reports:read.
Store and refresh tokens
Access tokens are short-lived. Use the refresh token returned by the token endpoint to keep the connection alive.
List Companies
curl -H "Authorization: Bearer mcp_at_your_token" \
"https://ledgerhq.pro/api/v1/companies?limit=250"Response:
{
"data": [
{
"id": "company_uuid",
"name": "Summit Ridge Design LLC",
"type": "company",
"firmId": "firm_uuid",
"defaultCurrency": "USD",
"status": "active"
}
],
"pagination": {
"limit": 250,
"cursor": null,
"nextCursor": null,
"hasMore": false
}
}Pull Bookkeeping Data
curl -H "Authorization: Bearer mcp_at_your_token" \
"https://ledgerhq.pro/api/v1/companies/company_uuid/accounts"curl -H "Authorization: Bearer mcp_at_your_token" \
"https://ledgerhq.pro/api/v1/companies/company_uuid/journal-entries?startDate=2026-01-01&endDate=2026-06-30"curl -H "Authorization: Bearer mcp_at_your_token" \
"https://ledgerhq.pro/api/v1/companies/company_uuid/bank-transactions?limit=100"curl -H "Authorization: Bearer mcp_at_your_token" \
"https://ledgerhq.pro/api/v1/companies/company_uuid/reports/profit-and-loss?startDate=2026-01-01&endDate=2026-06-30"List endpoints support cursor pagination and pull sync:
limit=100
cursor=last_seen_id
updatedSince=2026-06-17T12:00:00.000ZDate-bearing endpoints also support startDate, endDate, and asOf where
appropriate.
Post Transactions
Posting endpoints describe accounting intent and create posted ledger entries.
Every posting request requires Idempotency-Key so retries do not double-post.
curl -X POST \
-H "Authorization: Bearer mcp_at_your_token" \
-H "Idempotency-Key: partner-purchase-1001" \
-H "Content-Type: application/json" \
-d '{
"sourceAccountId": "bank_or_chart_account_uuid",
"date": "2026-06-17",
"amountCents": 12995,
"categoryAccountId": "expense_account_uuid",
"description": "Software subscription",
"reference": "vendor-invoice-42"
}' \
https://ledgerhq.pro/api/v1/companies/company_uuid/purchasesReceipt:
{
"data": {
"id": "resource_uuid",
"resourceType": "purchase",
"status": "posted",
"journalEntryId": "journal_entry_uuid",
"bankTransactionIds": ["bank_transaction_uuid"],
"affectedAccountIds": ["account_uuid"],
"idempotentReplay": false,
"createdAt": "2026-06-17T12:00:00.000Z"
}
}Scopes
Recommended scopes:
companies:read
accounts:read
journal_entries:read
bank_accounts:read
bank_transactions:read
reconciliations:read
reports:read
transactions:read_write
bill_payments:read_write
journal_entries:read_writeThe broad mcp scope remains accepted for LedgerHQ's MCP/OAuth connector.
Errors
Partner routes return structured errors:
{
"error": {
"code": "missing_scope",
"message": "OAuth scope required: reports:read",
"retryable": false
}
}Common codes include unauthorized, missing_scope,
organization_access_denied, invalid_request, idempotency_key_required,
idempotency_conflict, accounting_period_locked, and internal_error.
OpenAPI
The same contract is available as OpenAPI:
https://ledgerhq.pro/api/openapi.json