Idempotency
Networks fail halfway. When a call times out, you can't tell whether Picked received it. This page explains which calls you can safely send again.
Your own number is the key
Orders and deliveries already carry a number your system gives them, and Picked recognises a repeat by it. Starting a process run has no such number, so it takes an Idempotency-Key header instead:
| Call | Recognised by | A repeat answers |
|---|---|---|
POST /api/v1/orders |
external_id, your order number |
200 with the order the first call made |
POST /api/v1/receipts |
reference, your delivery or purchase number |
200 with the receipt the first call made |
POST /api/v1/processes/{process}/runs |
the Idempotency-Key header |
the first call's answer, unchanged |
POST /api/v1/process-events/{eventKey} |
not recognised | a new delivery of the event |
For orders and receipts the first call answers 201 Created, and every repeat 200 OK with the same body shape, so your integration can treat both as success and store the id it gets back.
The Idempotency-Key header
Send Idempotency-Key with any string of up to 255 characters that is unique to the request, such as a UUID or your own job number. Picked keeps the first answer for 24 hours:
- The same key again, for the same request: you get the first answer back, status and body, with the header
Idempotency-Replayed: true. Nothing is done again. The first answer'sLocationheader isn't repeated; its_linkspoint to the same place. - The same key for a different request (another process, or other variables):
409with the codeconflict. A key is used once per workspace, whichever endpoint it was sent to. - A request that was refused (a
4xxor5xx) keeps no key, so you can fix the request and send it again under the same key. - Two requests with the same key at once: the second waits for the first and then gets its answer.
Keys are compared exactly: abc and ABC are two keys. After 24 hours a key may be used again.
A repeat changes nothing
A repeat returns what Picked already has, unchanged. If the repeat carries different lines or a different customer, those differences are ignored: it is not an update, and it is not an error either. Compare the answer with what you sent if you need to know.
Orders
An external_id is used once per workspace, for good. Importing it again returns that order, even if it has since shipped, been cancelled or been deleted.
Orders that arrive through a connected webshop or marketplace number their orders on their own, so they don't count: an API order and a shop order may share a number. Orders your team made in Picked by hand or imported from a spreadsheet do count.
Receipts
Always send a reference. Without one, Picked makes one up, and every call announces a new delivery, so a retry announces the same delivery twice.
If two calls with the same new reference arrive at the same moment, one of them makes the receipt and the other answers 422 with an error on reference. Send that one again: it now returns the receipt the first call made.
Process events
A process event is a signal, not a record. Each call delivers it again, and wakes whichever processes are waiting for it at that moment. Sending it twice usually wakes nothing the second time, because the processes woken by the first call are no longer waiting.
Send a process event again in two cases: when the call itself failed, and when it answered 200 with ids under deferred_task_batch_ids. Those processes matched the event but couldn't continue yet, for want of stock or capacity. Send the event again later, or the signal is lost for them.
Check without writing
To find out whether an order or receipt already exists, send the call with the Picked-Dry-Run: true header. The answer's would field says created or already_exists, and nothing is written.