HEADLESS · API-ONLY · APPEND-ONLY

Ledger17

Double-entry bookkeeping as an API.

Ledger17 is a headless ledger: no screens, no workflows — a command API records immutable, balanced transactions and a query API serves balances, subledgers and the live journal. Your systems post the facts; the ledger keeps the books.

Built on CQRS and event sourcing. Writes append immutable events; reads hit pre-calculated views, so queries stay fast at any ledger size.

ONE REQUEST, ONE BALANCED BLOCK

Post a transaction. Everything else is enforced.

Amounts are integers at the unit’s scale, so 125000 EUR is €1,250.00 (scale per unit). Every block must balance — the ledger refuses anything else.

POST /ledger/v1/transactions 201 Created
$ curl -X POST https://api.example.com/ledger/v1/transactions \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: org-84120557" \
  -H "X-Idempotency-Key: inv-2026-0042" \
  -d '[{
    "name": "Sales invoice #42",
    "transactionDate": "2026-07-01",
    "unit": "EUR",
    "entries": [
      { "accountReference": "1500-receivables",
        "entryType": "DEBIT",  "amountMinorUnits": 125000,
        "dimensions": { "CUSTOMER": "cust-001" } },
      { "accountReference": "3000-sales",
        "entryType": "CREDIT", "amountMinorUnits": 100000 },
      { "accountReference": "2700-vat-out",
        "entryType": "CREDIT", "amountMinorUnits": 25000 }
    ]
  }]'
transaction block a3f9…c217
1500-receivablesDEBIT1,250.00
3000-salesCREDIT1,000.00
2700-vat-outCREDIT250.00
Σ debits = Σ credits✓ balanced

Blocks that don't balance exactly are rejected with 400 UNBALANCED_TRANSACTION. Once accepted, a block is immutable — corrections are new, compensating blocks.

WHY HEADLESS

Accounting guarantees, delivered over HTTP

history_edu

Append-only, immutable

Transactions are events, stored forever. No updates, no deletes — corrections are compensating reversals, so the audit trail is the database.

balance

Double-entry, enforced

Every transaction block must balance: Σ debits = Σ credits, exactly — integer arithmetic, no rounding. Unbalanced writes are rejected before they touch the books.

bolt

Fast, pre-calculated reads

Balances are aggregated as transactions post, not when you ask. Queries are lookups, not scans — response times stay flat as the books grow.

fingerprint

Idempotent writes

Every write carries an X-Idempotency-Key. Retry as hard as you like — the same key can never post twice.

account_tree

Dimensions & subledgers

Tag entries with CUSTOMER, SUPPLIER, PROJECT and more. Rollups are pre-computed for every dimension in parallel; each query filters on one.

eco

Money and carbon on one account

Book NOK, EUR, gold or kg CO₂e on the same account. Each unit keeps its own balance and is never converted.

podcasts

Live event stream

Subscribe to the journal over WebSocket and follow every posted block in real time — from any sequence number you choose.

AGENTS & INTEGRATIONS

Built for software — human optional

The same ledger, three ways in: an MCP server for AI assistants, API keys for unattended systems, and an admin console for your tenant.

smart_toy

MCP server for AI agents

Connect Claude or any MCP client to mcp.ledger17.com and the ledger becomes tools: balances, subledgers, reports — and balanced writes. The caller’s own permissions apply; the admin API is deliberately absent.

AI agent docs chevron_right
vpn_key

API keys for integrations

Unattended systems authenticate with an API key bound to one tenant, scoped to exactly the permissions the integration needs — read:ledger for a dashboard, write:ledger for a posting system.

API key docs chevron_right
admin_panel_settings

Admin console

Manage your tenant, subscription and API keys at admin.ledger17.com. Everything else stays headless — the console administers access; your systems and agents keep the books.

Get started chevron_right
TWO SERVICES, ONE LEDGER

Command writes. Query reads.

All endpoints live under /ledger/v1. Tenant scoping via X-Tenant-ID, OIDC bearer tokens in production.

south_westCommand API :8080

Record transaction blocks, submit business events, reverse mistakes. Accepts facts; derives and validates entries via domain rule sets.

  • POST /ledger/v1/transactions record balanced blocks
  • POST /ledger/v1/transactions/{id}/corrections compensating reversal
  • POST /ledger/v1/events submit a business event
  • POST /ledger/v1/events/batch bulk import (up to 10 000)
  • GET /ledger/v1/events inquire submitted events
Command API reference chevron_right
north_eastQuery API :8081

Read the books: balances, transaction lines, subledger rollups, party exposure and the live journal — served from pre-aggregated views, fast at any size.

  • GET /ledger/v1/balances account balance for a period
  • GET /ledger/v1/transactions transaction lines
  • GET /ledger/v1/subledger subledger rollup by dimension
  • GET /ledger/v1/parties/{partyId}/exposure net exposure per party
  • WS /ledger/v1/events live journal stream
Query API reference chevron_right