Skip to content

Idempotency

Inventory integrations must be safe to retry. Network timeouts, process restarts and upstream retries should not duplicate stock movements.

Send a request id on every request:

X-Request-Id: req_...

Request ids are for observability. They help correlate client logs, API logs and support tickets. They do not make writes idempotent.

Send one idempotency key per logical write operation:

Idempotency-Key: receive-po-10001-line-1

Use idempotency keys for operations that create or change inventory state, including product/location creation, stock operations, reservations, transfers, inbounds and outbounds.

Reuse the same idempotency key only when retrying the exact same request after a timeout or transient failure.

An idempotent replay does not create another ledger mutation and does not consume another billable inventory operation. It is still a new HTTP request, so an API-key retry consumes one additional api_requests unit.

Do not reuse a key for:

  • A different payload.
  • A different organization.
  • A different business operation.
  • A new attempt after the original operation succeeded and the business intent changed.

If the same key is reused with a different payload, Skunivo returns IDEMPOTENCY_CONFLICT.

import { createIdempotencyKey } from '@skunivo/sdk'
await client.stock.receive(
{
productId,
locationId,
quantity: 10
},
{ idempotencyKey: createIdempotencyKey('receive', 'po-10001-line-1') }
)

Use stable business identifiers when available. For example, combine purchase order, order line, fulfillment id or transfer id with the operation name.

  • Treat idempotency keys as retry keys, not as random request ids.
  • Persist the key in your job record when the write is triggered by a queue.
  • Keep the Skunivo response or resulting resource id in your own system when possible.
  • Log both Idempotency-Key and X-Request-Id, but never log API keys.