Create an invoice document from a confirmed sales order
Generates the invoice record (a row in the canonical orders table
with document_type='invoice') from a confirmed sales order.
Stamps the invoice number from the configured counter and posts
the AR JE per the standard order-to-cash workflow. Distinct from
GET /v1/orders/invoices (the collection list endpoint).
Requires the orders:write scope. Idempotent via Idempotency-Key.
Historical import (migration only). The body fields
is_historical_import, invoice_date, and posted_at are
migration-mode flags that bypass live AR/GL posting and stamp the
caller-supplied dates. They are ONLY honored when the API key
carries the migration:write scope (or *); ordinary
orders:write keys have them silently ignored and ALWAYS receive
standard order-to-cash AR/GL posting. Every grant emits an
api_key.migration_option_used audit row.
Revision acknowledgment gate (HTTP 409 revision_unacknowledged).
If the order was revised after the customer received their copy and the customer has not
yet acknowledged the new total, this endpoint returns HTTP 409 with
code: revision_unacknowledged. Lift the gate via
POST /v1/orders/{id}/customer-acknowledge-revision, or bypass with
?override=true / {"skip_revision_ack": true} (requires orders.revision_override
permission). The gate is bypassed automatically when is_historical_import: true is
set for migration callers.
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.
255Path Parameters
Body
Migration-mode flag. When true AND the key carries
migration:write, the invoice skips the AR/revenue JE
(AR is loaded separately by the migration). Silently
coerced to false for non-migration callers.
Caller-supplied invoice date. Honored only when the key
carries migration:write; ignored otherwise.
Caller-supplied GL posting timestamp. Honored only when
the key carries migration:write; ignored otherwise.
When true, bypasses the revision acknowledgment gate. Requires the caller to have the orders.revision_override permission; returns 403 otherwise. Equivalent to the ?override=true query parameter.
Response
Invoice created
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.
ship, pick_up, local_delivery order, manual, proforma, correction 
