Skip to main content

Create an invoice

POST 

/api/v1/workspaces/:workspace_id/invoices

Creates a new invoice for the specified workspace.

Before the invoice is built, the payload is completed with company-side defaults:

  • party_id resolution: a parties entry with a party_id (optionally billing_address_id) is filled from the company's directory (name, legal registration id/scheme, VAT id, routing identifier, billing address, default contact) and back-linked so the response's party_id round-trips. Lookup is scoped by STI type to match direction: buyer on sales resolves against the company's customers, seller on purchases against its suppliers; payee and tax_representative resolve against the whole directory. A party_id on the company's own role (seller on sales, buyer on purchases) returns 422 (api.invoices.errors.party_id_not_allowed_for_company_role) - that party is derived from the company record, not the directory. party_id and billing_address_id must be positive integers; anything else returns 422 (api.invoices.errors.invalid_reference_id) rather than being coerced. Any sibling attribute also sent on the entry overrides the corresponding directory value. An unresolvable party_id returns 422. When the directory record carries a SIRET declared under scheme 0009, the party is filled with the SIREN of the legal unit - the first 9 digits - under scheme 0002, because BR-FR-11 reads BT-47 off the 0002 selector and requires exactly 9 digits once the invoice is a B2B flux 2 piece; a value left under 0009 does not fill that selector at all and the assertion is fatal. Only the identity this endpoint copies from the directory is converted: a legal_registration_id sent explicitly on the entry is the declared intention of the caller and passes through untouched, and a 14-digit registration carrying no declared scheme is not converted either, since shape alone does not prove a French identity.
  • Company-side party default: when the payload has no entry for the company's own role (seller on direction: sales, buyer on direction: purchases), one is filled from the Company and its headquarters establishment. A party entry the caller does supply is never overwritten.
  • item_notes default: when the key is OMITTED and direction is sales, the company's legal disclaimers are inserted. purchases invoices get none. Sending an explicit empty array clears the collection and is never refilled - that is how an integrator removes existing notes on a PATCH.
  • payment_means default: when the key is OMITTED (an explicit empty array clears the collection and is never refilled), the company's on-invoice bank accounts are inserted, on both directions. On sales, when the buyer resolves to a directory customer that is confidentially factored, that customer's factor account replaces them. When a sales buyer is present but cannot be resolved to a directory customer (sent by name only, with no party_id and no persisted link), no payment means are inserted at all - factored status cannot be determined, and emitting the company's own accounts for a factored customer would misroute the payment.
  • Third-party payer profile guard: a parties entry with role: "payer" (the EXT-FR-FE-BG-02 block) is accepted only when customization_id is one of the two EXTENDED-CTC-FR forms - urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended (Factur-X/CII) or urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr (UBL). An omitted, blank, or plain EN 16931 customization_id returns 422 (api.invoices.errors.payer_requires_extended_profile) and writes nothing: the UBL and CII generators refuse to emit a payer outside EXTENDED-CTC-FR, so accepting one here would create an invoice whose every structured export fails, which the caller would only discover at download time.
  • Structured actors (XP Z12-014): buyer_agent (EXT-FR-FE-BG-01), seller_agent (EXT-FR-FE-BG-03), invoicee (EXT-FR-FE-BG-04) and invoicer (EXT-FR-FE-BG-05) are returned under their own key on read, populated on received documents; none is ever read as the seller, the buyer or the payer. They are accepted on create and update only under one of the two EXTENDED-CTC-FR customization_id forms, and the UBL and CII exports emit them there; under any other customization_id an entry returns 422 (api.invoices.errors.extended_role_requires_extended_profile). Each entry must carry a name (EXT-FR-FE-03 / -66 / -89 / -112, 1..1), sent or filled from party_id, else 422 (api.invoices.errors.structured_actor_name_required); an identifier must come with its identifier_scheme_id (EXT-FR-FE-07 / -70 / -92-1 / -116, 1..1), else 422 (api.invoices.errors.structured_actor_identifier_scheme_required); an endpoint_id must come with its endpoint_scheme_id (EXT-FR-FE-13 / -76 / -99 / -122, 1..1), else 422 (api.invoices.errors.structured_actor_endpoint_scheme_required); a legal_registration_id must come with its legal_registration_scheme_id (EXT-FR-FE-09 / -72 / -95 / -118), else 422 (api.invoices.errors.structured_actor_legal_registration_scheme_required); an address stating any field must carry its country_code (EXT-FR-FE-107 / -130, Factur-X EXTENDED), else 422 (api.invoices.errors.structured_actor_country_required), and a country_code that is not ISO 3166-1 alpha-2 returns 422 (api.invoices.errors.structured_actor_country_unknown); endpoint_scheme_id must be in the CEF EAS list (BR-CL-25), identifier_scheme_id and legal_registration_scheme_id in the ISO 6523 ICD list (BR-CL-10 / -11), each narrowed to the codes Scribee's scheme table carries less 0231 (reserved for the single taxable entity), else 422 (api.invoices.errors.structured_actor_scheme_outside_code_list); an endpoint_id over 125 characters returns 422 (api.invoices.errors.structured_actor_endpoint_too_long, BR-FR-25, fatal); any of those three schemes sent without its value returns 422 (api.invoices.errors.structured_actor_value_required), since it is emitted only as the value's attribute; a directory_routing_identifier returns 422 (api.invoices.errors.structured_actor_routing_identifier_unsupported) - it routes the seller and the buyer only, an actor's electronic address is its endpoint_id, and it is not copied from a party_id directory sheet onto an actor; a non-string name or scheme counts as missing; and a second entry of the same actor role returns 422 (api.invoices.errors.structured_actor_duplicated); a buyer_agent or invoicee without a buyer, or a seller_agent or invoicer without a seller, returns 422 (api.invoices.errors.structured_actor_parent_required), since UBL nests the actor inside that party - the company-side party the API adds counts. An invoice naming an invoicer is deposited only when the company holds an active third-party invoicer billing mandate for it on the issue date (XP Z12-014 cas 19a); otherwise the deposit returns 422 and the invoice stays a draft.
  • role_code guard: role_code is accepted on a payer (EXT-FR-FE-44), a payee (EXT-FR-FE-26) and a structured actor entry (EXT-FR-FE-04 / -67 / -90 / -113). Sending one on any other role returns 422 (api.invoices.errors.role_code_not_allowed_on_role), because no other role's value is ever emitted on the wire. The invoicee's code is always IV and the invoicer's II, and any other value returns 422 (api.invoices.errors.role_code_mismatch). On every accepted role, the value must come from the UN/CEFACT PartyRoleCode D22A list - the UNCL 3035 value space - and is matched case-sensitively; anything else returns 422 (api.invoices.errors.invalid_role_code). PR is the third-party payer code. On a payee entry the code also requires one of the two EXTENDED-CTC-FR customization_id forms: EXT-FR-FE-26 is defined only in the EXTENDED profiles and CII-SR-352 / UBL-CR-270 forbid the element in plain EN 16931, so a payee role_code under any other profile returns 422 (api.invoices.errors.payee_role_code_requires_extended_profile). A payee WITHOUT a role_code is plain EN 16931 (BG-10) and is accepted under every profile.
  • Currency guard: currency_code (BT-5), tax_currency_code (BT-6) and each tax_subtotals[].currency_code must be an ISO 4217 alpha-3 code drawn from the code lists Scribee vendors - the UN/CEFACT ISO3AlphaCurrencyCode enumeration unioned with the Peppol BIS ISO4217 list. Matching is case-sensitive, so eur is refused rather than upcased, and anything outside those lists returns 422 (api.invoices.errors.invalid_currency_code); the message names which of the three fields was refused. Acceptance here is not Peppol conformance: PEPPOL-EN16931-CL007 is fatal against its own narrower list, so a handful of codes are accepted at write time and still refused at Peppol export. An omitted or blank value is never refused - BT-5 falls back to EUR on create and to the invoice's existing currency on update.
  • VAT breakdown coherence guard (direction: "sales" only): the tax_subtotals must reconcile with the document totals. The sum of amount_without_taxes (BT-116) is compared with total_amount_excluding_taxes (BT-109), and the sum of vat_amount (BT-117) with total_tax_amount (BT-110), each within 0.01 - the tolerance PPF rule F1-START-TOTAL-COHERENCE-G1.53 spends at deposit. A gap beyond it returns 422 with code: "operation_failed" (api.invoices.errors.ventilation_not_reconciled) and writes nothing; the message names the total, the figure the document declares and the figure the breakdown sums to. Each half is judged on its own and is out of scope when its document total is omitted or when no tax_subtotals row states its amount - an omitted total is not a zero total, which is how the schematron reads it too. direction: "purchases" is never judged: a purchase recorded through the API is the reflection of a piece the tenant received and this platform never deposits it. The guard exists because BT-116 carries the base EXCLUDING tax, so a caller filling it with the tax-inclusive amount used to get a 201 here and a PPF refusal hours later.
  • Already-paid coherence guard (direction: "sales" only): an invoice or credit note stating the already-paid state - invoicing_process_id paid_goods_invoice / paid_services_invoice / paid_goods_and_services_invoice (codes B2 / S2 / M2, BT-23), or one of those codes in profile_id - must state the settlement itself: prepaid_amount (BT-113) equal to tax_inclusive_amount (BT-112), payable_amount (BT-115) 0, no payable_rounding_amount (BT-114) other than 0, and the payment date in due_date (BT-9), on or before issue_date. These are the fatal flux 2 rule BR-FR-CO-09 and EN 16931 BR-CO-16. Anything else returns 422 with code: "operation_failed" (api.invoices.errors.already_paid_*) and writes nothing. The API never fills these totals in, and it never infers the already-paid state from them: a paid invoice may also stay in the B1 / S1 / M1 family, which this guard does not judge. Stating the state creates no payment record and no lifecycle status. An already-paid invoice may not name a down-payment invoice by document_id in invoice_references either: that makes it a final invoice settling down payments, whose B4 / S4 / M4 family has no already-paid variant (XP Z12-014 CU-21), so it returns the same 422 and writes nothing.

Request​

Responses​

The created invoice, including any party, item-notes, or payment-means fields the API filled in from the company's directory defaults.