Update Invoice
Replaces the invoice’s economic document — the invoice.updated action.
The body still carries the FULL document (categoryId, dates, memo,
fieldData, lineItems); links are excluded by schema (they change via
re-link and
payee change).
The immutability law. Once an invoice is POSTED (a non-draft
creation, or finalize for drafts), its line items — ids, types, amounts —
and its category are FIXED: an update may change only incurredDate,
dueDate, memo, fieldData (and per-line memos), and must echo the
stored line-item set and categoryId verbatim. ANY line-item or category
deviation is rejected with 422 LINE_ITEMS_IMMUTABLE, at any payment
count — zero included. Corrections are void-and-recreate, payments
removed first. A DRAFT edits freely until finalize — the document
(line items and category included) replaces wholesale while drafting.
Concurrency. Send the invoice’s current headJournalId as If-Match
(from any read or write response). Stale → 409 IF_MATCH_CONFLICT with
the current invoice in the body; missing/malformed → 400.
Idempotency. actionId is a client-minted uuid; an identical retry
replays the original outcome (the watermark is not re-evaluated on
replay); reuse with a different payload is 409 ACTION_ID_REUSED.
Other preconditions (422). Cited types must belong to the cited
category (UNKNOWN_ID, reachable on draft edits); newly-introduced
refs must be live (DEPRECATED_CONFIG); voided/deleted invoices reject
updates (INVOICE_VOIDED / INVOICE_DELETED).
Required permission: company.payment:update
Authorizations
API key authentication. Send your raw API key as the Authorization header value with NO scheme prefix — Authorization: YOUR-API-KEY. Do NOT prefix it with Bearer or ApiKey, and do not use an X-API-Key header; those are not accepted.
Headers
The invoice's current headJournalId — the optimistic-concurrency watermark every single-invoice write after creation must send. Read it off any invoice read or write response and echo it verbatim (a bare uuid; an entity-tag dressing of it — "uuid" or W/"uuid" — is also accepted). Missing or malformed is a 400 (IF_MATCH_REQUIRED / IF_MATCH_INVALID); a stale value is a 409 IF_MATCH_CONFLICT whose body carries the current invoice. An idempotent actionId replay short-circuits BEFORE the watermark is evaluated.
Path Parameters
Company identifier
Invoice identifier
Body
Client-minted idempotency key — becomes the action's journal id. An identical retry replays the original outcome; reuse with a different payload is 409 ACTION_ID_REUSED
The transaction category — changing it requires zero live payments (422 LIVE_PAYMENTS)
Optional display label for the source system's author (e.g. the integrator-side user). Stamped as the journal record's display attribution; the acting principal stays the External API service user, so a label can never impersonate an in-app user. Ignored on idempotent replays
1 - 255The recognition date for the charges (ISO YYYY-MM-DD) — the period the amount lands in. May be in the future while the invoice is policy-linked; on an event-linked or unlinked invoice a future date is 422 FUTURE_DATE
When payment is owed — display metadata only
Free-text memo
Values for the tenant-defined custom invoice fields, keyed by field referenceId — an opaque JSON object
Response
The updated invoice — refreshed read state
The response of every single-invoice write — refreshed read state, not an ack: the emitted journal id(s), THE invoice row (identical shape to the reads — one invoice representation everywhere; its headJournalId is the next If-Match), and the invoice's live payments. An idempotent actionId replay returns this same shape rebuilt from the original outcome, server-minted values included.
Every journal id the write emitted — the anchor action's id (the actionId you supplied) first, then any engine-minted siblings (a multi-mark payment's additional marks) and any companion the horizon rule composed (e.g. the reserve unwind of a pre-horizon eroding payment's removal, or a delete's payment sweep)
1THE invoice representation — the same shape everywhere an endpoint returns an invoice (listing rows, the detail read, and every write's refreshed-row response). headJournalId is the invoice's current journal head — the optimistic-concurrency token subsequent writes echo back as If-Match.
The invoice's live payment marks after the write, newest first
