Skip to main content
Send an Idempotency-Key header with a write. Repeating the same request with the same key returns the original response and does the work once. Without a key, a timed-out request or a duplicate signup event can create a second subscription and a second invoice.

Send a key

Add an Idempotency-Key header to any POST request.
Use an id from your own system, such as your signup id, order id or event id. A random value generated on each attempt defeats the purpose, because a retry would send a different key.

What happens on a repeat

Saasybill compares the method, the path and the body of the repeat with the first request. Only a success is stored. A 4xx that was refused before anything happened doesn’t lock you out of your own key, so you can fix the body and resend under the same key.
A 201 from POST /v1/subscriptions counts as a success even when invoice.xero.sync_status is failed. The subscription and invoice exist, so a repeat returns that same response. It doesn’t raise a second invoice.

Extra protection for subscriptions and invoices

A new subscription’s id is derived from the API key and the idempotency key. If a server crashes after the subscription is saved but before the response is stored, your retry finds the subscription it already made and returns it. A crash can’t turn into a second subscription. A one-time invoice works the same way. A crash can’t turn into a second invoice, or a second bill.

Retry pattern

Retry on timeouts, 429, 500 and 502, with the same key and the same body. Back off between attempts.