DocumentationReference

Evaluation API

Submit an action, decode ALLOW or DENY, and negotiate a supported HOLD response.

Updated 2026-09-22 Read as Markdown
On this page

Endpoint and authentication

Use POST https://api.kastra.ai/v1/evaluate with a Kastra environment API key or supported Edge device credential. This is a cooperative API: your integration must consult it before the action and enforce the result. Kastra does not execute the submitted action for you.

Send explicit context

Create a test evaluate.json:

{
  "jurisdiction": "US",
  "model": "example-agent",
  "workload_type": "tool-call",
  "environment": "dev",
  "request_id": "documentation-example-001",
  "action": "inspect_repository",
  "attributes": {
    "x-kastra-attr-tool": "example_read_tool"
  }
}

Use real policy context and an existing environment. The example tool and model are illustrative identifiers, not built-in integrations.

jurisdiction, model and workload_type must be non-empty. source, when supplied, must be a supported decision source. A fingerprint cannot be combined with a non-empty prompt or attributes. Use the API key’s bound environment; a device caller should select its environment explicitly.

curl -i https://api.kastra.ai/v1/evaluate \
  -H "Authorization: Bearer $KASTRA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Accept-Kastra-Hold: 1' \
  --data-binary @evaluate.json

Decode every outcome

ResponseRequired handling
200 with ALLOWProceed only with the evaluated action
403 with a decision envelopeDecode the reason and stop; a policy denial is not a transport failure
202 HOLDRetain the checkpoint and wait for an effective permission outcome
Opted-in 429Handle the negotiated rate-limit result
Other errorsApply the integration’s explicit error posture; never turn unknown output into permission

Accept-Kastra-Hold: 1 opts into the HOLD contract. Without it, a matching HOLD rule falls back to denial for compatibility. The server must also have the checkpoint subsystem enabled. An ALLOW/DENY envelope and a HOLD envelope are different wire shapes; parse the negotiated shape rather than assuming all responses have the same fields.

Normal 200/403 responses wrap the result in { "success": true, "data": { ... } }. Inspect data.decision, data.reason, and the returned identifiers. A negotiated 202 also uses success and data, but its data contains decision: "HOLD", checkpoint_id, expiry, timeout behavior, and connection information instead of an ordinary decision record. The current default normal-evaluation storage-failure response is 503; see failure behavior.

Checkpoint lifecycle

Read GET /v1/checkpoints/{id} with an authorized credential and inspect status plus effective_decision. Human approval requires a current authorized membership. Device cancellation/heartbeat and human resolution are separate operations. Approval guide.

Limits and retries

Discover effective byte limits with GET /v1/limits. The default prompt ceiling is 1 MiB; oversized input is denied, not silently treated as fully evaluated. Use an Idempotency-Key for a supported transport retry when appropriate, preserving the request. It is distinct from proxy HOLD operation identity. The current idempotency middleware can be bypassed for device-only context or a storage error; do not treat it as a universal exactly-once guarantee. Direct evaluation matches principal only when established through server-bound identity; an unverified body principal does not become a principal predicate.

Model output controls require a surface that supplies output context. Posting a prompt to this pre-inference endpoint does not make it a proxy output scanner.

Display-only content preview

POST /v1/content/preview accepts an environment API key and only a JSON content string. The complete body must fit within 256 KiB. It returns success: true with data.content and data.redaction_count, using Cache-Control: no-store. Invalid input returns 400; an oversized body returns 413.

This stateless masking helper does not evaluate policy, call a model, or store the supplied content. Render its output as plain text; do not display the original as a fallback on failure. Its supported detectors do not guarantee anonymity of arbitrary prose.