Idempotency & rate limits
Retry any write safely with Idempotency-Key, and the per-key quota shared with the Storefront API.
Idempotency-Key
Every write on this API lists Idempotency-Key as a parameter in the
reference. Send a fresh random key per
logical request and retry with the same key on a network failure, and the
second request cannot execute twice.
curl -X POST https://api.usequeek.com/api/v1/merchant/inventory/adjustments \
-H "X-Client-Key: sk_live_..." \
-H "Idempotency-Key: 7d3c4c1a-2c50-4c0f-8f0f-3a4d1a2b9c77" \
-H "Content-Type: application/json" \
-d '{ "product_ids": ["the-id-from-a-listing"], "quantity_change": -2, "type": "adjustment", "reason": "weekly stocktake" }'The contract:
| Situation | Result |
|---|---|
| Same key, same body | The stored status and JSON body are replayed with Idempotent-Replayed: true for 24 hours. |
| Same key, different body | 409 idempotency_key_reuse. The key already means something else. |
| Same key, two requests in flight | The second waits up to 15s for the first to finish, then replays its response. If it is still running, Queek returns 409 idempotency_key_in_progress; retry with the same key. |
The response status is 400 or higher | The response is not stored. A retry with the same key runs the request again. |
| 24 hours later | The stored response has expired; the same key starts a new request. |
The slot is store + caller + METHOD:path + key, and the caller is the
Merchant API key itself — two keys of one store never replay each other's
writes. The body is checked against the stored request fingerprint, not used
as part of the slot. GET requests ignore this header. Always send a key on
writes: without one the request runs without idempotency protection.
Rate limits
Merchant API calls using the same private key share one per-key quota across the Merchant and Storefront APIs. The quota is based on the store's plan:
| Bucket | Ceiling |
|---|---|
| Per plan, per key | free 60/min · social_media 120/min · starter 120/min · growth 240/min · scale 1200/min · enterprise 2400/min |
When the key reaches its quota, Queek returns 429 too_many_requests with
Retry-After. Wait for that interval before retrying. The quota applies to
each private key; app installation credentials use the same per-key rule.
Invalid or refused credentials have a separate per-address refusal limit. Valid credentials are not charged to that refusal bucket.