---
title: "Retrieve an event"
method: GET
path: "/companies/{company}/events/{event}"
tags: ["Events"]
---

# Retrieve an event

`GET /companies/{company}/events/{event}`

## Request

- Base URL: `https://api.factuarea.com/v1`
- URL: `https://api.factuarea.com/v1/companies/{company}/events/{event}`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Retrieve a single event by its `id`, a UUID v7. Useful for auditing and replaying webhook payloads. Returns `404 event_not_found` if the event does not exist or belongs to another company.

## Path parameters

- `company` string, uuid, required
- `event` string, uuid, required

## Headers

- `Factuarea-Version` string, date

## Response `200`

- object
  - `data` Event, required: A read-only record of something that happened in your account. The same object is delivered to your webhook endpoints.
    - `id` string, uuid, required: Opaque identifier of the event, a UUID v7 (e.g. `01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a9b`). Consistent with the `id` field of every other v1 resource.
    - `object` 'event', required: Always `event`.
    - `type` string, required: Event type in `<category>.<action>` form (e.g. `invoice.paid`, `quote.approved`). See `GET /event-catalog` for the full list.
    - `aggregate_id` string, uuid, nullable, required: UUID v7 of the resource that produced this event (e.g. the invoice for `invoice.paid`). `null` for events without backfill. Distinct from `id`, which identifies the event itself.
    - `correlation_id` string, uuid, nullable, required: UUID v7 correlating this event end-to-end with the operation that produced it. `null` for events without a correlation context (e.g. born from scheduler sweeps). The key is always present.
    - `api_version` string, nullable, required: API version (date-based) the event data was serialized under, sealed at emission (e.g. `2026-10-05`). An event re-emitted by an automation declares the payload version its data was frozen in, which can be older than the latest version. `null` only for legacy events emitted before versions were sealed.
    - `livemode` boolean, required: `true` for events generated in production (live keys, `fact_live_`); `false` for events generated in test mode (sandbox company, test keys `fact_test_`).
    - `test` boolean, required: `true` when the event is a test delivery triggered from the dashboard; `false` for real events. Orthogonal to `livemode`, which reflects the key environment (live vs sandbox): a test delivery may be issued in either, so e.g. `livemode: true, test: true` is valid.
    - `data` union, required: The payload embedded when the event was emitted, discriminated by `type`. Carries the full snapshot of the affected resource under `object` — identical to the `GET` of that resource at emission time (for an invoice, `GET /v1/companies/{company}/invoices/{invoice}`) — plus event-specific keys, e.g. `{ "type": "invoice.paid", "object": { ...invoice... }, "amount": "1210.00" }`. The snapshot is frozen: later changes to the resource do not rewrite past events.
      - EventDataInvoiceCreated: Payload (`data`) emitted with the `invoice.created` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.created', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoiceAutoCreated: Payload (`data`) emitted with the `invoice.auto_created` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.auto_created', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `invoice` object, required
          - `uuid` string, uuid, required
          - `number` string, nullable, required
          - `client_uuid` string, uuid, nullable
          - `total` string, required: Total amount of the invoice (EUR), as a 2-decimal string.
          - `source` string, required
      - EventDataInvoiceCorrectiveAutoCreated: Payload (`data`) emitted with the `invoice.corrective_auto_created` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.corrective_auto_created', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `corrective` object, required
          - `uuid` string, uuid, required
          - `original_invoice_uuid` string, uuid, required
          - `refund_id` string, required
          - `provider` string, required
          - `amount` string, required: Amount of the individual refund (EUR), as a 2-decimal string.
          - `correction_type` string, required
      - EventDataInvoiceSubscriptionAutoCreated: Payload (`data`) emitted with the `invoice.subscription_auto_created` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.subscription_auto_created', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `subscription` object, required
          - `uuid` string, uuid, required
          - `stripe_subscription_id` string, required
          - `stripe_invoice_id` string, required
          - `billing_reason` string, required
          - `period_start` string, date, required
          - `period_end` string, date, required
      - EventDataInvoiceUpdated: Payload (`data`) emitted with the `invoice.updated` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.updated', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoiceIssued: Payload (`data`) emitted with the `invoice.issued` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.issued', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoiceSent: Payload (`data`) emitted with the `invoice.sent` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys. Deprecated: alias of `invoice.issued`, emitted at the same instant and with the same `data.object`. New integrations should subscribe to `invoice.issued`; its removal will be announced with a `Sunset` date.
        - `type` 'invoice.sent', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoiceMarkedSent: Payload (`data`) emitted with the `invoice.marked_sent` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.marked_sent', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoiceUnsent: Payload (`data`) emitted with the `invoice.unsent` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.unsent', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
      - EventDataInvoicePaid: Payload (`data`) emitted with the `invoice.paid` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.paid', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `amount` string, required: Amount of the payment that settled the invoice (EUR), as a 2-decimal string.
        - `payment_date` string, date, nullable, required
        - `payment_method` string, nullable, required
        - `payment_reference` string, nullable, required
      - EventDataInvoiceCancelled: Payload (`data`) emitted with the `invoice.cancelled` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.cancelled', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `cancelled_at` string, date-time, nullable, required
      - EventDataInvoiceAnnulled: Payload (`data`) emitted with the `invoice.annulled` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.annulled', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `annulled_at` string, date-time, nullable, required
        - `reason` string, nullable, required
      - EventDataInvoiceOverdue: Payload (`data`) emitted with the `invoice.overdue` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.overdue', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
            - `total` string, required
            - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime of the line: the per-document override (`iva`/`igic`/`ipsi`) when the user set it (precedence override>zone), otherwise `null` (derived from the establishment AEAT zone). Writable per-document input on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
            - `variant` object, nullable, required
              - …
            - `presentation` object, nullable, required
              - …
            - `item_kind` string, nullable, required
            - `commercial_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `base_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'null', nullable, required
            - `conversion_factor` string, nullable, required
            - `base_quantity` string, nullable, required
            - `price_list_id` string, nullable, required
            - `price_list_name` string, nullable, required
            - `price_source` string, nullable, required
            - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
            - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
            - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
            - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
              - …
            - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
              - …
            - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the resolved price: `per_base_unit` (product/variant own price, converted once by the presentation factor) or `per_commercial_unit` (presentation, combination or price-list entry, never converted). `null` on a line with no catalog price context.
            - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string. Informational when an exact price already absorbed them.
            - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the resolved price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined — the assembler refuses such a line with 422 rather than risking charging the adjustments twice, so `null` only ever reaches a reader on a legacy line with no configurable options at all.
            - `regime_key` string, nullable: VeriFactu special regime key (ClaveRegimen, AEAT L8.1) declared for this line, or null when the line inherits the regime from the invoice header.
            - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line inherits the qualification from the invoice header.
            - `aeat_tax_code` string, nullable: AEAT operation qualification code snapshot frozen at issuance. Read-only (derived).
            - `line_type` 'NORMAL' | 'SUPLIDO': Kind of line. `NORMAL` is an ordinary line of the issuer's own operation. `SUPLIDO` is a DISBURSEMENT: an amount the issuer paid in the name and on behalf of the client (an official fee, duty or registry charge) and now re-invoices at cost. Under art. 78.Tres.3 of the Spanish VAT Act (LIVA) a disbursement is not part of the issuer's taxable base, so a `SUPLIDO` line stays out of `subtotal`, `taxes_total` and `total`, is aggregated into `total_disbursements` instead, carries no VAT, withholding, surcharge, discount or product, and is never declared in the AEAT VeriFactu record. Always present and never `null` in a response (a line created before this field existed reads as `NORMAL`); optional on write, where it defaults to `NORMAL`.
            - `source_invoice_reference` string, nullable: Reference of the supporting document that originated the disbursement — the receipt or fee number issued by the public body (≤100 chars). REQUIRED on a `SUPLIDO` line (a disbursement without its supporting reference is rejected with 422) and `null` on a normal line. Free text on purpose: the receipt of a public body is rarely a supplier invoice.
            - `source_invoice_ids` string[], nullable: Optional traceability of a `SUPLIDO` line: IDs (UUID v7) of your own expenses that back the disbursement. `null` when the line carries no traceability — never `[]`, so "no traceability" cannot be confused with "empty list". An expense of another company is rejected with 422.
            - `unit` string, nullable: Unit of measure printed next to the quantity on the document (`hours`, `kg`, `units`, …), ≤20 chars, or `null` when not reported. Presentation only: free text with no closed catalog and no fiscal effect, since no AEAT catalog applies to the ordinary Spanish invoice.
            - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of this line (≤255 chars), printed under the line description to satisfy the mention required by art. 6.1.j of Royal Decree 1619/2012 when the catalogued cause does not cover it. Orthogonal to `exemption_reason` and to the document-level exemption cause: no coherence is enforced between them and the automatic header legal mention is unchanged.
          - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
          - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
          - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
            - `field` string, required: Field key (non-empty, ≤ 60 chars).
            - `value` string, required: Field value (≤ 500 chars).
          - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
          - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
          - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
          - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
          - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
          - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
          - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
          - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
            - `detail` InvoicePaymentDetail[], required: List of individual payments. Empty `[]` in list responses or when there are no payments yet.
              - …
            - `total` string, required: Total amount collected (mirrors `paid_amount`).
            - `pending` string, required: Outstanding balance pending collection (mirrors `pending_amount`).
          - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
          - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
            - `original_id` string, nullable, required: UUID v7 of the original corrected invoice.
            - `original_number` string, nullable, required: Human-readable number of the original corrected invoice.
            - `original_date` string, date, nullable, required: Issue date of the original invoice (YYYY-MM-DD).
            - `correction_reason` string, nullable, required: Reason for the correction (AEAT code R1–R5).
            - `correction_type` string, nullable, required: Scope of the correction: `total` (the whole invoice, `correction_type: full` on input) or `partial`.
            - `correction_nature` string, nullable, required: Effective nature of the correction (art. 15.5 RD 1619/2012), the same one its VeriFactu record declares as `TipoRectificativa`: `I` by differences (the corrective carries the amount of the rectification, any sign) or `S` substitution (the invoice as it ends up). A corrective with a negative base is always `I`.
            - `base_rectificada` string, nullable, required: Taxable base of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.BaseRectificada` on a substitution (`S`).
            - `cuota_rectificada` string, nullable, required: VAT amount of the ORIGINAL invoice being corrected; reported to VeriFactu as `ImporteRectificacion.CuotaRectificada` on a substitution (`S`).
            - `correction_aeat_type` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable, required: AEAT corrective invoice type code (`R1`–`R5`) frozen at issuance from the VeriFactu record. `null` if not resolved.
          - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
            - `method` string, nullable, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
            - `reference` string, nullable, required: Payment reference (e.g. transfer number).
            - `date` string, date, nullable, required: Payment date (YYYY-MM-DD).
          - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
            - `object` 'public_link', required
            - `url` string, uri, required: Absolute URL of the public link to share with the client.
            - `id` string, required: UUID v7 of the document the link points to.
            - `enabled` boolean, required: Indicates whether the public link is currently active.
            - `expires_at` string, date-time, nullable, required: Expiration date/time of the link, or `null` if it does not expire.
            - `max_days` integer, required: Maximum number of days allowed when extending the link validity (business limit).
          - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
            - `id` string, nullable, required: UUID v7 of the substitute full invoice.
            - `number` string, nullable, required: Human-readable number of the replacement full invoice.
          - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
            - `id` string, required: UUID v7 of the parent recurring invoice.
          - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
          - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
          - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
          - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
          - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
          - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
          - `voided_at` string, date-time, nullable, required
          - `void_reason` string, nullable, required
          - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
          - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
          - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
          - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
          - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
          - `created_at` string, date-time, required
          - `updated_at` string, date-time, required
        - `due_date` string, date, nullable, required
        - `days_overdue` integer, required
      - EventDataInvoiceDeleted: Payload (`data`) emitted with the `invoice.deleted` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.deleted', required
        - `object` union, required: Snapshot of the resource at emission time. When the resource is still recoverable the full snapshot is emitted with an additional `deleted: true` key; otherwise it degrades to `{ id, deleted: true }`.
          - Invoice: An invoice (compliant with Spanish AEAT VeriFactu).
            - `id` string, required
            - `object` 'invoice', required
            - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
            - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
            - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
            - `series` SeriesRef, required
              - …
            - `client` ClientRef, required
              - …
            - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
            - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
            - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
            - `issued_on` string, date, required
            - `due_on` string, date, nullable, required
            - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
            - `subtotal` string, required
            - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
            - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
            - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
            - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
            - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
            - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
            - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
            - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
            - `notes` string, nullable, required
            - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
            - `lines` InvoiceLine[], required
              - …
            - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
            - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
            - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
              - …
            - `operation_regime` string, required: AEAT VAT operation regime (`general`, `recargo_equivalencia`, `exenta`, etc.).
            - `exemption_reason` string, nullable, required: VAT exemption cause per document (AEAT catalog E1..E6), or `null` when not exempt. Read-only: the public API derives the AEAT qualification from the regime/cause at issuance.
            - `legal_mentions` string[], required: Header legal mentions (includes the mention derived from the exemption cause). Read-only.
            - `exclude_347` boolean, required: Read-only flag: whether this invoice is excluded from the annual Modelo 347 report. The public API cannot change it; the flag is managed from the Factuarea app.
            - `verifactu_status` string, required: Status of the AEAT VeriFactu submission.
            - `paid_amount` string, required: Amount already collected for this invoice (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
            - `pending_amount` string, required: Outstanding balance pending collection for this invoice (derived from the payment ledger).
            - `payments` object, required: Payment ledger summary, ALWAYS present (never `null`). `total` mirrors `paid_amount`, `pending` mirrors `pending_amount`. `detail` lists the individual payments and is materialized ONLY on the show endpoint (`GET /v1/companies/{company}/invoices/{invoice}`); in list responses `detail` is `[]` (by cost) while `total`/`pending` stay populated. The detail is also available via `GET /v1/companies/{company}/invoices/{invoice}/payments`.
              - …
            - `is_corrective` boolean, required: Whether this invoice is a corrective (rectificativa) of another invoice.
            - `corrective` InvoiceCorrective, required: Correction data of a corrective invoice. Present (object) when `is_corrective=true`, `null` on ordinary invoices.
              - …
            - `payment` InvoicePayment, required: Payment data of the invoice. An object when `status` is `paid`, `null` otherwise.
              - …
            - `public_link` PublicLink, required: Represents the state of the shareable public link of a document (quote/invoice/proforma/delivery_note). `url` is the absolute URL ready to send to the client; `enabled` indicates whether it is active; `expires_at` the deadline (`null` = unlimited); `max_days` the maximum allowed when extending it.
              - …
            - `substituted_by` InvoiceSubstitutedBy, required: Reference to the full invoice (F3) that replaced this simplified invoice (F2). `null` when not applicable.
              - …
            - `recurring` InvoiceRecurring, required: Reference to the recurring invoice (template) that generated this invoice. `null` when the invoice does not come from a recurrence.
              - …
            - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the collection that settled the invoice was RECORDED in the ledger. `null` while the invoice is not collected. Not the declared date: see `paid_date`.
            - `paid_date` string, date, nullable, required: Declared collection date (YYYY-MM-DD). `null` while the invoice is not collected. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
            - `issued_at` string, date-time, nullable, required: When the invoice was issued (ISO 8601), or `null` while it is a draft or scheduled. Not present before API version `2026-10-01`: earlier versions publish this instant in `sent_at`.
            - `sent_at` string, date-time, nullable, required: When the invoice was first delivered to the customer (ISO 8601): the moment the mail server accepted its delivery email, or the date of a manual mark. `null` while it has not been delivered. A resend never moves it. Before API version `2026-10-01` this field carries the ISSUANCE instant instead (that contract called issuing "sending").
            - `sent_via` 'email' | 'manual' | 'null', nullable, required: Channel of the first delivery: `email` (the mail server accepted the delivery email) or `manual` (marked with `POST /v1/companies/{company}/invoices/{invoice}/mark-sent`). `null` while the invoice has not been delivered. Not present before API version `2026-10-01`.
            - `is_sent` boolean, required: Whether the invoice has been delivered to the customer, independently of its fiscal `status`: an issued or overdue invoice can be delivered or not. Derived from the delivery mark (`sent_at` + `sent_via`), never set directly. Not present before API version `2026-10-01`.
            - `voided_at` string, date-time, nullable, required
            - `void_reason` string, nullable, required
            - `scheduled_for` string, date-time, nullable, required: Scheduled emission timestamp (ISO 8601), or `null` when the invoice is not scheduled. Populated only while `status` is `scheduled`.
            - `scheduled_action` 'issue' | 'issue_and_send' | 'draft' | 'null', nullable, required: Action the scheduler runs when `scheduled_for` is reached: `issue` (issue without sending) or `issue_and_send` (issue and email it). `null` when the invoice is not scheduled. Before API version `2026-10-01` the `issue` action is published as `draft`, its previous name.
            - `channel` string, nullable, required: Sales channel the invoice originated from (`woocommerce`, `shopify`, `prestashop`), or `null` when it was not created from a store order — which is the common case.
            - `source_store_id` string, uuid, nullable, required: UUID v7 of the connected store whose order produced this invoice, or `null` when it was not created from a store order. A store order is not a resource of its own on this API, so `channel` and `source_store_id` are the traceability from the order to the invoice.
            - `origin` 'native' | 'historical_import', required: Where the invoice comes from: `native` (issued in Factuarea) or `historical_import` (a historical invoice registered by import: literal number from the file, no series counter and no VeriFactu record).
            - `created_at` string, date-time, required
            - `updated_at` string, date-time, required
          - EventDeletedObject: Degraded snapshot emitted with `*.deleted` events when the resource could no longer be recovered at emission time.
            - `id` string, uuid, required: Opaque identifier (UUID v7) of the deleted resource.
            - `object` string: Resource type of the deleted object (`task`, `task_comment`…), when the event carries it.
            - `deleted` true, required: Always `true`.
      - EventDataInvoiceNumberAssigned: Payload (`data`) emitted with the `invoice.number_assigned` event: the full resource snapshot captured at emission time under `object`, plus event-specific keys.
        - `type` 'invoice.number_assigned', required
        - `object` Invoice, required: An invoice (compliant with Spanish AEAT VeriFactu).
          - `id` string, required
          - `object` 'invoice', required
          - `number` string, nullable, required: Definitive invoice number, or `null` for drafts (where `is_number_assigned` is `false`).
          - `is_number_assigned` boolean, required: Whether the invoice has a definitive number assigned. `false` for drafts (where `number` is `null`); becomes `true` after `POST /v1/companies/{company}/invoices/{invoice}/assign-real-number`, or automatically when the invoice is issued.
          - `type` string, required: Document type: `F1` (ordinary invoice, *ordinaria*), `F2` (simplified invoice, *simplificada*), `F3` (invoice replacing simplified ones, *sustitutiva de simplificadas*) or `R5` (corrective of a simplified invoice). A corrective of an `F1`/`F3` keeps `F1` here; its AEAT corrective code (`R1`–`R5`) is `corrective.correction_aeat_type`, and `is_corrective` tells correctives apart.
          - `series` SeriesRef, required
            - `id` string, nullable, required
            - `code` string, nullable, required
          - `client` ClientRef, required
            - `id` string, nullable, required
            - `name` string, nullable, required
          - `status` 'draft' | 'scheduled' | 'issued' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'annulled' | 'sent', required: Public invoice status. `issued` means the invoice has been ISSUED (definitive number, VeriFactu record); it says nothing about delivery, which lives in `is_sent`/`sent_at`/`sent_via`. `paid` and `partially_paid` are derived from the payment ledger. Before API version `2026-10-01` the issued status is published as `sent` (that contract called issuing "sending"), so `sent` only appears for integrations pinned to an earlier version.
          - `price_list_id` string, nullable, required: UUID of the price list selected for this document.
          - `price_list_name` string, nullable, required: Price-list name snapshot frozen on the document.
          - `issued_on` string, date, required
          - `due_on` string, date, nullable, required
          - `operation_on` string, date, nullable, required: Date the operation took place when it differs from `issued_on` (arts. 6.1.f and 7.1.c of Royal Decree 1619/2012), or `null` when both coincide. It cannot be later than `issued_on` unless the first line that declares a `regime_key` uses 14 or 15 (otherwise 422 `operation_date_after_issue_date`), and it is immutable once the invoice is issued. A corrective invoice inherits the date of the original. It is printed on the PDF and reported in the VeriFactu record (`FechaOperacion`).
          - `subtotal` string, required
          - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge − total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total (4,320.00 + 259.20 − 648.00 = 3,931.20 against a real total of 4,579.20). It is NOT the VAT figure of the Spanish Modelo 303 — read `total_vat` for that. Beware that on an expense the same field name carries a DIFFERENT meaning (VAT only), which is why the identity that holds across all five document families is the explicit one: `total === subtotal + total_vat + total_surcharge − total_retention`.
          - `total_vat` string, required: Output VAT (IVA repercutido) accrued by the document: sum of the VAT of its lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
          - `total_retention` string, required: Withholding (retención de IRPF) applied to the document: sum of the withholding of its lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
          - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the document: sum of the surcharge of its lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
          - `total` string, required: Total of the document. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice and yields a false total (4,320.00 + 259.20 - 648.00 = 3,931.20 against a real 4,579.20).
          - `total_disbursements` string, required: Sum of the `SUPLIDO` (disbursement) lines of this invoice: amounts the issuer paid in the name and on behalf of the client and re-invoices at cost. Deliberately OUTSIDE `subtotal`, `taxes_total` and `total`, because a disbursement is not part of the issuer's taxable base (art. 78.Tres.3 LIVA) and is not declared in the AEAT VeriFactu record. `0` on an invoice without disbursements.
          - `total_to_pay` string, required: Amount the client actually has to pay: `total + total_disbursements`. DERIVED, never stored — one single formula computes it — and equal to `total` on an invoice without disbursements. Worked example: a 1,000.00 service line at 21% plus a 150.00 `SUPLIDO` line yields `subtotal` 1000.00, `taxes_total` 210.00, `total` 1210.00, `total_disbursements` 150.00 and `total_to_pay` 1360.00. Note that `paid_amount`/`pending_amount` are measured against `total`, not against `total_to_pay`.
          - `currency` string, required: ISO 4217 currency code (always "EUR" in v1).
          - `notes` string, nullable, required
          - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
          - `lines` InvoiceLine[], required
            - `object` 'invoice_line', required
            - `description` string, nullable, required
            - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
            - `product` ProductRef, required
              - …
            - `quantity` number, required
            - `unit_price` string, required: Unit price as a decimal STRING with the 4-decimal scale of its column (e.g. `"0.0125"`, `"100.0000"`): it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its price. Derived amounts (`subtotal`, `taxes`, `total`) keep 2 decimals.
            - `tax_rate` number, required
            - `retention_rate` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
            - `discount_percent` number, required
            - `subtotal` string, required
            - `taxes` string, required
- … truncated; see the full OpenAPI document linked below

## Other responses

- `400`: `parameter_unknown` with `subcode` `retired_active_profile_header`: the retired `X-Active-Profile` header was sent; the company goes in the path. `parameter_invalid_format` on `Factuarea-Version`: the header is not a `YYYY-MM-DD` date. `unsupported_api_version`: the `Factuarea-Version` date is not a supported version.
- `401`: Missing or invalid API key.
- `403`: The request is authenticated but not allowed: the API key lacks the required scope (`insufficient_scope`), the plan does not include the public API or this feature (`addon_not_active`, `feature_not_available_in_plan`), or the module is not available with a test key (`module_not_available_in_sandbox`).
- `404`: The requested resource does not exist or belongs to another company.
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.

---

[API](https://skmtc.dev/factuarea/apis/factuarea-public-api.md) · [All operations](https://skmtc.dev/factuarea/apis/factuarea-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/factuarea/apis/factuarea-public-api/revisions/718e77934422?raw)
