Errors
Error envelope and codes.
Envelope
All error responses share the same JSON shape:
Codes
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_json | Request body was not valid JSON. |
| 400 | invalid_request | JSON parsed but failed schema validation. Carries issues. |
| 400 | (none) | No upstream status to report: the URL did not resolve to a supported provider, or the call never reached the bank. Read error. |
| 401 | missing_key | No x-api-key header. |
| 401 | invalid_key | Key not recognised. |
| 401 | revoked_key | Key was revoked. |
| 429 | rate_limited | Hit the per-minute request rate. Includes Retry-After. |
| 429 | quota_exceeded | Hit the plan's uncached verification cap. Carries used and cap, plus Retry-After to the window rollover. |
| 429 | image_cap_reached | Hit the plan's monthly screenshot read allowance. POST /api/verify-image only. |
| 429 | ocr_daily_cap_reached | The service-wide daily screenshot budget is spent. Rare, and not about your account. |
| 502 | (none) | The bank answered but the receipt failed validation. See error and the partial receipt. |
There is no 504. A call that times out or gives up waiting for a busy bank
has no upstream status code to report, so it comes back as a 400 with the
reason in error. See
what a busy bank does.
POST /api/verify-image can also return ai_not_configured (503, the
extractor is not set up on this deployment) and detection_failed (502, the
extractor ran but could not read a receipt reference out of the image).
Retry guidance
rate_limitedwait theRetry-Afterinterval, then try again.quota_exceededandimage_cap_reacheddo not retry on a timer.Retry-Aftercan be days away, because the window is your plan's, not a minute. Upgrade, enable overage, or wait for the rollover.- 502 and the busy-bank 400 are usually the bank rather than you. Retry after 1 to 2 s with jitter and treat three consecutive failures as a real outage. Do not retry a Siinqee reference at all: those links allow about five views in total, so a retry loop destroys the receipt. See providers.
- 401 never retry. Mint a new key from the dashboard.
- 400
invalid_requestnever retry. The body is wrong.