Skip to content
Not released yet: version 0.1 is being built. See what works today.

API refusal codes

Match on the stable code, then follow the suggestion. REST service refusals carry error, message, field, value, rule and suggestion. MCP returns isError: true, a text explanation and structured code, field, value, rule and suggestion. Fields without a value are null.

This table lists every code in apps/api/src/services/codes.ts. Hidden and missing catalog details have the same status and fixed refusal bytes. An ambiguous name lists only visible candidates.

Code HTTP status Next step
dataset_not_found 404 Search for datasets you can use, then use a returned name.
metric_not_found 404 Search for metrics, then use a returned name or id.
term_not_found 404 Search for terms, then use a returned name or id.
node_not_found 404 Search, then trace a returned node id.
report_not_found 404 List reports, then use a returned path including .html.
ambiguous_name 409 Retry with one of the visible ids in the suggestion.
api_key_not_allowed 400 Declare api_key in the account’s credential_kinds in git and deploy.
api_key_not_found 404 Use the API key id returned when it was created.
busy 409 Retry after the concurrent key operation finishes.
connection_not_found 404 List admin connections and use a returned id.
engine_unavailable 502 Retry after the query engine recovers.
expiry_too_long 400 Shorten expires_in_days to the stated limit.
forbidden 403 Ask a person with the required permission to perform the action.
invalid_body 400 Send the documented JSON object.
invalid_cursor 400 Use the previous audit page’s next_cursor unchanged, once.
invalid_dataset 400 Supply the audit dataset filter only once.
invalid_decision 400 Supply the audit decision filter once, as allow or deny.
invalid_depth 400 Use a lineage depth from 1 to 10.
invalid_direction 400 Use up, down or both.
invalid_expiry 400 Use a positive whole number of days within the stated limit.
invalid_from 400 Supply one valid audit start time with its time zone.
invalid_key 400 Send a valid public JWK of the accepted type.
invalid_level 400 Use table or column.
invalid_limit 400 Use a whole number within this operation’s documented limit.
invalid_principal 400 Supply the audit principal filter only once.
invalid_query 400 Correct the AQL or search text using the refusal’s rule.
invalid_status 400 Supply the audit status filter only once.
invalid_to 400 Supply one valid audit end time with its time zone.
key_exists 409 Make a new key pair with a new kid; ids are never reused.
key_not_found 404 Use the uploaded key’s kid or public-key thumbprint.
key_pair_not_allowed 400 Declare key_pair in the account’s credential_kinds in git and deploy.
key_set_refused 400 Send one public JWK at the top level, not a key set.
not_ready 503 Retry after the api finishes setting up the account.
private_key_refused 400 Keep private material local; send only a new pair’s public JWK.
rate_limited 429 Wait for the retry interval in the refusal message.
service_account_disabled 409 Review the account declaration in git and deploy before adding keys.
service_account_not_found 404 Declare the account in access/service_accounts.yml and deploy.
too_many_live_keys 409 Revoke one of the two live keys before adding another.
unavailable 503 Retry after authorization, database or audit service recovery.
unknown_field 400 Remove the unrecognized body field.
unknown_filter 400 Use only the documented audit filters.
unsupported_key 400 Use a public EC P-256 or Ed25519 JWK.

REST and MCP validate arguments before calling services. These adapter refusals use invalid_input (400 in REST), with an input echo capped at 120 characters. MCP unexpected failures use internal with a request id. Authentication and HTTP guards have their own codes, such as origin_refused and body_too_large; they are outside the service-code table.

To add, rename or remove a service code, update this page with codes.ts in the same change. Announce a rename or removal as an interface change.