What atomic-create means
Most ERP APIs require multiple round trips to build a complete record. You create the parent, get the ID, then POST each child separately. If one child call fails midway, you are left with a partial record. Arcus create endpoints accept the entire resource graph in a single POST. Children (addresses, line items, pricing tiers, kit components, contacts) nest directly inside the parent body. The server writes every row in a single database transaction. If anything fails, the whole request rolls back and you receive a structured error with the exact field path that failed. The pattern is the same across all primary resources:POST /v1/orders sits outside the all-or-nothing rule: an inline payment is charged after the order is committed. See What runs after the commit.
Anatomy of an atomic-create request
Every atomic-create request follows the same structure:Transactional guarantee
Every child is written inside a singleBEGIN / COMMIT block. The database constraint rules that apply are:
- All-or-nothing: if any child fails validation or insert, the parent row and every already-inserted child are rolled back. You get a complete record or nothing.
-
Validated upfront: required fields on every child are validated before any write begins. The first validation error stops execution and returns a 422 with the exact
parampath. - Side effects in-transaction: GL postings, inventory reservations, and activity log entries all write inside the same transaction (or queue atomically post-commit for async paths).
-
Unknown references stop the request before anything is created: on
POST /v1/orders, anaccount_idthat names no account of your entity returns404withcode: account_not_found, and ashipping_address_idorbilling_address_idthat names no address of one of your accounts returns404withcode: address_not_found. An id that belongs to another entity gives the same answer as an id that does not exist, and no order is created.
Error response: exact param path
When a nested child fails, theparam field points to the exact location inside the request body. This makes it possible to display an error next to the right field in your UI without parsing the error message.
param format is dot-and-bracket notation, matching the shape of the request body:
line_items[2].quantity— third line item, quantity fieldvariants[0].pricing[2].pricing_level_id— first variant, third pricing tier, pricing level fieldaddresses[1].country— second address, country field
What runs after the commit
OnPOST /v1/orders, the order header, line items, discount, tax, and inventory allocation are one transaction. An inline payments[] entry is different: each payment is charged after the order has been committed, because the card or bank charge happens outside the Arcus database.
- A payment that fails does not roll back the order. The order stays, unpaid, and the 201 response carries an
_inline_payment_resultsarray with one entry per payment (itsindex, and for a failure acodesuch aspayment_method_not_foundorpayment_failedwith aparamsuch aspayments[0].payment_method_id). - Retry a failed payment with
POST /v1/orders/{id}/payments, which is one of the incremental endpoints below. - The order confirmation email and automatic coupons also run after the commit. A failure in either never changes the 201 response.
Posting dates on journal entries and vendor bills
POST /v1/journal-entries (the entry_date) and POST /v1/vendor-bills (the effective_date, which defaults to bill_date) post to the ledger on that date, so both check it before anything is written. The date must be inside the entity’s posting window (by default up to 180 days back and none ahead), in an open accounting period.
A date outside the window is refused with 422 and nothing is written:
backdate_beyond_allowed_rangewhen the date is further back than the windowfuture_beyond_allowed_rangewhen the date is further ahead than the window
backdate_reason (or future_reason for a future date), a string of 4 to 500 characters. The override is granted only when the identity behind the call holds the accounting.close_period permission and an accounting period covers the date; on a journal entry, a reason sent by an identity without it is refused 403; a reason that is too short or not a string is refused 422 with backdate_override_reason_invalid or future_override_reason_invalid. The reason is recorded on the audit trail of the entry or bill.
A vendor bill that carries landed-cost lines also returns landed_receipt_warnings, landed_allocation, and landed_duplicate_overridden beside data. A vendor invoice number already on file, or a landed charge that looks like a duplicate, is refused 409 unless you send allow_duplicate_override with a duplicate_override_reason. See Purchase-to-Pay Flow for the full bill workflow.
Idempotency
Every atomic-create endpoint honors theIdempotency-Key header. Generate the key before the first attempt and reuse it on every retry. If Arcus processed the original request but your network failed, replaying the same key returns the original response without writing anything twice.
Hydrated response
The 201 response always includes every child expanded inline. No additional API calls are needed to verify what was created.Incremental edits still work
Atomic-create does not replace the per-child endpoints. After creating a parent, you can add children incrementally:When to use atomic-create vs incremental add
Entity isolation
All child rows inheritentity_id from the authenticated API key. You cannot set entity_id in the request body; on POST /v1/accounts, any attempt returns 422 with code: forbidden_field. This ensures data isolation is structurally enforced at the API layer — one API key, one entity, every time.
See Also
- Creating Products, Kits, and Variants — variant parent with kit variants and qty-break pricing in one call
- Creating Accounts with Addresses — full B2B account graph with addresses, contacts, and payment methods
- Creating Orders — order with line items, tax, allocation, and inline payment
- Purchase-to-Pay Flow — PO through receipt, vendor bill, and AP payment
- Idempotency — how idempotency keys work across all create endpoints
- Error Handling — retry logic and structured error logging

