Resubmit an order that is on hold
POST/orders/:orderId/resubmit
Asks the fulfillment provider to fulfill an order again, with the shipping address and customer details the order carries now. You can resubmit an order that is on hold (holdStatus held), and an order sent with customer details that break the provider's rules (recipientFaults) without waiting for the provider to hold it. Correct the customer first — both kinds of order pick up customer updates — then resubmit. An order on hold is resubmitted for you when you correct its customer's name, phone number or shipping address, unless its holdReasonCode is one such a correction does not fix; calling this after that, before the provider answers, is refused as already resubmitted, and you can treat that refusal as done. The provider takes the change only while it is holding the order, so it may refuse an order it has not held yet; resubmit that one once it does. The provider answers asynchronously: holdStatus becomes resubmitted immediately, then clears once the provider accepts the order, or becomes held with a new holdReason if it holds it. An order held because the provider found no shipping option for it is also re-quoted automatically for a while; resubmitting it ends that and asks at once. An order held because the provider could not charge your prepaid balance for it (holdReasonCode insufficient_funds) is sent again automatically once the balance covers it; resubmit it to send it sooner, for example right after you top up, while the provider has it (externalOrderId is set). When the provider refused it before creating it, externalOrderId is empty and there is nothing to resubmit: use POST /orders/{orderId}/retry-submission instead. Only orders sent to NextSmartShip are resubmitted. ShipBob takes no resubmission, and an order it holds is never sent to it a second time. When ShipBob holds the order because it could not validate the shipping address (holdReasonCode address_invalid), resubmitting sends ShipBob the shipping address the order carries now instead, for the shipments it holds, and ShipBob checks it again. The order stays held until ShipBob releases it. The order's history records ShipBob's answer as a tpl_address_update_requested entry. If ShipBob did not save the address for every shipment it holds, the request is refused with the reason: correct the address in ShipBob. It is also refused if you cancelled some of the order's items or recorded a shipment of it yourself, because ShipBob would still ship those items. Every other order ShipBob holds is refused: resolve the hold in ShipBob, which ships the order itself once it releases the hold.
Request
Responses
- 200
- 202
- 400
- 401
- 403
- 404
- 429
- 500
- 503
- 504
The merchant is entitled but its OMS environment is not provisioned yet. Provisioning has been kicked off (exactly once) and is in progress; retry the request — it succeeds once the environment is ready. Returned only for identity-token (dashboard) requests bound to an active-entitled merchant, not for secret-key API calls; any such endpoint can return it while provisioning is underway.
The request was rejected. type is invalid_request_error; when the failure is a validation failure code is validation_failed and errors lists every problem found, with field-attributable entries prefixed by the field’s path.
No credentials were supplied, or the identity token / secret key is not valid for the target merchant. type is authentication_error.
The credentials are valid but lack the permission this operation requires. type is permission_error.
No resource exists with the requested identifier. type is not_found_error.
Too many requests. The rate limit is applied per client across all operations. type is rate_limit_error.
The request could not be completed because of an unexpected error. type is api_error.
A dependency needed to serve the request is temporarily unavailable — for every operation the auth service that verifies credentials and resolves entitlement, and on the provisioning routes also the ODUS API the OMS reconciles against. type is api_error. Unlike a plain 500 the condition is transient rather than a fault in the request, so it is worth retrying with backoff.
The request exceeded the processing time limit and was abandoned. type is api_error and code is timeout — unlike a plain 500 the request may still have taken effect.