Reference
Idempotency
Network calls fail halfway. To retry a write safely, send an Idempotency-Key header — a repeat with the same key replays the original response instead of performing the write again.
How it works
- First request with a given key runs normally and its response is stored.
- Any repeat with the same key replays that stored response — no second invoice, receipt, or GL posting is created.
- A concurrent duplicate (the first is still in flight) gets
409 IDEMPOTENCY_CONFLICT— wait and retry. - Server errors (5xx) are not cached, so a genuine transient failure is always safe to retry with the same key.
- Keys are scoped per business and expire after 7 days.
Works on every write endpoint
The header is honoured on every POST — invoices (create and /post), receipts, expenses, bills, quotations, credit/debit notes, and the rest. It is not endpoint-specific.
Use one key per logical operation
Derive the key from something stable on your side — e.g. your order id plus the action (order_10428:invoice). Reuse the same key when you retry that operation; use a new key for a genuinely new record.
Example — retry-safe invoice post
curl -X POST "https://api.finorabusiness.com/v1/invoices?businessId=$BID" \
-H "Authorization: Bearer $FINORA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_10428:invoice" \
-d '{ "customerId": "cust_xyz", "status": "unsent", "lineItems": [ ... ] }'If the connection drops and you retry with the same Idempotency-Key, you get the original invoice back — never a duplicate.
Receipts: an extra natural key
Receipts additionally de-duplicate on a client-supplied reference (e.g. your order number): if a receipt with that reference already exists for the business, the existing one is returned. So a receipt is safe even without the header, as long as you send a stable reference. Other endpoints rely on the Idempotency-Key header.