API Reference
Complete reference for all KYA REST API endpoints.
Base URL & Docs#
| Interface | URL |
|---|---|
| API base | http://localhost:8000 |
| OpenAPI JSON | http://localhost:8000/openapi.json |
| Swagger UI | http://localhost:8000/docs |
| ReDoc | http://localhost:8000/redoc |
| Playground UI | http://localhost:5173 (pnpm --filter playground dev) |
Authentication#
Sensitive endpoints require the workspace header:
X-Workspace-Id: <workspace_uuid>The workspace_id in the request body must match the X-Workspace-Id header. Mismatch returns 403 WORKSPACE_MISMATCH.
Workspace bootstrap uses a separate token:
X-Bootstrap-Token: <bootstrap_token>Error Format#
All business errors follow this shape:
{
"detail": {
"code": "WORKSPACE_MISMATCH",
"message": "Workspace does not match authenticated context"
}
}Workspaces#
POST
/workspacesRequest body
{
"name": "My Workspace",
"slug": "my-workspace" // optional
}Response 201
{
"id": "ws_01J...",
"name": "My Workspace",
"slug": "my-workspace",
"status": "active",
"created_at": "2025-01-15T10:00:00Z"
}| Status | Code | Condition |
|---|---|---|
| 201 | — | Workspace created |
| 401 | AUTH_BOOTSTRAP_MISSING | X-Bootstrap-Token header absent |
| 401 | AUTH_BOOTSTRAP_INVALID | Token value does not match server config |
| 409 | WORKSPACE_SLUG_ALREADY_EXISTS | Slug already taken |
| 503 | WORKSPACE_BOOTSTRAP_DISABLED | KYA_WORKSPACE_BOOTSTRAP_TOKEN not set server-side |
GET
/workspaces/{workspace_id}| Status | Code | Condition |
|---|---|---|
| 200 | — | Success |
| 403 | WORKSPACE_MISMATCH | X-Workspace-Id header does not match path param |
| 404 | WORKSPACE_NOT_FOUND | Workspace does not exist |
Agents#
POST
/agentsRequest body
{
"workspace_id": "ws_01J...",
"name": "payment-agent",
"public_key": "base64_ed25519_public_key",
"runtime_type": "claude" // optional: claude, codex, custom
}Response 201
{
"id": "agt_01J...",
"workspace_id": "ws_01J...",
"name": "payment-agent",
"status": "active",
"fingerprint": "sha256:abc123...",
"created_at": "2025-01-15T10:00:00Z"
}GET
/agents/{agent_id}POST
/agents/{agent_id}/revokePolicies#
POST
/policiesRequest body
{
"workspace_id": "ws_01J...",
"name": "payment-policy",
"rules": {
"allowed_tools": ["charge_payment", "get_balance"],
"spend_limits": {
"max_per_tx": 50,
"max_per_day": 500,
"max_per_month": 5000
},
"rate_limits": {
"actions_per_minute": 10,
"calls_per_hour": 100
}
}
}POST
/agents/{agent_id}/bind_policyRequest body
{
"workspace_id": "ws_01J...",
"policy_id": "pol_01J..."
}Capabilities#
POST
/capabilities/requestRequest body
{
"workspace_id": "ws_01J...",
"agent_id": "agt_01J...",
"action": "charge_payment",
"ttl_seconds": 300 // 5–1800
}Response 201
{
"capability_token": "eyJhbGciOiJFZERTQSJ9...",
"expires_at": "2025-01-15T10:05:00Z",
"jti": "cap_01J..."
}Verification#
POST
/verifyRequest body
{
"workspace_id": "ws_01J...",
"agent_id": "agt_01J...",
"capability_token": "eyJhbGciOiJFZERTQSJ9...",
"action": "charge_payment",
"payload": {
"amount": 45,
"currency": "EUR"
},
"signature": "base64_ed25519_signature",
"payload_hash": "sha256_hex_of_canonical_json"
}Response — ALLOW
{
"decision": "ALLOW",
"reason_code": null,
"audit_event_id": "evt_01J..."
}Response — DENY
{
"decision": "DENY",
"reason_code": "SPEND_LIMIT_EXCEEDED",
"audit_event_id": "evt_01J..."
}Deny Reason Codes#
| Code | Meaning |
|---|---|
| AGENT_REVOKED | Agent has been revoked and can no longer act |
| POLICY_NOT_BOUND | No active policy bound to this agent |
| CAPABILITY_INVALID | Capability token is malformed or unrecognized |
| CAPABILITY_EXPIRED | Capability token TTL has passed |
| CAPABILITY_REVOKED | Capability token was explicitly revoked (blacklisted) |
| CAPABILITY_SCOPE_MISMATCH | Action does not match the capability's scope |
| SIGNATURE_INVALID | Ed25519 signature verification failed |
| SPEND_LIMIT_EXCEEDED | Transaction or daily/monthly spend limit exceeded |
| RATE_LIMIT_EXCEEDED | Action rate limit exceeded for this agent |
Audit#
GET
/audit/eventsGET
/audit/export.jsonGET
/audit/export.csvGET
/audit/integrity/checkIntegrity response
{
"status": "OK", // OK | BROKEN | PARTIAL
"checked_events": 1247,
"first_event_id": "evt_01J...",
"last_event_id": "evt_09K..."
}