---
title: "Generate corrective invoice"
method: POST
path: "/companies/{company}/invoices/{invoice}/corrective"
tags: ["Invoices"]
---

# Generate corrective invoice

`POST /companies/{company}/invoices/{invoice}/corrective`

## Request

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

Issue a corrective invoice amending an issued one; returns 201 with the new invoice.
- Born issued; the original is never modified; AEAT alta is asynchronous.
- 422 `series_invoice_kind_mismatch`.

**Signing certificate (NO VERI*FACTU).** Only in that mode, a missing or invalid company certificate is rejected before the invoice is issued: 422 `verifactu_not_eligible`, `error.subcode: signing_certificate_unavailable`; nothing is consumed, so fix it and repeat the call.

## Path parameters

- `company` string, uuid, required
- `invoice` string, uuid, required

## Headers

- `Idempotency-Key` string, required
- `Factuarea-Version` string, date

## Request body

- CreateCorrectiveInvoiceRequest: Generate a corrective (rectificativa) invoice for a previously issued invoice. `correction_reason` (required) maps to a VeriFactu R-code; `correction_type` is `full` or `partial`; the optional `correction_nature` is `I` (by differences: void the whole invoice with `full` and no `lines`, or correct amounts with `partial` and the adjustment `lines`) or `S` (substitution: `full` with the final `lines`, no negative quantity) — omitted, `full` with `lines` is `S` and the rest `I`; `unit_price` is never negative (a negative `quantity` subtracts); the optional `correction_code` (`R1`..`R5`) forces the explicit R-code and is validated against the AEAT legal matrix for the original invoice type. Optional `justification`, `notes`, and `lines[]` (none to void the whole invoice; required for a partial correction and for a substitution). Each line may also declare the fiscal nature of the line it corrects — `unit`, `regime_key`, `exemption_reason` and `exemption_reason_text` — with the same rules as `POST /v1/companies/{company}/invoices`: a key you OMIT inherits the value of the original line at the same index, a key you SEND (even `null`) replaces it, and `null` means explicitly none.
  - `correction_reason` 'error_fundado' | 'concurso' | 'incobrable' | 'error_importe' | 'error_cliente' | 'devolucion' | 'descuento' | 'otras', required
  - `correction_type` 'full' | 'partial', required
  - `correction_code` 'R1' | 'R2' | 'R3' | 'R4' | 'R5' | 'null', nullable
  - `correction_nature` 'I' | 'S' | 'null', nullable: Nature of the correction (art. 15.5 Royal Decree 1619/2012; VeriFactu `TipoRectificativa`). Optional: OMIT it and `full` with `lines` is a substitution (`S`), while `full` without `lines` and `partial` are by differences (`I`). `I`, by differences: the corrective carries the amount of the rectification, whatever its sign — void the whole invoice with `correction_type: full` and no `lines`, or correct some amounts with `partial` and the adjustment `lines` (`full` with `lines` and an explicit `I` is rejected). `S`, substitution: `correction_type: full` with the FINAL `lines` of the correct invoice (no negative quantity); registered with `ImporteRectificacion` (base and tax of the original). An incoherent combination is rejected with 422 before anything is created.
  - `series_id` string, uuid, nullable
  - `justification` string, nullable
  - `notes` string, nullable
  - `tags` string[], nullable
  - `custom_fields` object[], nullable
    - `field` string, required
    - `value` string, required
  - `lines` object[]
    - `description` string
    - `additional_description` string, nullable
    - `quantity` number
    - `unit_price` number
    - `tax_rate` number, nullable
    - `retention_rate` number, nullable
    - `surcharge_rate` number, nullable
    - `discount_percent` number, nullable
    - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable
    - `product_id` string, uuid, nullable
    - `variant_id` string, uuid, nullable
    - `presentation_id` string, uuid, nullable
    - `confirmed_base_quantity` number, nullable
    - `line_type` 'NORMAL' | 'SUPLIDO' | 'null', nullable: Kind of line: `NORMAL` (default) for an ordinary line, or `SUPLIDO` for a DISBURSEMENT — an amount paid in the name and on behalf of the client (an official fee, duty or registry charge) re-invoiced at cost, which stays out of the taxable base (art. 78.Tres.3 LIVA) and is aggregated into `total_disbursements`. A `SUPLIDO` line must carry no VAT, withholding, surcharge, discount or product, and requires `source_invoice_reference`. Only meaningful when `lines[]` is sent (a partial correction or a substitution); a value outside the catalog is rejected with 422.
    - `source_invoice_reference` string, nullable
    - `unit` string, nullable: Unit of measure printed next to the quantity on the corrected line (`hours`, `kg`, `units`, …), up to 20 characters. Presentation only. OMIT it and the line inherits the unit of the original line at the same index; SEND it (even `null`) and it replaces it, `null` meaning no unit.
    - `regime_key` '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '14' | '15' | '17' | '18' | '19' | '20' | 'null', nullable: VeriFactu special-regime key of the corrected line (the closed AEAT catalog, e.g. `01` general regime, `14` or `15` for operations whose VAT accrues later than the issue date). OMIT it and the line inherits the key of the original line at the same index; SEND it (even `null`) and it replaces it, `null` meaning no special regime.
    - `exemption_reason` 'E1' | 'E2' | 'E3' | 'E4' | 'E5' | 'E6' | 'N1' | 'N2' | 'null', nullable: Cause of VAT exemption of the corrected line (the closed catalog of `POST /v1/companies/{company}/invoices`). OMIT it and the line inherits the exemption of the original line at the same index; SEND it and it replaces it; send `null` for explicitly none — for example, `exemption_reason: null` turns an exempt original line into a taxed one.
    - `exemption_reason_text` string, nullable: Free-text wording of the exemption provision of the corrected line (up to 255 characters), printed under the line description (art. 6.1.j of Royal Decree 1619/2012). OMIT it and the line inherits the text of the original line at the same index; SEND it (even `null`) and it replaces it, `null` meaning no text.
    - `configuration_uuid` string, uuid, nullable
    - `counted_quantity` number, nullable
    - `options` object[], nullable
      - `group_uuid` string, uuid, required
      - `value_uuid` string, uuid, required

