List Release Candidates
GET/api/sales-orders/release-candidates
Lists open sales orders that never produced a fulfillment, split into the ones that can be dispatched right now and the ones that are still blocked, grouped by reason.
Automatic dispatch runs once per order, when the order is created or edited. If that single attempt does not go through — or if it ran while something was still blocking the order, such as an unmapped line or a warehouse with no address — nothing tries again and the order stays open indefinitely. Clearing the blocker afterwards does not re-trigger dispatch either. This endpoint finds those orders so they can be reviewed and released.
Authentication: Requires Bearer token.
Query parameters: none.
Response fields:
- releasable_count (integer): How many of the scanned orders have nothing blocking them and can be dispatched now.
- blocked_count (integer): How many of the scanned orders are still blocked.
- scanned_count (integer): How many candidate orders were diagnosed in this pass. At most 500 are diagnosed per request.
- candidate_count (integer): Total number of open orders with no fulfillment, before the 500-order scan limit is applied.
- oldest_days_open (integer): Age in days of the longest-waiting candidate order. Measured across every candidate, not just the scanned window, so it stays accurate when truncated is true. 0 when there are no candidates.
- truncated (boolean): True when candidate_count is greater than scanned_count, i.e. more candidates exist than were diagnosed.
- releasable (array of objects): One entry per releasable order — id (integer), sales_order_number (string, nullable), customer_name (string, nullable), sales_channel_name (string, nullable), order_date (string, Y-m-d, nullable), days_open (integer), diagnosis (object, see below).
- blocker_breakdown (array of objects): One entry per distinct blocker, sorted by count descending — blocker (string), label (string), description (string), is_operator_actionable (boolean), count (integer), sales_order_ids (array of integers).
Diagnosis object (returned on each releasable order):
- sales_order_id (integer)
- blocker (string, nullable): Blocker code. Null when nothing is blocking the order.
- blocker_label (string, nullable): Short human-readable name for the blocker.
- detail (string, nullable): One sentence explaining the reason for this specific order.
- is_releasable (boolean)
- is_operator_actionable (boolean): False for blockers only time or incoming stock clears (awaiting_stock, held, before_inventory_start_date), and false whenever blocker is null; true otherwise.
Blocker codes: not_from_sales_channel, unmapped_lines, no_shipping_method, shipping_method_excluded, awaiting_stock, out_of_sync, held, before_inventory_start_date, no_warehouse_on_lines, warehouse_auto_dispatch_disabled, warehouse_manual_fulfillment, warehouse_missing_address, shipping_address_invalid.
Blockers reported with is_operator_actionable = false (awaiting_stock, held, before_inventory_start_date) clear on their own once stock arrives, a hold expires, or a date is reached. Every other blocker can be fixed and the order then released.
Request
Responses
- 200
- 401
- 403
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.