API Reference
5 REST endpoints. Base URL: https://app.keyless-ai.com/api/v3
Authentication
All requests require an API key in the Authorization header:
Authorization: Bearer ka_live_xxxxxxxxxxxx
Additionally, x-org-id and x-agent-id headers are required on all requests.
Intents
Declare an intent to perform an action. Every AI action starts here. The intent is risk-scored and stored before any policy evaluation or execution.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | uuid | Yes | Agent performing the action |
org_id | uuid | Yes | Organization scope |
action | string | Yes | Action name (max 200 chars) |
payload | object | No | Action metadata (max 64KB) |
amount | number | No | Action cost for budget tracking |
target | object | No | Structured target data |
idempotency_key | string | No | Prevents duplicate intents per org |
Response (201)
{
"intent_id": "uuid",
"status": "pending",
"risk_score": 0.45,
"created_at": "2026-04-05T12:00:00Z"
}
Policy
Evaluate policy rules against an existing intent. Returns the policy decision without executing anything.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
intent_id | uuid | Yes | Intent to evaluate |
org_id | uuid | Yes | Organization scope |
Response (200)
{
"decision": "require_approval",
"risk_score": 0.72,
"reason": "Amount exceeds $1,000 threshold",
"matched_rules": ["budget_threshold", "high_risk_action"]
}
Possible decisions: allow, require_approval, deny
Approval
Request human approval for a pending intent. Creates an approval record with a configurable expiry window.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
intent_id | uuid | Yes | Intent requiring approval |
org_id | uuid | Yes | Organization scope |
expiry_minutes | number | No | Approval window (default: 60) |
Approve or reject a pending approval.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
approval_id | uuid | Yes | Approval record ID |
decision | "approved" | "rejected" | Yes | Human decision |
approved_by | string | No | Reviewer identifier |
Execute
Execute a governed intent through the 10-step pipeline. This is the core of the Kernel.
10-Step Pipeline
- Fetch Intent — Load intent (org-scoped)
- Idempotency Check — Existing execution → 409
- Atomic Lock — PostgreSQL advisory lock via
lock_intent_execution() - Policy Re-check — Verify agent is still active
- Approval Check — Verify non-expired approval exists (if required)
- Budget Check — Atomic budget deduction via
increment_budget_usage() - Execute — Run action via connector layer
- Write Execution — Record execution result
- Audit Log — Mandatory audit trail entry
- Finalize — Update intent status + trust adjustment
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
intent_id | uuid | Yes | Intent to execute |
org_id | uuid | Yes | Organization scope |
Hard rule: No execution without intent_id. Direct execution is impossible by design.
Response (200)
{
"execution_id": "uuid",
"intent_id": "uuid",
"status": "completed",
"cost": 5000,
"duration_ms": 342,
"steps": [
{ "step": 1, "name": "fetch_intent", "status": "ok", "ms": 12 },
// ... all 10 steps
]
}
Ledger
Query the audit ledger. Two modes: single intent deep view (with intent_id) or list view with summary stats.
Query Parameters
| Param | Type | Description |
|---|---|---|
org_id | uuid | Required. Organization scope |
intent_id | uuid | Single intent deep view |
agent_id | uuid | Filter by agent |
status | string | Filter by status |
from | ISO-8601 | Start date |
to | ISO-8601 | End date |
limit | number | Max results (default 50, max 100) |
Response — List View (200)
{
"ledger": [...],
"summary": {
"total": 142,
"completed": 128,
"failed": 8,
"denied": 4,
"pending": 2,
"total_cost": 85200
}
}
Rate Limits
| Tier | Requests/min | Intents/day |
|---|---|---|
| Starter (Free) | 60 | 100 |
| Growth ($199/mo) | 600 | 10,000 |
| Enterprise | Custom | Unlimited |
Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (new intent) |
| 400 | Bad request (validation error) |
| 401 | Unauthorized (invalid API key) |
| 403 | Forbidden (policy denied, agent inactive) |
| 409 | Conflict (duplicate execution, intent locked) |
| 410 | Gone (approval expired) |
| 422 | Unprocessable (budget exceeded) |
| 429 | Rate limited |