Bulk Delete Sales Orders
DELETE/api/sales-orders
Bulk deletes sales orders in the background. IDs are resolved either from an explicit ids array or from a filters payload, then chunked (1000 per job) and dispatched as a job batch. Orders without return receipts are deleted first; orders with return receipts are deleted in a second batch.
orders:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Authentication: Requires Bearer token.
Request body (scope: one of ids or filters is required):
ids(array of int, required withoutfilters): Explicit sales order IDs to delete.filters(object, required withoutids): Resolves to a list of sales order IDs via the same Spatie QueryBuilder pipeline the V2 sales-orders list/export use. Two shapes are accepted:- Grouped filters (current list):
{ \"filter_groups\": \"<base64-encoded JSON tree>\" }. The decoded tree looks like{\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"order_status\",\"operator\":\"is\",\"value\":\"open\"}}]}. - legacy filter set (JSON string) for older clients.
- Grouped filters (current list):
apply_to_all(bool, optional): When true the action targets every order matching the activefiltersrather than an explicitidslist.
Behavior:
- Returns 200 immediately; deletion runs asynchronously via a background job batches.
- Sending
filtersas the groupedfilter_groupsobject is fully supported (previously returned a 500).
Requires permission: sales_orders.delete
Orders with a PayPal payment recorded or still clearing are never deleted; they are skipped and the response message says how many were kept. When every selected order holds PayPal money, nothing is dispatched and the message says none were deleted.
Orders whose returned stock has already been used elsewhere (a return receipt's units were consumed by later movements) are also kept, whether the ids came from ids or filters; the response message always reminds you that such orders are kept and should be cancelled or archived instead.
When filters selects the orders, archived orders are left out unless the filters set archived (bare archived or an archived.<operator> key) — the same rows the list shows for those filters.
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.