LimitLayer API โ Developer Reference
Financial guardrails for AI agents. Control budgets, enforce merchant rules, require approvals, and get real-time spend decisions.
1. Authentication
LimitLayer supports two authentication methods. Both can be used on every endpoint.
1a. API Key (recommended for machines)
Send the raw API key in either header:
X-API-Key: ll_aBcDeFgH... โ preferred Authorization: Bearer ll_aBcDeFgH... โ also accepted
1b. JWT Token (recommended for dashboard users)
External (tenant) login:
POST /auth/v2/login
Content-Type: application/json
{
"email": "user@yourcompany.com",
"password": "your-password"
}Internal / admin login:
POST /auth/v2/admin/login
Content-Type: application/json
{
"email": "admin@limitlayer.com",
"password": "your-password"
}Both return:
{
"access_token": "eyJ...",
"token_type": "bearer",
"expires_in": 3600
}Use the token in subsequent requests:
Authorization: Bearer eyJ...
Verify your identity
โ ๏ธ Never expose your API key in client-side code or public repositories. All calls to LimitLayer should be made from your server.
2. Roles & Permissions
Tenant Roles (per-organisation)
| Role | Description | Can Do |
|---|---|---|
owner | Organisation owner | Everything |
admin | Org admin | Everything except ownership transfer |
editor | Power user | Create/edit wallets, agents, policies, transactions |
viewer | Read-only dashboard | View all resources |
report_only | Reporting only | View transactions and audit log |
api_user | Machine identity | Transact via API |
Platform Roles (internal staff only)
| Role | Description |
|---|---|
platform_admin | Full platform access |
support_admin | Support access |
billing_admin | Billing access |
auditor | Read-only audit access |
Endpoint Permission Matrix
| Endpoint Group | owner | admin | editor | viewer | report_only | api_user |
|---|---|---|---|---|---|---|
| Create wallet | โ | โ | โ | โ | โ | โ |
| Read wallets | โ | โ | โ | โ | โ | โ |
| Freeze wallet | โ | โ | โ | โ | โ | โ |
| Create/edit agent | โ | โ | โ | โ | โ | โ |
| Read agents | โ | โ | โ | โ | โ | โ |
| Deactivate agent | โ | โ | โ | โ | โ | โ |
| Create/edit policy | โ | โ | โ | โ | โ | โ |
| Delete policy | โ | โ | โ | โ | โ | โ |
| Request transaction | โ | โ | โ | โ | โ | โ |
| View transactions | โ | โ | โ | โ | โ | โ |
| Resolve approvals | โ | โ | โ | โ | โ | โ |
| Confirm payment | โ | โ | โ | โ | โ | โ |
| Audit log | โ | โ | โ | โ | โ | โ |
| Webhooks | โ | โ | โ | โ | โ | โ |
| Manage API keys | โ | โ | โ | โ | โ | โ |
3. Organisation & API Keys
Register your organisation to get started. The API key returned is shown once only โ store it securely immediately.
4. Wallets
Wallets hold budget allocations. Every agent is attached to one wallet.
Budget field glossary
| Field | Description |
|---|---|
budget | Total allocated limit |
total_approved | Amount reserved by approved transactions |
total_confirmed | Amount of payments actually confirmed |
in_flight | total_approved โ total_confirmed (approved but not yet paid) |
remaining | budget โ total_approved (still available to spend) |
5. Agents
Agents are AI identities that make spending requests. Each agent belongs to one wallet.
6. Policies
Policies define rules the transaction engine enforces before approving any spend request. Set agent_id to scope to one agent, wallet_id for all agents in a wallet, or both.
Policy types
| policy_type | What it does | config keys |
|---|---|---|
spending_limit | Caps total spend per period | limit, period (daily/weekly/monthly) |
transaction_limit | Max amount per single transaction | max_amount |
merchant_allowlist | Only allow listed merchants | merchants (array) |
merchant_blocklist | Block listed merchants | merchants (array) |
time_restriction | Only allow transactions in a time window | start_hour, end_hour, timezone |
approval_required | Require human approval above threshold | min_amount |
velocity | Limit number of transactions per period | max_count, period |
7. Transactions
The core flow: an agent requests a transaction โ policies are evaluated โ decision is returned.
Transaction Lifecycle
CREATED โ [REQUIRES_APPROVAL] โ APPROVED โ PAYMENT_CONFIRMED
โ PAYMENT_FAILED (wallet reversed)
โ DENIED
โ EXPIRED (approval window elapsed)List transactions โ query parameters
| Parameter | Type | Description |
|---|---|---|
page | int โฅ 1 | Page number (default 1) |
per_page | int 1โ100 | Results per page (default 20) |
status | string | PENDING ยท APPROVED ยท DENIED ยท REQUIRES_APPROVAL ยท EXPIRED |
agent_id | uuid | Filter by agent |
wallet_id | uuid | Filter by wallet |
merchant | string | Partial match |
min_amount | float | Minimum amount |
max_amount | float | Maximum amount |
from_date | ISO datetime | Start of date range |
to_date | ISO datetime | End of date range |
8. Approvals
When a transaction requires human approval it enters a 24-hour approval window. If not resolved it transitions to EXPIRED.
If the approval has expired, this returns 410 Gone.
9. Audit Log
Read-only transaction history for compliance and reporting.
Query parameters
| Parameter | Type | Description |
|---|---|---|
agent_id | uuid | Filter by agent |
wallet_id | uuid | Filter by wallet |
status | string | Evaluation status filter |
from_date | ISO datetime | Start of range |
to_date | ISO datetime | End of range |
limit | int โค 1000 | Results per page (default 50) |
offset | int | Pagination offset |
10. Webhooks
Webhooks deliver real-time event notifications to your HTTP endpoint via signed POST requests.
Verifying webhook signatures
Every webhook POST includes an X-LimitLayer-Signature header. Verify it to ensure the payload is genuine.
import hmac, hashlib
def verify_signature(payload_bytes: bytes, header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", header)const crypto = require('crypto');
function verifySignature(rawBody, signatureHeader, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}11. Webhook Event Payloads
All webhook POST bodies share this envelope:
{
"event": "transaction.approved",
"timestamp": "2026-03-28T10:00:00Z",
"organisation_id": "uuid",
"data": { }
}Headers on every delivery:
X-LimitLayer-Signature: sha256=<hmac> X-LimitLayer-Event: transaction.approved Content-Type: application/json
transaction.approved{
"transaction_id": "uuid",
"agent_id": "uuid",
"amount": 249.99,
"currency": "USD",
"merchant": "AWS",
"wallet_remaining": 4750.01
}transaction.denied{
"transaction_id": "uuid",
"agent_id": "uuid",
"amount": 249.99,
"currency": "USD",
"merchant": "ShopXYZ",
"denial_reason": "Merchant not in allowlist"
}transaction.requires_approval{
"transaction_id": "uuid",
"approval_id": "uuid",
"agent_id": "uuid",
"amount": 1500.00,
"currency": "USD",
"merchant": "Salesforce",
"expires_at": "2026-03-29T10:00:00"
}transaction.payment_confirmed{
"transaction_id": "uuid",
"amount": 249.99,
"currency": "USD",
"merchant": "AWS",
"payment_reference": "stripe_ch_abc123",
"wallet_remaining": 4750.01
}transaction.payment_failed{
"transaction_id": "uuid",
"amount": 249.99,
"currency": "USD",
"merchant": "AWS",
"payment_failure_reason": "Insufficient funds",
"wallet_remaining": 5000.0
}wallet.budget_warningFired when utilisation โฅ 70%{
"wallet_id": "uuid",
"wallet_name": "GPT-4 Operations Budget",
"budget": 5000.0,
"total_approved": 3600.0,
"remaining": 1400.0,
"usage_pct": 72.0
}wallet.budget_criticalFired when utilisation โฅ 90%{
"wallet_id": "uuid",
"wallet_name": "GPT-4 Operations Budget",
"budget": 5000.0,
"total_approved": 4600.0,
"remaining": 400.0,
"usage_pct": 92.0
}12. 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 - JWT token expired or signature invalid
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
Last updated: March 2026