What is idempotency?
An idempotent operation can be repeated multiple times without changing the result beyond the first execution. On the Arcus API, idempotency protects you from creating duplicate orders, payments, or other records when a request fails partway through (network timeout, server restart, etc.).How to use it
Include theIdempotency-Key header on a write operation that accepts it. Most POST operations do, including POST /v1/orders; some PATCH operations do, such as PATCH /v1/orders/{id}; a few DELETE operations do; DELETE /v1/orders/{id} does not. Each operation’s page in the API Reference lists the header when it is accepted. The value must be unique per operation — a UUID v4 is the recommended format.
Replay behavior
Keys are scoped to your entity, so the same string used by another entity never collides with yours. A replay returns what the first attempt returned, so after you fix a request that was rejected, send the corrected request with a new key.
24-hour replay window
Arcus stores idempotency keys and their responses for 24 hours. After that window, the key is expired and a new request with the same key is treated as a fresh operation. If your retry strategy spans more than 24 hours, generate a new key.Key format
The key can be any string up to 255 characters. Best practices:SDK usage
All SDKs handle idempotency keys automatically for safe retries:When to use idempotency keys
Use them on every write operation that accepts the header. The most critical cases:- Creating orders, invoices, or payments
- Processing refunds
- Purchasing shipping labels
- Posting journal entries
- Any financial or inventory-affecting operation
Bulk imports and async jobs
The migration endpointPOST /v1/entities/{entity_id}/migration/{resource}/bulk accepts Idempotency-Key and gives you two distinct safety nets. A request carries up to 1000 records, and some heavy resources accept fewer per call (a larger batch returns 400 with code: batch_too_large_for_resource and the limit), so a loader splits a big load into batches.
-
Request-level idempotency (this header). If your loader retries the same bulk request after a network timeout, you get the original 202 response back with the same job
id. No duplicate jobs queued. PollGET /v1/entities/{entity_id}/migration/jobs/{job_id}for the job’s current status. -
Per-record provenance idempotency (
external_source+external_id). Even if you submit the same record across multiple jobs over time, the canonical handlers use the(entity_id, external_source, external_id)partial unique index to upsert. Re-runs against the same source data are safe.
Idempotency-Key for each batch, and pick up where it left off without creating duplicates.
conflict_mode semantics
The bulk endpoint takes a conflict_mode body field that controls behavior when a record already exists at the provenance key (external_source, external_id):
skip(default) - leave the existing row untouched, count it asskipped.update- PATCH the existing row with the new field values; preserves any Arcus-side fields not in the payload.replace- DELETE the existing row and INSERT the new payload as if it were a fresh record. Use with care.error- return an error envelope per-record and continue processing the rest.
Dry-run mode
Add?dry_run=true to validate a payload without writing anything. The endpoint returns a synchronous 200 with the result envelope, and no records are created, updated, or replaced. Use this in CI to catch schema errors before the real run.

