ar-invoices

Credit Ar Invoice

Fully credit an issued invoice: create a credit-note document — carrying a copy of the credited invoice's lines — and reverse the original's posting (AR + output VAT + open item back out) through the guarded storno door. Partial credits are a follow-up.

Dated body.posting_date, else today (never before the invoice): the credit note is printed with that date and its VAT reduction is declared in that date's VAT window — the credited invoice's output VAT is backed out of the MWST-Abrechnung, not just out of the ledger. The invoice's posted dunning fees are reversed with it.

Once the customer has paid, the cash actually received (fees included) is additionally posted as its own opposite-direction credit_note document against the AP control account: that gives the refund an open item a bank payment can settle (ar.service §credit note).

Refusals: 422 when the invoice is not issued, is itself a credit note, was already credited, or carries a write-off (a written-off invoice cannot be credited); 422 when posting_date predates the invoice or a dunning fee or payment the credit undoes, or when no open accounting period covers the credit's date — re-send with a posting_date in an open period (or open the fiscal year); 422 when a posted recognition installment would have to be reversed in a closed period (reopen that period; no date clears it); 409 when the credit's date falls in a filed/paid VAT period — re-send with a posting_date in an open VAT period.

post/companies/{company_id}/ar/invoices/{invoice_id}/credit-note

Request

  • Base URL: https://app.zeno-works.ch (the document declares no server; this is the origin it was published from)
  • URL: https://app.zeno-works.ch/companies/{company_id}/ar/invoices/{invoice_id}/credit-note
  • Auth: none declared

Path parameters

company_idstring required
invoice_idstring required

Headers

authorizationstring nullable

Cookies

access_tokenstring nullable

Request body

posting_datestring date nullable

Response

Successful Response

doc_type'invoice' | 'credit_note'
counterparty_idstring nullable
issuer_profile_idstring nullable
issue_datestring date required
due_datestring date nullable
service_period_startstring date nullable
service_period_endstring date nullable
currencystring
languagestring required
payment_terms_idstring nullable
invoice_discount_kind'none' | 'percent' | 'amount'
invoice_discount_valuestring
footer_textstring nullable
legal_textstring nullable
notesstring nullable
credited_invoice_idstring nullable
idstring required
status'draft' | 'issued' | 'cancelled' required

Editorial lifecycle owned by ar_invoice (paid/overdue are derived on read from the linked gl_open_item, not stored here).

origin'human' | 'system' | 'ai' | 'api' | 'mcp' | 'chat'

What KIND of actor posted a journal entry — the attribution flag.

Two axes in one vocabulary, because the column answers one question — can a reader take this as a person's own judgement?

Authorship — the value says who composed the booking:

  • ai = the AI-accountant composed it (an autonomous post, or a one-click accept where the content is still the accountant's proposal);
  • system = a mechanical/background SystemPrincipal post (migrations, close automation, deterministic seeds).

Channel — the value says which surface a person's own action arrived through, because "a UserPrincipal acted" is NOT the same claim as "a person decided". All four are derived from the request edge by :func:~invoiage_db.repos.gl_posting._resolve_origin:

  • human = an interactive browser session (cookie/JWT auth). The only value that asserts a person was looking at the screen;
  • mcp = an API-key request carrying the mcp shell's X-Zeno-Surface marker — a connected agent, which MAY be relaying a person and may not;
  • api = any other API-key request (a script, an integration, an agent calling the REST api directly). Not provably a person either;
  • chat = the built-in CFO chat relaying a person's approval in-app. Its authored bookings stamp ai; chat is only for the relay.

Widening this vocabulary is a one-way door on rollback: the PG type is a native enum converted at load (pg_enums._pg_enum), so an api whose Python enum lacks a value raises LookupError reading any row that carries it. See the 0112 migration.

document_nostring nullable
commercial_document_idstring nullable
snapshot_document_idstring nullable
net_totalstring required
vat_totalstring required
gross_totalstring required
payment_statusstring nullable
open_amountstring nullable
is_overdueboolean
sent_atstring date-time nullable
last_sent_tostring nullable
issued_atstring date-time nullable
created_atstring date-time required
updated_atstring date-time required

Changes

No recorded changes to this operation across all 1 revision of this API.