The shape of the API.
A working subset of the public API surface, with curl examples. This page documents what the integration looks like — request and response shapes, the order of calls in a typical flow. The full schema, error catalog, and SDK are provided to design partners under engagement.
Base URL and authentication
Production API base: https://api.ledgerline.dev/v1. Authentication is via a bearer token issued during onboarding. Every request is scoped to a tenant; the tenant ID is either implicit in the token (preferred) or passed in the request body.
curl https://api.ledgerline.dev/v1/health
# {"status":"ok","service":"ledgerline-control-plane","timestamp":"..."}
Typical integration flow
- Create a tenant (one-time)
- Build the identity hierarchy under the tenant's root
- Attach policies and budgets to the identities that will take action
- (Optional, for spend) issue virtual cards bound to identities
- Call
/v1/authorizebefore each action — or rely on the inline card-network webhook for spend - Query
/v1/auditand/v1/audit/verifyto expose decisions and prove integrity
Tenants
One tenant per logical organization. Tenants are isolated; audit chains are per-tenant.
curl -X POST https://api.ledgerline.dev/v1/tenants \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Acme Co"}'
# Response (truncated):
# {
# "tenant_id": "t_01...",
# "root_identity_id": "id_01..."
# }
Identities
Every identity has a parent. Every chain ends at the tenant root, which represents the human principal accountable for the tenant.
curl -X POST https://api.ledgerline.dev/v1/identities \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "t_01...",
"parent_id": "id_01...",
"type": "agent",
"name": "Procurement worker"
}'
To walk an identity's chain back to the root:
curl https://api.ledgerline.dev/v1/identities/id_01.../chain \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN'
Revoking an identity invalidates every action attempted by it or its descendants on the next decision check. The revocation cascades; you do not have to walk the tree yourself.
curl -X POST https://api.ledgerline.dev/v1/identities/id_01.../revoke \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN'
Policies
Policies attach to a tenant or to a specific identity. They are evaluated in addition to (not in place of) any inherited policies. The current MVP accepts a JSON shape; the next version moves to Cedar for formal semantics.
curl -X POST https://api.ledgerline.dev/v1/policies \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "t_01...",
"identity_id": "id_01...",
"name": "Daily card-only policy",
"rules": {
"actions": ["card.authorize"],
"max_amount": 200,
"currencies": ["CAD"],
"allowed_mccs": ["5814", "5732", "7372"],
"allowed_hours": [9, 18]
}
}'
Budgets
Budgets attach to identities. Each authorized action that has an amount reserves from the matching budget at decision time. Settled transactions consume the reservation; declined or expired ones release it.
curl -X POST https://api.ledgerline.dev/v1/budgets \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "t_01...",
"identity_id": "id_01...",
"name": "Daily spend cap",
"dimension": "amount",
"period": "daily",
"limit": 500,
"currency": "CAD"
}'
Authorize — the hot path
The single endpoint that runs the chain walk, policy evaluation, budget check, reservation, and audit write.
curl -X POST https://api.ledgerline.dev/v1/authorize \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "t_01...",
"identity_id": "id_01...",
"action": "card.authorize",
"resource": {
"type": "merchant",
"id": "AWS",
"amount": 47.23,
"currency": "CAD",
"merchant_category": "7372"
}
}'
# Permit:
# { "decision_id": "dec_01...", "allowed": true, "reasons": [...], "budget_checks": [...] }
# Deny:
# { "decision_id": "dec_01...", "allowed": false, "reasons": [{"verdict":"deny","matched_rule":"..."}] }
Treasury — virtual cards
For spend, issue a card bound to an identity. The card is a real virtual card from our partner network; the spend limits and merchant restrictions are enforced both at the network level and at our authorization layer.
curl -X POST https://api.ledgerline.dev/v1/treasury/cards \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "t_01...",
"identity_id": "id_01...",
"spend_limit_daily": 200,
"spend_limit_monthly": 2000,
"currency": "CAD"
}'
Freezing a card is instant:
curl -X POST https://api.ledgerline.dev/v1/treasury/cards/<card_id>/freeze \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"tenant_id":"t_01..."}'
Kill switch — freeze every card under an identity and its descendants in one call:
curl -X POST https://api.ledgerline.dev/v1/treasury/kill-switch \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"tenant_id":"t_01...","identity_id":"id_01..."}'
Audit log
Every authorize decision writes a row. Query by tenant, identity, time range, decision verdict.
curl 'https://api.ledgerline.dev/v1/audit?tenant_id=t_01...&limit=50' \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN'
Verify chain integrity in one call. Returns the first row whose hash doesn't reconcile, or success.
curl 'https://api.ledgerline.dev/v1/audit/verify?tenant_id=t_01...' \
-H 'Authorization: Bearer $LEDGERLINE_TOKEN'
# { "valid": true, "entries_checked": 1284 }
Inline card-network authorization
Once a card is issued, you do not have to call /v1/authorize for individual swipes. The card network calls Ledgerline at the moment of the transaction; we evaluate the chain and respond synchronously. Your agent code does not change.
Errors and rate limiting
Errors return non-2xx HTTP status with a JSON body containing an error string. Rate limits are tenant-scoped; design partners receive limits sized for their workload during onboarding. The full error catalog and SDK are provided under engagement.
What this page is not
- The full API surface — internal admin endpoints, schema details, and the SDKs are provided to design partners.
- Versioned API documentation — once we have a stable v1, that page will live at
/docs/api/v1/. - A try-it-yourself sandbox — sandbox credentials are issued during onboarding rather than self-serve, both for security and because we want to be in the room when you first try to break it.
Want a working integration end-to-end? [email protected].