Idempotency for Accounting POST requests
Last updated: December 6, 2025
Merge's idempotency feature helps you safely retry POST requests without creating duplicate transactions in connected accounting systems. This guide explains how idempotency works in Merge, how to use it when posting accounting objects, and the best practices to avoid duplicates and data inconsistencies.
What is idempotency?
When you send a POST request with an Idempotency-Key header, Merge treats that request as a unique operation for 24 hours. Within that window:
First time with a new key: Merge processes the request and stores a log of the hashed body, status code, and response.
Same key with an identical body: Merge does not re-run the write. It returns the original response.
Same key with a different body: Merge rejects the request with a 400 error indicating invalid key reuse.
Why this matters:
Prevents duplicate invoices, payments, journal entries, or bank transactions during client-side retries or network issues.
Allows you to safely retry long-running or rate-limited asynchronous writes.
Idempotent operations are currently in beta. If you would like to enable this, please contact your Customer Success Manager
Header format and key selection
Header:
Idempotency-Key: <unique-string>Recommendation: Use a V4 UUID for each individual operation
Key lifetime: 24 hours
Scope: The key is evaluated against the full request, including URL, body, and relevant headers. Reusing a key for a different request body will result in a 400.
Tip: Generate a fresh UUID per transaction creation attempt on your side.
When to use idempotency
Use Idempotency-Key on any POST that creates accounting records, for example:
Invoices
Payments
Journal entries
Expenses or bank transactions
Purchase orders and vendor credits
Also use it for:
Client-side retry logic after timeouts.
Retries following
429 Too Many Requestsor transient5xxresponses.
Examples
cURL
curl -X POST "https://api.merge.dev/api/accounting/v1/invoices" \\
-H "Authorization: Bearer {MERGE_API_KEY}" \\
-H "Content-Type: application/json" \\
-H "Idempotency-Key: {uuid}" \\
-d '{
"model": {
"contact_id": "{contact_uuid}",
"issue_date": "2025-12-01",
"currency": "USD",
"line_items": [
{
"name": "Service Fee",
"total_amount": "120.00",
"quantity": "1",
"unit_price": "120.00"
}
]
}
}'If you need to retry, resubmit with the same Idempotency-Key and identical body within 24 hours of the original request. You’ll receive the same response envelope rather than creating a duplicate.
Best practices
Generate keys per object creation: One key per invoice creation, payment creation, etc.
Store keys alongside your outbound request record so you can reuse the same key on retries.
Keep bodies identical when retrying: Any difference will trigger a 400 for invalid reuse.
Pair with robust retry logic:
Retry on timeouts and 5xx responses with exponential backoff.
Respect 429 rate limits and retry-after guidance.
For client-side batching, give each object its own Idempotency-Key
Common scenarios
Network timeout after POST: Retry with the same key. Merge returns the same response if the first attempt succeeded or continues tracking the same operation.
400 Bad Requestinvalid key reuse: Confirm that the request body is identical to the original request that used that key, or generate a new key for a changed request.429 Too Many Requests: Delay per retry-after guidance, resend with the same key.
You need to re-run a changed request: Use a new key. Do not reuse the old key for a different body.
Troubleshooting
Received a duplicate record in the downstream system:
Ensure every retry reused the same
Idempotency-Key.Confirm that all retried bodies were identical.
Check that your client did not accidentally regenerate keys on retry.
400 Bad Requestinvalid reuse errors:Compare the original JSON and the retried JSON. Even small differences like reordered arrays, changed whitespace within strings, or defaults omitted in one request but present in another may result in a different hash.
409 Conflict: "Request with same idempotency key is currently in progress"When two or more requests with the same idempotency key are submitted in quick succession, one is being processed while the other(s) will return a 409 indicating that one is being processed
We recommend
ensuring two or more of the same requests are not submitted quickly, and
catching the 409 exception for when a duplicate request(s) is made while the first one is still processing.
FAQ
How long are keys valid?
24 hours. After expiration, reusing the same key will be treated as a brand new request.
Do I need idempotency for GET or PATCH?
Idempotency-Key is supported for POST operations to prevent duplicate creations
Can I use a non-UUID key?
Yes. Any sufficiently unique string works, but a UUID v4 is recommended.
How many characters can the idempotency key be?
50
If you have complex workloads like bulk writes or need help validating your retry strategy with idempotency, reach out to Merge support!