Submitting is asynchronous. POST /v1/commerce/submissions answers right away with 202 Accepted, then WHCC places your order in the background. Look up the submission to see what happened, then follow each order's fulfillment link for production and shipping.
202 means202 Accepted
WHCC has checked your submission and queued it. The body is the full submission with status: "submitting" and no orders key yet, because nothing has reached WHCC's order system. Save the id so you can look the submission up later.
Idempotency-Key headerIdempotency-Key is required on every submit call. It is a unique value you choose for the order, and it is how WHCC recognizes a retry. If a timeout or dropped connection makes your client send the same call again, the key keeps the order from being placed twice.
Use your own order ID if you have one. Otherwise generate a UUID (v4) and save it with the order before you send it, so a retry reuses the same key. On this route keys don't expire, so never reuse one for a different order. Keep the key short, the length of a UUID or an order ID: a very long header is rejected before it reaches the API.
missing
400, code submission.idempotency_key_required. Add the header and send again. A key that is empty or only whitespace counts as missing. The key is checked after the body, so a request with an invalid body and no key returns the body's 400 first, and only a clean body gets this one. The order is 415 for the wrong Content-Type, then request.invalid_json for a body that doesn't parse, then body validation, then the missing key.
same key, same body
Your original submission comes back, still 202, and nothing new is placed. It comes back as a snapshot that can lag the submission, so its status may already have moved past submitting. A replay can show status: "placed" while its guidance[] still says placement has not been confirmed and its order status is behind the one a lookup returns. Read GET /v1/commerce/submissions/{submissionId} for the current state and guidance, and don't act on the replay's guidance or order status. Retry this way as often as you need. Changing only metadata, or the order of items[], still counts as the same body, and you get the original submission with its original metadata.
same key, different body
409, code submission.idempotency_conflict. That key was already used for a different order, and your first submission stands. Changing reference or instructions is enough to make it a different body. Use a new key only if this really is a new order. See the worked 409 example.
Calculate is the opposite. It creates nothing, so it takes no Idempotency-Key, and sending one is a 400 (submission.idempotency_key_not_applicable).
Order status should come to you, not be fetched on a timer. Create an event subscription and WHCC posts order.accepted, order.rejected, order.shipped and order.cancelled for each order a submission produces. Match them to your checkout by ConfirmationId, which is each orders[] entry's confirmationId. A submission can produce several orders, so expect a set of events, not one.
Order events can't report a submission that failed before any order existed. So read the submission once after it settles, and whenever you need to reconcile, by its saved ID:
1
2
curl https://apis-stage.whcc.com/api/v1/commerce/submissions/<submissionId> \
-H "Authorization: Bearer <YOUR_API_KEY>"
The lookup shows whether WHCC placed every order, some, or none. Use it for reconciliation and for investigating an event that never arrived, and the fulfillment links below when you need an order's detail.
The submission's status tells you what happened to the request you sent, not the production status of each fulfillment order. Once orders[] is available, follow its actions.fulfillment.url to GET /v1/fulfillment/orders. That request returns a list, because one WHCC order can become several fulfillment orders. Follow a result's links.self to GET /v1/fulfillment/orders/{id} for its status, statusHistory, and shipments. See Orders & Fulfillment.
status valuesstatus tells you where the submission is in the order lifecycle:
staged
WHCC has your submission but hasn't started placing it. No orders key yet.
submitting
On its way to WHCC's order system. Every fresh 202 response reads submitting. No orders key yet.
placed
Every entry in orders[] was placed. Production and shipping may still be under way. If our team resolves a problem by hand, the submission can stay placed. Follow each order's actions.fulfillment link for current fulfillment details.
shipped
Every order in orders[] has shipped, and each entry's shippingInfo carries the details.
canceled
Every order in orders[] was canceled. Cancellation is done through the Orders & Fulfillment, or by WHCC customer service. A canceled order's entry reads order_canceled. When only some orders are canceled, the submission stays placed, so read each entry's status.
failed
Nothing was placed. Either every entry in orders[] failed, in which case read each entry's failure.code (see Errors & Rate Limits), or the submission couldn't be sent to WHCC at all and there is no orders key. In that case, contact WHCC support with the submission id.
partially_failed
Some orders in orders[] were placed and at least one failed. See below.
partially_failed carefullyOne submission can become several WHCC orders, and they don't all succeed or fail together. partially_failed means some of your customer's items are on their way and some aren't, under one submission ID. Don't treat it as "mostly fine." Walk every entry in orders[], act on each one that carries a failure, and decide whether to resubmit just those items, contact WHCC support, or tell your customer part of their order needs attention. Never resubmit the whole submission. This is the status integrations most often forget to handle, so write your handler before you need it.
1
2
3
4
5
curl -X POST https://apis-stage.whcc.com/api/v1/commerce/submissions \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <YOUR_ORDER_ID>" \
-d @submission.json
202 Accepted, trimmed. See Response Bodies for every field:
1
2
3
4
5
6
7
8
{
"id": "<submissionId>",
"status": "submitting",
"reference": "PO-90188",
"createdAt": "2026-09-24T20:50:31.518Z",
"items": [ { "…": "trimmed" } ],
"totalPrice": { "value": "91.26", "code": "USD", "…": "trimmed" }
}
Retrieve the saved id later to reconcile the submission (trimmed):
1
2
3
4
5
6
7
8
9
10
11
12
{
"id": "<submissionId>",
"status": "placed",
"orders": [
{
"confirmationId": "<confirmationId>",
"status": "order_placed",
"actions": { "fulfillment": { "url": "https://apis-stage.whcc.com/api/v1/fulfillment/orders?sourceConfirmationId=<confirmationId>", "method": "GET" } }
}
],
"…": "trimmed"
}
Once the order ships, status moves to shipped and the entry's shippingInfo fills in.
See the full submission on Response Bodies, or every error code on Errors & Rate Limits.