Errors and retries
Recover from errors without accidentally creating another charged reading.
API errors use an English message, a stable code and an action:
{
"request_id": "00000000-0000-4000-8000-000000000001",
"error": {
"code": "concurrency_limited",
"message": "The company has reached its limit of active readings. Follow Retry-After.",
"action": "retry_later"
}
}
Use code and action in application logic; do not parse the human-readable message. Preserve the HTTP status, request_id and Retry-After for troubleshooting. An edge or network failure may not have the API's JSON envelope.
Actions
| Action | Typical codes | Next step |
|---|---|---|
fix_request | invalid_idempotency_key, missing_images, invalid_content_type, invalid_options, idempotency_conflict, result_expired | Correct the request. Recover an expired result from your saved copy. |
check_api_key | invalid_api_key | Check the server's key or contact support. |
replace_images | invalid_image, file_too_large, image_dimensions, identical_sides, image_too_complex, no_fields | Obtain suitable photographs. Changed bytes require a new transaction key. |
retry_later | rate_limited, concurrency_limited, admission_changed, image_service_unavailable | Respect Retry-After when present. Keep the same key and files. |
check_quota | quota_exceeded, trial_exhausted | Review the company's monthly allowance and contact support if needed. |
check_status | submission_unknown, service_unavailable, upstream_busy, upstream_timeout | GET the known request_id before considering another submission. |
contact_support | trial_expired, invalid_ocr_response, result_unavailable, processing_expired, terminal failure | Contact support with the request identifier, without secrets or document data. |
The action is recovery guidance, not a promise that a request consumed no quota. Completed readings and no_fields failures remain billable. New technical failures are credited in quota when recorded; their attempt history remains. Historical failures keep their recorded usage. A quota credit is not a cash refund or an automatic retry.
Idempotency rules
Create a stable key once per business transaction and save it before sending. Use 8–128 characters from A–Z, a–z, 0–9, ., _, : and -.
| Situation | Behavior |
|---|---|
| Same company, key, exact bytes, mode and profile | Reuses the existing job, including across API versions. No extra unit. |
| Same key, changed bytes, mode or profile | HTTP 409 idempotency_conflict. |
| New key, even with the same photographs | Can create a new reserved job and consume another unit. |
| Expired or failed existing job replay | Returns that job's expiry or failure; it does not restart OCR. |
Do not generate a fresh key in an automatic retry loop. A timeout or disconnect does not reveal whether the server reserved a job, ran OCR or saved a result. If a request identifier is known, query it first. If it is not known, retain the same key and bytes when making an explicit recovery attempt.
Rate limits and terminal failures
Admission rejections use HTTP 429. concurrency_limited normally asks you to wait two seconds; rate_limited uses a rolling-window delay of 1–60 seconds; admission_changed asks for one second. Read the actual header. A monthly quota error does not promise a short retry interval. An expired pilot returns 403 trial_expired; an exhausted pilot returns 429 trial_exhausted. Neither creates a new job. Existing results remain retrievable within their normal access window.
GET or replay can return HTTP 422 for a failed reserved job. Stop polling that job. When a stored failure would otherwise suggest check_status, the action becomes contact_support to prevent a loop.
If a GET returns 404 after a confirmed pre-reservation rejection, an explicit POST retry can retain the same key and files. Do not infer that every 404 authorizes a new transaction: check the company, request identifier and original error first.
Contact ecodevcontact@gmail.com with the request identifier and error code. Keep API keys, dashboard codes, photographs and extracted personal data out of support messages and logs.