Retry Semantics
When and how to retry failed requests safely.
Parseo's retry model is simple: retry 5xx and 429; retry 4xx only for the two transient codes called out below.
Retry table
| Status | Retry? | Notes |
|---|---|---|
| 2xx | — | Success |
| 4xx (general) | No | Permanent — fix the request |
409 idempotency.request_in_progress | Yes | Another request with the same Idempotency-Key is still in flight; retry with backoff |
409 invoice.not_ready_for_export | Yes | Invoice is still being processed — poll GET /invoices/{id}/status until it reaches processed or failed, then retry |
409 other (e.g. idempotency.key_reused_with_different_params) | No | Permanent — sending the same key with different data is a client bug |
| 429 | Yes | Honor the Retry-After response header |
| 5xx | Yes | Exponential backoff recommended |
Backoff recommendation
For 5xx, use exponential backoff with jitter:
delay = min(30s, 500ms * 2^attempt) + random(0, 250ms)Cap at 5 attempts. Beyond that, surface the failure to your monitoring or on-call system — the problem is persistent and further retries won't help.
For 429, Retry-After is authoritative. Use the header value verbatim.
Idempotency keys make retries safe
Always send Idempotency-Key on POST requests. See Idempotency.
