The BenchKey API uses a single, consistent error envelope across every endpoint. When a request fails, the HTTP status is non-2xx and the body is always:
A required field was not supplied. param names the field.
invalid_field
A field was supplied but its value is invalid (wrong type, out-of-range, bad enum). param names the field.
invalid_query
A query parameter is invalid (wrong type, array where scalar expected, or out-of-range). param names the parameter.
invalid_idempotency_key
The Idempotency-Key header is present but does not meet length or character requirements.
invalid_value
A supplied value is semantically out of range for the target field (e.g. an integer exceeds the column’s 32-bit range, or a string exceeds its maximum length). Correct the value and retry. param names the field where known.
payload_too_large
The request body exceeds the maximum allowed size (HTTP 413).
The key’s tenant plan does not include public API access. details contains required_plan, current_plan, and upgrade_url.
payment_required
A billing action is required to proceed (e.g. past-due balance or entitlement gate).
billing_subscription_required
The tenant’s billing subscription is inactive. API access is unavailable until billing is restored. details contains billing_required, reason, subscription_status, and current_period_end.
The underlying operation timed out before completing. This is a transient error — retry with an Idempotency-Key to avoid duplicates. The response may include a Retry-After header.
The request is structurally valid but fails a business rule (e.g. closing a ticket that is already closed). The message field explains the specific rule.
At minimum, log error.code, error.message, and error.request_id for every non-2xx response. The request_id is the fastest path to support resolution when something goes wrong.