API Reference
Reference for KLA Control Plane tRPC procedures, evidence REST routes, authentication, and tenant headers.
The KLA Control Plane exposes two HTTP transports under the /v1 base path:
- Generated tRPC procedures use a dotted operation name such as
agents.create. The CLI exposes every operation from the generated control-plane catalog. - REST routes cover evidence export, file transport, policy registry, telemetry, and other service-owned surfaces.
Use the CLI for tRPC procedures and kla api rest or curl for REST routes. The API host in the examples is the deployed dev API:
export KLA_API_URL='https://api.dev.kla.digital'
export KLA_ACCESS_TOKEN='<short-lived access token>'
export KLA_TENANT_ID='<tenant external ID>'
# Build the repository CLI while the package is private, then expose it in this shell.
corepack enable
pnpm install --frozen-lockfile
pnpm kla --help
KLA_REPO_ROOT="$(git rev-parse --show-toplevel)"
kla() { KLA_CLI_CWD="$PWD" pnpm --dir "$KLA_REPO_ROOT" --silent kla "$@"; }
The catalog is generated from the server AppRouter. Its operation count changes as procedures change. Run kla api list to inspect the current count and kla api doctor to compare the embedded catalog with the configured server.
Authentication and tenant headers
Every request carries a short-lived OAuth 2.0 bearer token. The verified tenant claim supplies the default tenant. Keep tokens and client secrets in the environment of the calling service.
| Header | Required | Semantics |
|---|---|---|
Authorization |
Yes | Bearer <access token> authenticates the caller. |
x-kla-tenant-external-id |
No | Selects a tenant by external ID when the authenticated subject has an active membership in that tenant. A non-member selection returns 403. |
x-kla-tenant-id |
No | Internal tenant UUID. Authentication and verified membership determine the tenant. |
Content-Type |
On JSON writes | application/json. |
The CLI sends its configured KLA_TENANT_ID as x-kla-tenant-id. Commands with an explicit tenant selection, such as kla evidence export --tenant <external-id>, use x-kla-tenant-external-id and require active membership.
kla auth test
curl -sS "$KLA_API_URL/v1/tenants.current" \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: $KLA_TENANT_ID"
tRPC procedures
The tRPC handler is mounted at /v1. A procedure's HTTP path is /v1/<procedure>:
| Procedure type | HTTP method | Example |
|---|---|---|
| Mutation | POST |
POST /v1/agents.create |
| Query | GET |
GET /v1/approvals.getPending |
| Subscription | Realtime/WebSocket | traces.stream |
The generated catalog and the server validate the same Zod input. Discover input schemas with:
kla api list --prefix agents.
kla api describe agents.create
kla api describe approvals.decide
Register an agent
agents.create accepts the agent manifest as a YAML string. The curated command reads the same procedure as the generic command:
- Endpoint:
POST /v1/agents.create
kla agent create --file /tmp/claims-triage.yaml
# Equivalent generated procedure command:
kla api agents create --input "$(jq -Rs '{yaml: .}' /tmp/claims-triage.yaml)"
The response includes the registered agent identifier. An approved policy binding and release are required before executions.execute can run the agent.
Start and inspect an execution
The execution procedure returns an executionId:
kla agent run AGENT_UUID \
--environment sandbox \
--input '{"claim_id":"clm_9921","requested_refund":1250.00}'
kla api executions get --input '{"id":"EXECUTION_UUID"}'
kla api executions getEvents --input '{"id":"EXECUTION_UUID"}'
Read and resolve approvals
approvals.getPending lists pending Decision Requests for the current tenant. approvals.decide accepts approve, reject, or escalate and requires a reason.
- Endpoint:
GET /v1/approvals.getPending - Endpoint:
POST /v1/approvals.decide
kla api approvals getPending --input '{"limit":20}'
export KLA_REVIEWER_ACCESS_TOKEN='<reviewer short-lived access token>'
cat > /tmp/approval-decision.json <<'JSON'
{
"approvalId": "APPROVAL_UUID",
"decision": "approve",
"decisionAcknowledged": true,
"reason": "Reviewed the claim evidence and authorized the refund."
}
JSON
KLA_ACCESS_TOKEN="$KLA_REVIEWER_ACCESS_TOKEN" \
kla api approvals decide --input @/tmp/approval-decision.json
The API applies tenant permissions and maker-checker rules to the decision. A reviewer cannot approve a request from the same identity that created it when the tenant's policy requires separation of duties.
Inspect and verify traces
traces.getTrace returns the spans for one trace. Sensitive values remain masked unless the caller has the separate unmask permission and supplies a justification.
- Endpoint:
GET /v1/traces.getTrace - Endpoint:
GET /v1/traces.verify
kla api traces getTrace \
--input '{"traceId":"TRACE_ID","tenantId":"TENANT_EXTERNAL_ID","includeSensitiveData":false}'
kla api traces verify \
--input '{"tenant":"TENANT_EXTERNAL_ID","auditId":"AUDIT_ID","date":"PROOF_DATE","nonce":"PROOF_NONCE","merkleRoot":"MERKLE_ROOT"}'
traces.verify requires trace:verify permission. Its input always includes tenant; the proof fields are supplied when the corresponding audit record contains them.
Evidence REST routes
Evidence export is implemented by an asynchronous API REST job. The request accepts a time-window scope and proof/raw-payload flags. evidence:export creates a job and reads a job created by the same actor. evidence:list reads jobs across the tenant. evidence:read reads the sealed manifest and archive.
Create an export
- Endpoint:
POST /v1/evidence/export-jobs
EXPORT_JOB=$(curl -sS -X POST "$KLA_API_URL/v1/evidence/export-jobs" \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: $KLA_TENANT_ID" \
-H 'Content-Type: application/json' \
-d '{"startDate":"2026-07-01T00:00:00.000Z","endDate":"2026-07-31T00:00:00.000Z","includeProofs":true}')
echo "$EXPORT_JOB"
The response contains exportId, status, and pollTimeoutMs. Poll until the status is completed, completed_with_omissions, failed, or canceled.
Poll, read the manifest, and download the archive
- Endpoint:
GET /v1/evidence/factory/jobs/$EXPORT_ID - Endpoint:
GET /v1/evidence/factory/jobs/$EXPORT_ID/manifest - Endpoint:
GET /v1/evidence/factory/jobs/$EXPORT_ID/download
EXPORT_ID=$(jq -r '.exportId' <<<"$EXPORT_JOB")
curl -sS "$KLA_API_URL/v1/evidence/factory/jobs/$EXPORT_ID" \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: $KLA_TENANT_ID" | jq
curl -sS "$KLA_API_URL/v1/evidence/factory/jobs/$EXPORT_ID/manifest" \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: $KLA_TENANT_ID" | jq
curl -sS -f "$KLA_API_URL/v1/evidence/factory/jobs/$EXPORT_ID/download" \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: $KLA_TENANT_ID" \
-o "./evidence-$EXPORT_ID.zip"
The archive is a sealed evidence-room-bundle-v1 package. Verify it offline with:
kla evidence verify --bundle "./evidence-$EXPORT_ID.zip" --out ./evidence-report
The CLI kla evidence export command creates the job at POST /v1/evidence/export-jobs, polls GET /v1/evidence/factory/jobs/:exportId, then reads the manifest and downloads from the canonical Evidence Factory routes. It keeps the API origin, tenant selection, and credential in the selected CLI context.
REST request behavior and errors
REST responses use JSON for metadata and application/zip for archive downloads. Common status codes are:
| Status | Meaning |
|---|---|
400 |
Request validation failed or the tenant context is incomplete. |
401 |
The bearer token is missing, expired, or invalid. |
403 |
The caller lacks the required permission or tenant membership. |
404 |
The resource or route does not exist for the selected tenant. |
409 |
The request conflicts with the current resource state. |
429 |
The tenant rate limit was exceeded. |
5xx |
A transient service or dependency failure. |
Treat a failed policy decision, failed approval authorization, or failed evidence preflight as a failed operation. Retry only when the response identifies a transient failure and the operation is safe to repeat.
