Get Sales Order
GET/api/v2/sales-orders/:salesOrder
Returns core sales order data for the V2 show page. Includes essential fields, addresses, channel info, totals, counts, custom fields, financial lines, tags, discounts, credits, RMAs, and purchase orders.
orders:readGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Line items are loaded separately via the lineItems endpoint for parallel loading.
Also returns the top-level flag use_sales_order_line_nominal_codes (boolean) — sibling to data — indicating whether the per-line nominal code editor should be enabled in the UI. Mirrors the accounting.use_sales_order_line_nominal_codes config value.
Payment / credit totals:
total_paid: aggregated sum ofpayments.amountfor the order — lets the UI render Paid/Balance Due without lazy-loading the payments array.- Each entry in
sales_credits[]includesrefund_payments_total(sum of cash/card refunds against the credit, always positive),applied_to_other_total(sum of credit consumed by Loop Returns EXC-* exchange orders, always positive),fees_retained_total(sum of fees Loop withheld out of the customer's credit — return shipping, restocking, etc., always positive), andoutstanding_amount(= total − refund_payments_total − applied_to_other_total − fees_retained_total, clamped to zero). The frontend usesoutstanding_amountfor the Credits line so partially-refunded credits no longer double-count against Balance Due. Each credit also includesmetadata(nullable object) — a minimal source subset{source, sales_channel_refund_id}used to render the channel-source chip (e.g. eBay refund-synced credits); null for manually created credits.
Authentication: Requires Bearer token.
Address override fields: shipping_overridden_at is an ISO-8601 UTC timestamp (or null) set when an operator manually corrects the ship-to/billing address; is_shipping_overridden is the boolean equivalent. When set, sales-channel resyncs (e.g. Amazon) will not overwrite the corrected inline address columns.
routing_provenance is present only when a published order-routing workflow chose this order's warehouse; it is null otherwise. It reports the workflow (workflow_id, workflow_name), the run that made the decision (execution_id), and the warehouse the workflow selected (warehouse_id). The ids are recorded at routing time and are not foreign keys, so workflow_name comes back null once the workflow itself is deleted while the ids remain. A warehouse_id that differs from the order lines' current warehouse means the workflow's choice was later overridden. This is the same object the legacy GET /api/sales-orders/{salesOrder} show endpoint returns — the V2 order detail page reads it from here.
Marketplace fee provenance — fee_source reports where this order's marketplace fee came from, or why there isn't one, so an empty cost-line list is never mistaken for a fee-free order. state is one of actual (the channel reported a settled fee), estimated (a configured rate stands in for one), pending (an estimate is in force while the channel has yet to settle), none (the channel has no fee source configured, so profit on this order is overstated), or unsupported (the channel charges no marketplace fee). Each entry in financial_lines carries fee_basis_source — actual or estimated for a channel-fee line, null for any other line — plus external_source_type / external_source_id naming the settlement record a line was derived from.
Mixed delivery: has_mixed_delivery is true when the order mixes shipped items and Click & Collect (in-store pickup) items, e.g. a Shopify "ship and pickup in one order" checkout. Each line's own delivery method is returned by Get Sales Order Line Items.
Delivery flags: requires_pallet_delivery is true when at least one line must be delivered by pallet (freight/LTL), set from the sales channel (e.g. an Amazon Business buyer choosing pallet delivery); pallet_delivery_line_count is the number of such lines. signature_required is true when delivery needs a signature.
fulfillment_order_count — the number of fulfillment orders on the sales order, including closed and cancelled ones. A cancelled order can report fulfillment_status: unfulfilled while still holding a cancelled fulfillment order (for example one cancelled locally whose carrier order may still ship).
Customer tax exemption: customer_tax_exempt (boolean) and customer_tax_exemption_reference (string|null, set only when exempt) are read live from the order's customer. A tax-exempt customer's order is created without tax whenever SKU.io computes the order's tax itself; channel-imported orders keep the channel's tax.
Financial lines written from a 3PL billing feed also carry external_source_provider (e.g. shipbob), external_source_route (the provider bill to open, e.g. /integrations/shipbob/4/bills?bill=123), external_source_label, external_source_fee_name and external_source_transaction_id; these are null on every other line.
Action availability:
- delete_unavailable_reason (string|null): Why the order can't be deleted right now (it holds a PayPal payment recorded or still clearing), or null.
- revert_to_draft_unavailable_reason (string|null): Why the order can't be reverted to draft (awaiting tracking, closed, or holds a PayPal payment), or null.
- sales_credits[].is_paypal_refund (boolean) / sales_credits[].locked_reason (string|null): A credit that records a refund made through PayPal is read-only and can't be deleted; locked_reason says why.
Per-payout Shopify stores:
payout_settlement: payout, outside_payout, left_out, pending or pending_left_out — where the order is settled and, for orders paid outside Shopify Payments, whether the store invoiced or left out such orders; recorded when the order is created; null for orders of per-order channels.revenue_booked_by: payout (the Shopify Payments payout books its revenue, also while pending), order_invoice (invoiced per order because it was paid outside Shopify Payments) or left_out (paid outside Shopify Payments while the store left those out of the books); null for per-order channels.
Request
Responses
- 200
- 401
- 403
- 404
- 429
OK
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.
Not found — no record with the given identifier (or the route does not exist). Verify the ID before retrying.
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.