Skip to main content

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.