Documentation · API reference

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.

Access. The API is not open self-serve. Design partners receive a credential during onboarding. To request access, write to [email protected].

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

  1. Create a tenant (one-time)
  2. Build the identity hierarchy under the tenant's root
  3. Attach policies and budgets to the identities that will take action
  4. (Optional, for spend) issue virtual cards bound to identities
  5. Call /v1/authorize before each action — or rely on the inline card-network webhook for spend
  6. Query /v1/audit and /v1/audit/verify to 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


Want a working integration end-to-end? [email protected].