LimitLayer API — Developer Reference
Financial guardrails for AI agents. Control budgets, enforce merchant rules, require approvals, and get real-time spend decisions.
1. Authentication
Authenticate every request with your API key. You can find or create API keys in the LimitLayer Dashboard under Settings → API Keys.
Send the key in either header:
X-API-Key: ll_aBcDeFgH... ← preferred Authorization: Bearer ll_aBcDeFgH... ← also accepted
⚠️ Never expose your API key in client-side code or public repositories. All calls to LimitLayer should be made from your server.
Wallets, agents, policies, approvals, webhooks, and other management features are configured through the LimitLayer Dashboard. This reference covers only the API endpoints your application calls at runtime.
2. Transactions
The core flow: an agent requests a transaction → LimitLayer evaluates policy, wallet budget, and agent mandate → a decision is returned synchronously in the same response.
Decision Outcomes (returned by POST /transactions/request)
approved → proceed with payment, then call POST /transactions/{id}/confirm
denied → budget exceeded, policy FAIL, or mandate hard violation. Stop.
escalated → held for human review via an Escalation (priority + SLA deadline)
requires_approval → held for human review via the legacy Approval flow (no Escalation
Level configured for this org) — poll GET /transactions/{id}/status2.1 Request a transaction
agent_id accepts either the agent's UUID or its exact name. If you're using an L3 (Zero-Trust) agent, you can also pass the agent name via the X-Agent-ID header instead of the body.
2.2 Confirm or fail a payment
Only callable on a transaction whose evaluation status is APPROVED. On failure, the wallet's total_approved is automatically reversed by the transaction amount.
2.3 Check status / list / fetch
2.4 Approvals (legacy flow)
Only relevant when a transaction comes back with decision: "requires_approval". These endpoints are typically called from your internal approver tooling, not from the agent itself.
Tip: After receiving escalated or requires_approval, poll GET /transactions/{transaction_id}/status until the status changes to APPROVED, DENIED, or EXPIRED. Escalations and approvals are resolved by your team in the LimitLayer Dashboard.
2.5 L3 Zero-Trust agents (request signing)
Agents configured with security_level: "L3" must sign every call to POST /transactions/request with an HMAC-SHA256 signature, in addition to the standard API key. L1/L2 agents skip this entirely.
X-Agent-ID: procurement-bot-01 X-Timestamp: 2026-03-28T10:00:00Z ← ISO-8601 UTC X-Nonce: b7e6c1f2-... ← unique per request X-Signature: 9f2c1e4a... ← hex HMAC-SHA256, see below
canonical = "<METHOD>\n<PATH>\n<TIMESTAMP>\n<NONCE>\n<SHA256(body)>" signing_key = sha256(sk_live_...) ← your agent's secret key, hashed signature = hmac_sha256(signing_key, canonical) → hex-encoded
Timestamps outside the agent's configured nonce_window_seconds are rejected, and each nonce can only be used once — replayed requests are blocked automatically.
3. Decline Normalisation
Send a raw wallet-provider decline and get back a normalised category, recommended action, and risk score.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
wallet_provider | string | Yes | Which wallet returned the error |
raw_response | object | Yes | The raw error/decline JSON — any shape |
agent_id | string | Yes | Your LimitLayer agent ID |
transaction.amount | float | No | Transaction amount (for analytics) |
transaction.merchant | string | No | Merchant name (for analytics) |
4. Outcomes & Retry Advisory
Report payment outcomes to LimitLayer and receive intelligent retry recommendations based on historical patterns.
5. Error Reference
All errors follow this shape: { "detail": "Human-readable error message" }
| Status | Meaning |
|---|---|
400 | Bad request — validation failed or invalid input |
401 | Unauthenticated — missing or invalid credentials |
403 | Forbidden — authenticated but insufficient role/access |
404 | Resource not found or doesn't belong to your org |
409 | Conflict — e.g. duplicate wallet name |
410 | Gone — approval request has expired |
422 | Unprocessable entity — request body schema violation |
423 | Locked — wallet is frozen, transactions blocked |
429 | Rate limit exceeded |
500 | Internal server error |
Common 401 causes
- API key not in
X-API-Keyheader orAuthorization: Bearerheader - API key
is_active = falseorstatus = revoked - API key
expires_atin the past - L3 agent signature rejected — see codes below
| Signature error code | Meaning |
|---|---|
TIMESTAMP_MISSING | X-Timestamp header was not sent on an L3 agent request |
TIMESTAMP_INVALID | X-Timestamp is not valid ISO-8601 UTC (e.g. 2026-07-04T10:30:00Z) |
TIMESTAMP_EXPIRED | Timestamp is outside the agent's configured nonce_window_seconds |
NONCE_MISSING | X-Nonce header was not sent on an L3 agent request |
NONCE_REPLAYED | This nonce was already used — generate a new unique nonce per request |
SIGNATURE_INVALID | HMAC signature does not match the canonical string — check signing key |
Common 403 causes
- Tenant role insufficient for this operation (see permission matrix)
- Cross-tenant request blocked (path org_id ≠ caller's org_id)
- Organisation inactive or soft-deleted
- Agent found but
is_active = false
Common 423 causes
- The agent's wallet has
is_frozen = true— all new transactions are blocked until unfrozen in the Dashboard
Last updated: July 2026