Dry runs
Try an order import or a delivery announcement against your real data, without writing anything. Picked has no separate test mode; a dry run is how you test a write before it counts.
How to send one
Add the header Picked-Dry-Run: true to POST /api/v1/orders or POST /api/v1/receipts:
curl -X POST "https://picked.nl/api/v1/orders" \
-H "Authorization: Bearer $PICKED_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Picked-Dry-Run: true" \
-d '{
"warehouse_id": 12,
"external_id": "WS-2026-104233",
"lines": [
{ "product_external_ref": "art-10021", "product_sku": "BEL-ZW-01", "quantity_ordered": 2 }
]
}'
Picked runs the call for real, against your workspace's real warehouses, products and orders, and then undoes it. Nothing remains: no order, no placeholder product, no stock reserved, nothing on the pickers' work list and nothing pushed to your sales channels.
What the answer says
A dry run answers 200 with the body the real call would have returned, plus two fields:
| Field | Meaning |
|---|---|
dry_run |
Always true, so you can tell a dry run's answer from a real one. |
would |
created if the real call would make a new order or receipt; already_exists if it would return one you sent before. |
{
"id": null,
"external_id": "WS-2026-104233",
"status": "pending",
"shipped_short": false,
"warehouse_id": 12,
"line_count": 1,
"provisioned_products": [],
"dry_run": true,
"would": "created"
}
The ids of anything that would only be created are null, because it doesn't exist: the order's or receipt's id, the product_id of a placeholder product, a receipt's created_at, and a receipt's reference when you didn't send one. When would is already_exists, you get the existing order or receipt with its real ids. Something that would only be created has no _links and no Location header yet: there is nothing to point at.
A request that is wrong fails exactly as the real call would: 422 with the same errors. That is the main use of a dry run: finding out whether Picked accepts your data before it counts.
What a dry run can't do
A dry run checks one call. It can't test a flow end to end:
- You can't read back what it made:
GET /api/v1/receipts/{id}has no id to ask for. - The order never reaches the warehouse, so you can't follow it through picking and shipping.
- Calls that depend on each other can't be chained, because the second one doesn't see the first.
To test a whole flow, make real calls while your workspace isn't live yet: before the warehouse works in Picked, nobody picks your test orders. Once you are live, ask us about a separate test workspace.
Rules
- The header must be
trueorfalse, sent once. Any other value answers400with the codebad_request, and nothing is done, so a typo never turns into a real write. falseis the same as leaving the header out: the call is real.- Only
POST /api/v1/ordersandPOST /api/v1/receiptssupport it.Picked-Dry-Run: trueon any other write, such as a process event, answers400and does nothing. - On a read,
truechanges nothing: the call runs as usual. - A dry run counts against your rate limit, like any other call.
- The token's request log marks dry runs, so you can tell them apart from real calls.