Errors
HTTP-level errors, and the reason codes attached to non-succeeded documents.
EXPORT_AMOUNT_UNRESOLVABLE (400): our reading missed a transaction amount. Correct the row named in the message before exporting.
REPORT_UNAVAILABLE (403): a shared report or export is not available right now. Public responses do not disclose the creator's account protection state.
PASSWORD_REMOVAL_NOT_ALLOWED (403): password sign-in cannot be removed to bypass account protection. You can change your password. OAuth and passkey removal require completed protection and a fresh identity check.
TWO_FACTOR_SETUP_REQUIRED (403): an account with a password must enable an authenticator app (TOTP) for a sensitive action, even with a passkey or linked Google sign-in. Checkout, billing changes, reports, exports, sharing, connections, credentials and team changes require protection. The free first look, profile name, pricing, sign-out and account deletion remain available; deletion keeps its existing identity check. The app prompts inline and continues the action after setup. REST API keys and MCP credentials are blocked when their creating user needs setup; organization/service keys without a creator keep existing behavior. MCP uses JSON-RPC error -32005 with error.data.code TWO_FACTOR_SETUP_REQUIRED.
HTTP errors
API errors use this shape, except empty method negotiation responses such as 405:
{
"error": { "code": "INVALID_DOCUMENT_TYPE", "message": "...", "field": "document_type" }
}| Status | Meaning | Example |
|---|---|---|
| 503 | Maintenance | MAINTENANCE_MODE: retry after the number of seconds in the Retry-After header. Reads remain available under the release guard. During the cutover bridge, every request returns 503 with code MAINTENANCE and Retry-After: 60. |
| 400 | Bad request | Malformed body, missing required field, invalid document_type. |
| 401 | Unauthorized | Missing, invalid or revoked API key. |
| 402 | Payment required | QUOTA_EXCEEDED: this upload would exceed your plan’s included pages plus any page credits for the period. Upgrade your plan or buy a page pack (or, on an AppSumo plan, add another code) to continue. |
| 403 | Forbidden | The signed-in user’s role doesn’t allow this action, for example a member trying to change billing or org settings that only an owner or admin can. |
| 404 | Not found | The document, schema or webhook id doesn’t exist in your organization. |
| 405 | Method not allowed | Unsupported methods return an empty response with supported methods in the Allow header. HEAD follows GET; OPTIONS keeps its existing preflight behavior. |
| 409 | Conflict | An Idempotency-Key was reused with a different request body, or the action needs a document/org state (for example a terminal document) that isn’t there yet. |
| 413 | Payload too large | The uploaded file is over 25MB, or the document has more pages than the plan allows. |
| 415 | Unsupported media type | The file isn’t one of the supported types: PDF, PNG, JPEG, WebP or TIFF. |
| 429 | Too many requests | Rate limited; see the Retry-After header. |
Document reason codes
A partial / needs_review / failed document always carries one or more of these, attached to reasons[] and (for checks) the matching entry in checks[]. Codes are stable and never repurposed; a new failure mode gets a new code.
| Code | Drives status | Meaning |
|---|---|---|
| MULTI_ACCOUNT_DOCUMENT | failed | This statement covers more than one account. Upload each account's statement separately, or split the PDF. |
| PDF_PASSWORD_PROTECTED | failed | This PDF is password protected. Remove the password and upload it again. |
| NO_PAGES_PROCESSED | failed | Engine processed zero pages (corrupt or unreadable file) |
| NO_DATA_EXTRACTED | failed | Pages were processed but zero fields and zero table rows were found |
| UNSUPPORTED_DOCUMENT | failed | File type or content not supported |
| ENGINE_ERROR | failed | We could not process the file. Upload it again, or contact support@arkrel.com with the document id. |
| DEADLINE_EXCEEDED | failed | No terminal result before the processing deadline, fallback also exhausted |
| PAGES_INCOMPLETE | partial | pages.processed is less than pages.total |
| LINE_ITEMS_SUBTOTAL_MISMATCH | partial | Sum of line items does not equal the stated subtotal |
| SUBTOTAL_TAX_TOTAL_MISMATCH | partial | subtotal + tax (+ shipping - discount) does not equal the stated total |
| BANK_BALANCE_MISMATCH | partial | opening + credits - debits does not equal closing |
| RUNNING_BALANCE_DISCONTINUITY | partial | A transaction’s running balance does not follow from the previous one |
| TABLE_ROW_COUNT_MISMATCH | partial | row_count_extracted does not equal row_count_expected for a table |
| REQUIRED_FIELD_MISSING | needs_review | A required field has no value |
| TAX_RATE_INCONSISTENT | needs_review | Computed tax rate does not match a stated tax rate field |
| DATE_SANITY_FAILED | needs_review | A date failed to parse, is out of order, or is implausible |
| CURRENCY_INCONSISTENT | needs_review | More than one currency code appears across money fields |
| LOW_CONFIDENCE | needs_review | A required field’s confidence is below 0.5 |
Status precedence
When more than one thing is wrong with a document, the worst status wins:
failed > needs_review > partial > succeeded