StrataDocs

Errors

The Strata HTTP API returns errors as RFC 7807 problem documents. Every non-2xx response uses the same shape, so you can write one handler for the whole /v1/* surface.

Response shape

All errors return Content-Type: application/problem+json and a JSON body with these fields:

FieldTypeDescription
typestringA URI identifying the error class, e.g. https://api.strata.kronisys.com/errors/rate_limit_exceeded. The slug after /errors/ is the stable identifier — branch on it.
titlestringShort human summary. Safe to log.
statusintegerHTTP status code, mirrors the response status.

Some errors add extra fields for context — for example a 403 model_not_allowed includes requested_model and allowed_models, and a 429 includes retry_after, used, and limit. Treat any field beyond type/title/status as optional and tolerate its absence.

Tip

Branch on the type URI — match the stable slug after /errors/, not the HTTP status code or title. The title string may change; the type URI will not.

Error catalog

The type field is always the full URI https://api.strata.kronisys.com/errors/<slug>. The catalog lists the <slug> for readability.

StatusSlugWhen you get it
400invalid_requestBody failed validation — required field missing, wrong shape, or unparsable.
400unsafe_image_refA document-generator spec referenced a local file path or a disallowed image source. Only inline data: URIs and public https:// URLs are accepted.
401missing_tokenNo Authorization: Bearer header was sent.
401invalid_tokenToken is malformed, unknown, expired, or revoked. Strata deliberately does not distinguish these — issue or rotate a key from Admin → API Keys.
402subscription_requiredYour organization has no active Strata subscription. An admin can start one in Billing.
403insufficient_scopeAuthenticated, but the key was not granted the scope this endpoint requires. Includes required_scope and granted_scopes.
403trial_no_api_accessYour organization is on a self-serve trial. The API is not available during a trial — add a payment plan.
403key_actor_revokedThe user (or connection bot) the key acts as is no longer active, so the key was disabled with them.
403model_not_allowedThe requested model is not in the key's allowed models, or your organization has disabled it in the Model Catalog. Includes requested_model and allowed_models.
403org_suspendedThe key's organization is suspended. Contact your admin.
404not_foundResource (or /v1 route) does not exist or is not visible to this key's organization.
404conversation_not_foundThe conversation_id you referenced does not exist for this organization.
409request_in_progressA request carrying the same Idempotency-Key is still being processed. Wait for it to finish, then retry to fetch the cached result.
413payload_too_largeRequest body or uploaded file exceeds the endpoint limit (the JSON body cap is 1 MB; file uploads have their own cap).
413spec_too_largeA document-generator spec exceeded the generator's own size limit. Split the document or trim the spec.
422spec_invalidA document-generator (/v1/excel, /v1/pdf, /v1/pptx, /v1/docx) rejected the spec you sent.
429rate_limit_exceededThe key's hourly request cap was exceeded. Honor Retry-After.
429ip_rate_limit_exceededA coarse per-IP guardrail was tripped (before the key was even resolved). Honor Retry-After.
429usage_limit_exceededThe actor's per-user rate limit, or the organization's shared usage pool, was hit (the same cap the web app, Teams, and agents share). Includes unit, used, and limit. Honor Retry-After.
429budget_exhaustedThe key's monthly token budget — or the organization's token pool — is fully consumed. Resets on the organization's billing-cycle reset day.
500internal_errorStrata encountered an unexpected failure. Safe to retry.
500engine_returned_emptyA document generator produced an empty file. Safe to retry; if it persists, simplify the spec.
500extension_config_errorThe key's extension tools could not be safely initialized for this request. Retry; if it persists, check the actor's extension connections.
503budget_check_failedBudget enforcement is briefly unavailable (a transient backend hiccup). Strata fails closed rather than spend uncapped. Retry with backoff.
503entitlement_check_failedStrata could not confirm your organization's API entitlement. It fails closed rather than assume access. Retry shortly.
503policy_lookup_failedThe organization's model/mode policy could not be read for this request. Strata fails closed. Retry with backoff.
Note

Token-budget exhaustion returns 429, not 403. The budget_exhausted body reports used (committed tokens since the cycle reset), in_flight (estimated tokens reserved by currently-running requests), and limit. Both the per-key budget and the shared organization token pool are enforced on the same call.

Examples

401 invalid_token

{
  "type": "https://api.strata.kronisys.com/errors/invalid_token",
  "title": "The provided API key is invalid, expired, or revoked.",
  "status": 401
}

403 model_not_allowed

{
  "type": "https://api.strata.kronisys.com/errors/model_not_allowed",
  "title": "Model \"claude-opus\" is not currently allowed by this organization's policy. Pick an allowed model or have an admin update the org's allowed models.",
  "status": 403,
  "requested_model": "claude-opus",
  "allowed_models": ["gpt-5.4", "gpt-5.4-mini", "claude-sonnet"]
}

429 rate_limit_exceeded

{
  "type": "https://api.strata.kronisys.com/errors/rate_limit_exceeded",
  "title": "API key rate limit exceeded (1000/1000 per hour). Retry after 42s.",
  "status": 429,
  "retry_after": 42,
  "used": 1000,
  "limit": 1000
}

A 429 rate-limit response also includes the Retry-After (seconds) and X-RateLimit-Reset (Unix epoch) headers, so you know exactly when to try again. Every successful response also carries X-RateLimit-Limit and X-RateLimit-Remaining.

Model governance and errors

The set of models a key may call is the intersection of your organization's allowed models, the key's allowed_models, and any role or per-user limits. Because your organization curates which models it enables from the central Model Catalog, a model that worked yesterday can return 403 model_not_allowed today if an admin disabled it — even if the key's own allowed_models still lists it. The organization's policy is always authoritative and is re-checked on every request.

Tip

Don't hard-code model IDs in retry logic. On a 403 model_not_allowed, read allowed_models from the response body and fall back to one of those, or surface the error to whoever provisioned the key.

How to handle errors

Build one error handler that reads type and decides what to do.

Retry on 5xx and 503

500, 503 budget_check_failed, 503 entitlement_check_failed, and 503 policy_lookup_failed are transient. Retry with exponential backoff (for example: 1s, 2s, 4s, 8s, cap at 30s) and a small amount of jitter. Cap total retries at 3–5 attempts.

Key

On the non-streaming POST /v1/chat, send an Idempotency-Key header on retries. Strata caches the first result for 24 hours and replays it on a repeat with the same key, so a network-timeout retry never creates a duplicate conversation or double-bills. While the first request is still running, a retry returns 409 request_in_progress — wait, then retry to fetch the cached result. Idempotency is not applied to streaming requests; streaming clients recover by reconnecting, not re-POSTing.

Back off on 429

When you receive a 429, wait for the duration in Retry-After (or until the timestamp in X-RateLimit-Reset) before sending another request with the same key. A budget_exhausted 429 will not clear until the organization's billing cycle resets, so back off long rather than retry tightly. Spreading bursts across multiple keys is fine; hammering a throttled key is not.

Don't retry most 4xx

400, 401, 402, 403, 404, 413, and 422 will never succeed on retry without changing the request. Surface them to your caller or your logs, fix the underlying cause (bad payload, missing scope, disallowed model, expired key, rejected spec), then send a new request. The exception is 409 request_in_progress, which clears once the in-flight request completes.

Log the request context

Log the type, title, and any extra fields (such as allowed_models or required_scope) on every failure. Include them in any support request — they let the Kronisys Inc. team trace the exact problem without asking you to reproduce it.

Related