Create an order (any document_type)
Atomic order create. A single POST creates the order header plus all inline children in one transactional write. Any child failure rolls back the entire graph — no half-baked orders.
Inline children accepted:
line_items[]— each entry specifiesproduct_id,quantity, and optionallyvariant_idorsell_rate(override). Pricing engine runs per-item (qty-break pricing levels, account defaults). Variant guard: if the product has variants,variant_idis required.discount— header-level discount applied as an order_adjustment row.{type: "percentage"|"flat", value: number}. Percentage is applied to the sum of line subtotals before tax.auto_compute_tax: true— triggers AvaTax (or local rate) after all items are inserted. Requires ashipping_address_id(or inlineshipping_address) that resolves to a US jurisdiction. Skips cleanly for tax-exempt accounts.auto_allocate_inventory: true— reserves stock per line item atlocation_id(falls back to entity default location). Returns422 insufficient_inventorywith shortfall details if any line lacks available stock. The rollback is atomic: no line is reserved if any line fails.payments[]— inline charge after the order and items are committed. Each entry:{payment_method_id, amount, payment_type?, auto_capture?}.payment_method_idis the Arcus internal UUID fromaccount_payment_methods. Payment failure does NOT roll back the order (industry standard — order persists withpayment_status: unpaid; retry viaPOST /v1/orders/{id}/payments). Results appear in_inline_payment_results[]in the response.
Response: fully hydrated order with line_items, payments, and tax_lines
expanded. Developer never needs a follow-up GET.
Totals guarantee (NEW-GAP Wave A.5, 2026-05-15): the response order
always lands with non-NULL subtotal, tax_total, shipping_total,
and order_total — the canonical totals helper runs inside the
same transaction as the order + line-item INSERTs, so a successful
201 implies the header has been recomputed against the just-inserted
items. Tax + shipping totals are 0 when no AvaTax connector is active
or the shipping address is incomplete (a warning is logged but never
leaks into the response envelope).
Idempotency: supply Idempotency-Key header to safely retry without
double-creating. The same key returns the same response.
See the Creating Orders guide for curl, TypeScript, and Python examples.
Authorizations
API key issued per entity via Settings > Developers > API Keys.
Each key carries scopes (e.g. orders:read, products:write).
Bearer token format: Authorization: Bearer ark_live_ent_Test keys use ark_test_ent_. Both are issued per entity
via Settings > Developers > API Keys.
Headers
Client-generated unique key for idempotent POST/PATCH/DELETE operations. Alias for the Idempotency parameter. Max 255 chars. On retry with the same key, the original response is returned without re-executing the operation. Keys expire after 24 hours.
255Body
Discriminator. sales_order and invoice are for customer accounts; purchase_order for vendors.
quote, sales_order, invoice, return, purchase_order Customer or vendor account. Account defaults (pricing level, addresses, payment terms) are auto-inherited.
Warehouse location for inventory allocation. Defaults to entity default location.
Shipping address. Auto-resolved from account default when omitted.
Billing address. Auto-resolved from account default when omitted.
Payment terms (e.g. Net 30). Auto-resolved from account, channel, and entity default cascade.
Override pricing level. Auto-resolved from account default when omitted.
Customer purchase order number.
Order date. Defaults to now.
Customer-visible notes.
Internal-only notes.
When true, do not ship partial. Inherited from account default.
Order-header shipping-method override. Accepts a Shippo service token (e.g. 'ups_ground') or a carrier service name (e.g. 'UPS Ground'); stored canonicalized as the token. Unrecognized values return 400 validation_failed. Omitted: inherited from the account's Default Ship Method when set. Drives rate-shop suggested-service selection (header override beats shipping rules).
Mark order tax-exempt. Requires avatax_entity_code on the order or linked account.
AvaTax exemption entity code (e.g. 'RESALE', 'EXEMPT').
Arbitrary key-value metadata stored on the order.
Inline line items. Inserted atomically with the order. Any failure rolls back all items and the order header.
Header-level discount applied to the order subtotal.
Run AvaTax (or local rate) after all items are inserted. Requires shipping_address_id to resolve to a taxable jurisdiction.
Reserve inventory per line item. Returns 422 with shortfall details if any line has insufficient stock. Rollback is atomic.
Inline payment(s). Fired after the order is committed. Payment failure does NOT roll back the order.
Response
Created order (hydrated with line_items, payments, tax_lines)
An Arcus ERP order document. One table holds quotes, sales_orders, invoices, returns, and purchase_orders -- always filter by document_type. entity_id is always from the API key (Layer 1 isolation).
order quote, sales_order, invoice, return, purchase_order draft, confirmed, partially_fulfilled, fulfilled, cancelled, voided, awaiting_ach_clearance, on_hold unpaid, partially_paid, paid, overpaid, refunded, partially_refunded, voided unfulfilled, partially_fulfilled, fulfilled Derived (display-only): SUM(list_price * qty) over non-kit lines. The gross baseline of the gross-to-net bridge (List price minus pricing_savings equals subtotal). Never part of order_total.
Derived (display-only): SUM(pricing_rule_adjustment * qty) over non-kit lines (positive magnitude). Per-unit pricing-rule savings already baked into subtotal via sell_rate (ASC 606 transaction price); shown as an informational List-to-Subtotal bridge, never subtracted from order_total.
SSOT: utils/ar-helpers.mjs::updateARBalance. Do not write directly.
AR receivable (the amount this document is owed AS A RECEIVABLE). Forced to 0 on DRAFT sales documents, on cancelled / archived / expired orders, and on voided or fully-refunded invoices, because none of those carries a receivable: a draft is not a receivable, and a terminal document owes nothing. This is the number that ties to AR aging, the AR outstanding total, and the GL AR control account. For the amount still COLLECTIBLE on any document at any status (including a draft), use amount_due. Purchase orders and quotes are never forced to 0. SSOT: utils/ar-helpers.mjs::updateARBalance. Do not write directly.
Collectible remainder: order_total minus amount_paid, rounded to 2 decimals. Status-blind BY DESIGN, so it answers "how much is still OUTSTANDING on this document as simple arithmetic" even where balance_due is 0 because the document is not (yet) a receivable. Negative when the customer has overpaid (money owed back to them). On a confirmed, non-refunded document with no sales allowance and no cancellation, amount_due and balance_due are equal. NOT A PAYABLE AMOUNT. Because it is status-blind it stays positive on documents that can accept no payment at all -- a cancelled / archived / expired order, a voided invoice, a fully-refunded order -- and it OVERSTATES what is owed on an allowance-settled order (a standalone concession refund reversed goods or tax: balance_due correctly settles to 0 while the remainder does not). Collecting amount_due on either shape creates an overpayment, and the payment endpoints will refuse it with order_not_payable (422). To decide how much to collect, take the amount from the payment surface you are about to call (POST /v1/orders/{id}/payments validates and caps server-side); to reconcile against AR aging or the GL AR control account, use balance_due.
ship, pick_up, local_delivery order, manual, proforma, correction 
