Decision records
Updated
Read a stored decision, or its trace, with the API key that created it.
Look up a decision
GET /v1/ system-zero/ decisions/ {id} - The stored decision, byte for byte.
GET /v1/ system-zero/ decisions/ {id}/ trace - Metadata about the same decision, without answer content.
Send the active API key that created the decision. Another key in the same workspace cannot read it.
Use the id of a decide reply: szd_ followed by 32 lowercase hexadecimal characters. Any other id returns 404 decision_not_found.
A found decision returns its stored status and reply, exactly as they were first returned. A legacy reply keeps its stored answer shape. Do not use legacy confidence as decision probability.
HEAD returns the same status and headers without a body. Neither read takes a request body or query parameters. There is no list endpoint.
Read the trace
A trace is a JSON object whose object is system_zero.decision_trace. It reads these fields from the stored decision.
id- The decision's id.
created- When the decision was made, in Unix seconds.
model- The model named in the stored reply.
model_version- The stored reply's
served_by. route- The stored reply's
context.route. usage_units- Seven usage counts, each a whole number or null.
refusal_codes- The distinct question refusal codes in the decision, sorted.
refusal_code- The one refusal code when there is exactly one, else null.
These fields are null in this release: request_id, render_id, attachments, timings.queue_ms, timings.node_ms, timings.settle_ms, usage_units., idempotency, stream_id and state_version.
A missing usage count is null, never zero. The trace holds no question names, answer values, probabilities, messages or request content.
Availability and retention
Send decide with an Idempotency-Key. A lookup finds only decisions stored under an Idempotency-Key; see Idempotency.
Unkeyed decisions, older decisions without a lookup index and replies over the storage limits are unavailable.
A stored decision is kept for up to 24 hours, and its answer or index can be removed earlier. Reading it never extends that time.
A lookup runs no new decision and is not charged. It still counts toward your requests a minute. The lookup index keeps no copy of request or answer content.
A decision id is not a permanent archive. Keep the answers you need in your own storage.
Errors and headers
Both reads can return these refusals.
400 invalid_trace_header- X-Client-Request-Id is blank, not printable ASCII or over 512 characters.
401 invalid_api_key- The key is missing, malformed or unknown.
403 auth_error- The key is revoked.
403 account_suspended- The workspace is suspended or waiting for access.
404 decision_not_found- The id is invalid, or no stored decision matches it for this API key.
405 method_not_allowed- The method is not GET, HEAD or OPTIONS.
429 rate_limit_exceeded- Too many requests from this key, workspace or address.
503 service_unavailable- A store the lookup reads cannot answer right now.
503 limiter_unavailable- Rate limiting cannot answer right now.
decision_not_found has error.retryable: false. It does not say whether a decision was never stored, expired, was removed or belongs to another key.
Retry only when error.retryable is true. Wait for Retry-After-Ms, in milliseconds, or Retry-After, in seconds; prefer Retry-After-Ms. See Errors.
Lookups use the same requests a minute as decide. Their X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers report them; see Rate limits.
X-Request-Id identifies the lookup, not the original decision. A valid X-Client-Request-Id you send is echoed back.
Lookups never set X-. Every response sends Cache-Control: no-store. A 405 lists Allow: GET, HEAD, OPTIONS.