How it works
Send anIdempotency-Key header on POST /v1/invoices (and any future write that documents the header):
- The key is any string of 1–255 printable ASCII characters, scoped to your environment. Derive it from something unique on your side (your order id, your job id), or use a UUID.
- The first request with a key executes normally and its response is stored for 24 hours.
- A retry with the same key and the same body returns the stored response without executing again, marked with an
Idempotent-Replayed: trueheader. The invoice is issued exactly once no matter how many times you retry. - The same key with a different body is rejected with
409 idempotency_conflict: a key names one logical request, not a slot to reuse. - While the original request is still running, a concurrent retry answers
409 idempotency_conflict. Wait and retry: once the original completes you get its stored response.
Failures
- Deterministic rejections (4xx, for example
invalid_tax_id) are stored and replayed like successes: retrying the same wrong request repeats the same answer without re-executing. - A
503 tax_id_validation_unavailable(census down) releases the key: nothing was persisted, so retrying with the same key re-executes once the census recovers. This is the retry theRetry-Afterheader schedules. - If a request ends in a truly unknown state (a crash mid-flight), the key stays blocked with
409for up to 24 hours rather than risking a duplicate. If you never received a response and the 409 persists, issue with a fresh key after checkingGET /v1/invoicesfor whether the original landed.
What not to do
- Do not reuse a key across different invoices, even after the previous one succeeded.
- Do not retry a 409 in a tight loop; use backoff and let in-flight requests finish.
- Do not skip the header on invoice creation. It is optional in the schema, mandatory in spirit.