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.