## Response `201`

Corrective invoice created successfully. The `Location` header contains the canonical URL of the NEW corrective invoice.

- object
  - `data` 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
        - `id` string, required
        - `name` string, nullable, 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
        - `id` string, required
        - `name` string, nullable, required
      - `presentation` object, nullable, required
        - `id` string, required
        - `name` string, nullable, required
        - `mode` string, 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).
        - `id` string, required
        - `name` string, nullable, required
        - `signature` string, nullable, required
      - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
        - `group` object, required
          - `id` string, required
          - `name` string, nullable, required
        - `value` object, required
          - `id` string, required
          - `name` string, nullable, required
        - `price_adjustment` string, nullable, required: Adjustment of the chosen value per commercial unit. `null` means the value does not change the price — NOT the same as adjusting by `0`.
        - `applied` boolean, required: Whether that amount was actually ADDED to the unit price. `false` when an exact price (price-list entry, combination price or a manually typed unit price) already absorbed it.
      - `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.
        - `id` string, required: Opaque UUID v7 of the payment.
        - `object` 'payment', required: String identifying the object type. Always `payment`.
        - `invoice_id` string, required: UUID v7 of the invoice this payment belongs to.
        - `amount` string, required: Payment amount.
        - `payment_date` string, date, required: Payment date (YYYY-MM-DD).
        - `payment_method` string, required: Payment method (backing value of the Shared enum `PaymentMethod`, e.g. `bank_transfer`).
        - `payment_method_text` string, required: Human-readable label of the payment method (Spanish).
        - `reference` string, nullable, required: Payment reference/operation number. `null` if not provided.
        - `notes` string, nullable, required: Internal notes for the payment. `null` if not provided.
        - `is_reversed` boolean, required: Whether the payment has been reverted. A reverted payment stays in the ledger but stops counting towards `paid_amount`, `pending_amount` and every treasury aggregate — read this flag, do not infer the state from absence.
        - `reversed_at` string, date-time, nullable, required: When the payment was reverted (ISO 8601), or `null` while it is in force.
        - `reversal_reason` 'direct_debit_return' | 'card_dispute' | 'misapplied_payment' | 'bounced_effect' | 'recording_error' | 'issued_in_error' | 'null', nullable, required: Reason the payment was reverted, from the closed catalog. `issued_in_error` appears only on payments reverted by annulling an invoice issued by mistake with `revert_collections`; it cannot be requested for a single payment. `null` while the payment is in force.
        - `reversal_reason_text` string, nullable, required: Human-readable label of the reversal reason (Spanish), or `null`.
        - `reversal_note` string, nullable, required: Free-text remark recorded with the reversal (up to 500 characters), or `null`.
        - `created_at` string, date-time, nullable, required: When the payment was recorded (ISO 8601), or `null`.
        - `updated_at` string, date-time, nullable, required: When the payment was last updated (ISO 8601), or `null`.
      - `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
  - `warnings` string[]

## 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.
- `402`: The operation requires a payment that could not be completed: either no payment method is on file (`error.details.payment_setup_url` links to the Billing Portal where it can be set up), the immediate charge was declined by the payment provider, the account lacks the plan or add-on this operation bills against, the annual document limit is reached (`plan_limit_exceeded`, with `error.details.period_end` indicating the end of the period — wait until it has ended or upgrade the plan to continue now), or the account has reached its maximum usage (`storage_quota_exceeded`, raised by upload operations such as signing a delivery note or attaching a file to an expense — contact support before retrying). Nothing was created or modified — resolve the cause and retry the same request. Version note: `error.type` is `payment_required_error` from `Factuarea-Version: 2026-09-01` onwards; earlier versions receive `invalid_request_error` for the three codes that predate that cut (`payment_method_required`, `employee_seat_payment_method_required` and `employee_seat_charge_failed`; every other 402 code, such as `addon_required`, `plan_limit_exceeded` or the additional tax ID codes, is newer and always carries `payment_required_error`). `error.code` is stable across every version.
- `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.
- `409`: The request conflicts with data that already exists or with a request running at the same time. `resource_conflict`: another request was reserving identifiers for the same kind of record at that moment and this one could not complete its reservation. Nothing was written; send the request again after a few seconds.
- `422`: Validation failed, or the invoice cannot undergo the requested state transition (e.g. marking an already-paid invoice as paid, or editing an issued invoice — use a corrective instead). The `error.param` field identifies which input is invalid, if any. Issuing or annulling an invoice can also be rejected with `verifactu_not_eligible`: either a field of the invoice does not fit its billing record, or — only when the company has VeriFactu enabled in NO VERI*FACTU mode — it has no usable signing certificate (`error.subcode: signing_certificate_unavailable`; `error.param` is `certificate`, `representation` or `system_certificate`, depending on what is missing); in both cases the invoice stays exactly as it was.
- `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)
