Errors
Every error has one shape. Branch on code: it is stable, and a code is never renamed or reused. The errors a correct integration still sees often are period_locked, send_validation_failed, and rate_limited.
Any call can answer the common errors: invalid_key, key_expired, key_revoked, wrong_environment, live_key_from_docs, api_access_disabled, invalid_request, rate_limited, api_error, service_unavailable.
The whole list downloads as JSON: errors.json.
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_request |
The body is not valid JSON, or a value has the wrong type. param names it. |
| 400 | unknown_field |
The body has a field the API does not accept. |
| 400 | read_only_field |
The body sets a computed field (e.g., grand_total). |
| 400 | missing_required_input |
A required field is missing. |
| 400 | invalid_line_type |
A line type other than product, service, custom, or text, heading included. |
| 400 | currency_not_supported |
currency is not usd. |
| 400 | idempotency_key_required |
A create, send, or void with no Idempotency-Key and no external_id. |
| 401 | invalid_key |
The key is wrong or malformed. |
| 401 | key_expired |
The key passed its expiry date. |
| 401 | key_revoked |
The key was revoked, or its member was deactivated. |
| 401 | wrong_environment |
A co_test_ key reached a real tenant, or a co_live_ key reached QA or a sandbox. |
| 402 | billing_locked |
The tenant's subscription is locked. |
| 403 | api_access_disabled |
API access is off for this company. Every key gets this until staff turn it on. |
| 403 | scope_missing |
The key lacks the scope. param names it (e.g., invoices.send). |
| 403 | member_lacks_permission |
The key's member is not allowed to do this in the app. |
| 403 | agent_key_not_allowed |
An agent key called the REST API. |
| 403 | live_key_from_docs |
A co_live_ key was sent from the docs site's Try it panel. |
| 404 | resource_missing |
No such record, or the key cannot see it. param names the id. |
| 409 | idempotency_conflict |
The same Idempotency-Key with a different body. |
| 409 | external_id_exists |
A create with an external_id already used. The error carries the existing id. |
| 409 | books_not_set_up |
The tenant has no chart of accounts yet. |
| 409 | period_locked |
The write would post on or before the lock date (books_locked_through). |
| 409 | invoice_not_draft |
A change that only a draft allows (lines, amounts, delete). |
| 409 | invoice_locked |
A change to an invoice with a payment applied. |
| 409 | invoice_fix_in_progress |
The owner has the invoice open in "Fix the numbers". |
| 409 | invoice_not_voidable |
The app would refuse this void (e.g., already voided). The message gives the app's reason. |
| 422 | send_validation_failed |
Send rules I1 to I9 failed. errors lists each one. |
| 429 | rate_limited |
Too many requests. Carries Retry-After and reason (key_rate or tenant_rate). |
| 500 | api_error |
Our fault. |
| 503 | service_unavailable |
The API is down or overloaded. |