> ## Documentation Index
> Fetch the complete documentation index at: https://www.finseed.es/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an invoice

> Issue Verifactu invoices programmatically: payload anatomy, idempotency, and ready-to-run examples for every common tax situation.

<Warning>
  **Alpha endpoint**

  This endpoint is in alpha. Request and response shapes, error codes, and behavior may still change without notice. Avoid relying on it for production traffic until it is announced as stable.
</Warning>

Creating an invoice issues it immediately: the number is assigned from a series, the Verifactu record is chained and hashed, and the issue date is stamped server-side. Registration at the tax agency then progresses asynchronously: poll `GET /v1/invoices/{id}` until `verifactu.status` leaves `pending`. The response is the full invoice object, including `pdf_url` and the Verifactu artifacts.

Three things follow from invoices being legal documents:

* **They cannot be backdated or edited.** There is no `invoice_date` field and no update endpoint. A wrong invoice is corrected with a rectificativa, never by mutation. To record that the operation happened before the issue date, use [`operation_date`](#operation-date).
* **Always send an `Idempotency-Key`.** A network timeout without one can issue a duplicate that you can only undo with a corrective invoice. With the header, retrying the exact same request replays the original response instead of issuing twice. See [Idempotency](/docs/api-reference/idempotency).
* **Totals are computed server-side** from `quantity`, `unit_amount` (net cents) and the tax `rate`, with the same rounding the Finseed dashboard uses. Dry-run any payload with `POST /v1/invoices/validate` to see the exact totals before issuing.

## Complete or simplified

Send `type: "complete"` when the recipient is identified: the full `recipient` block is required and the tax id is validated against the census (AEAT for Spanish NIFs, VIES for EU VAT numbers) before anything is persisted. Send `type: "simplified"` for tickets without an identified recipient. It is capped at 3,000 EUR including tax, and its optional `recipient` block deliberately has no `tax_id` field.

On a complete recipient, `tax_id_type` and `tax_id_country` may both be omitted: they are auto-detected from the `tax_id` format and the address country. When you do send `tax_id_type`, the country may still be omitted if the type implies it (`es_nif` and `not_registered` imply `ES`; `eu_vat` derives it from the VAT prefix), while `passport`, `official_document`, `residence_certificate` and `other` require an explicit `tax_id_country`. A pair that contradicts itself, such as `es_nif` with a non-`ES` country, is rejected with [`tax_id_type_country_mismatch`](/docs/api-reference/errors#tax_id_type_country_mismatch).

## Operation date

The issue date is always stamped server-side, but the operation itself may have happened earlier: an invoice issued in July for goods delivered in June. Send the optional `operation_date` (`YYYY-MM-DD`, a calendar day in the Europe/Madrid timezone) to record it. It must be between 2025-01-01 and today. When omitted it equals the issue date, and it is reported to the tax agency only when the two differ. It is not available on rectificativas.

```json theme={null}
{
  "type": "complete",
  "operation_date": "2025-06-15",
  "recipient": {
    "name": "ACME, S.L.",
    "tax_id": "B12345678",
    "address": {
      "line1": "Calle Mayor 1",
      "postal_code": "28001",
      "city": "Madrid",
      "country": "ES"
    }
  },
  "line_items": [
    {
      "description": "Entrega de mercancía de junio",
      "quantity": 1,
      "unit_amount": 25000,
      "tax": { "type": "vat", "rate": 21 }
    }
  ]
}
```

## Examples

Standard domestic sale at 21% VAT:

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "ACME, S.L.",
    "tax_id": "B12345678",
    "email": "facturas@acme.example",
    "address": {
      "line1": "Calle Mayor 1",
      "postal_code": "28001",
      "city": "Madrid",
      "country": "ES"
    }
  },
  "line_items": [
    {
      "description": "Consultoría técnica",
      "quantity": 2,
      "unit_amount": 4150,
      "tax": { "type": "vat", "rate": 21 }
    }
  ]
}
```

Simplified ticket (no recipient):

```json theme={null}
{
  "type": "simplified",
  "line_items": [
    {
      "description": "Menú del día",
      "quantity": 1,
      "unit_amount": 1364,
      "tax": { "type": "vat", "rate": 10 }
    }
  ]
}
```

Exempt operation (for example training):

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "ACME, S.L.",
    "tax_id": "B12345678",
    "address": {
      "line1": "Calle Mayor 1",
      "postal_code": "28001",
      "city": "Madrid",
      "country": "ES"
    }
  },
  "line_items": [
    {
      "description": "Curso de formación",
      "quantity": 1,
      "unit_amount": 50000,
      "tax": { "type": "es_exempt" }
    }
  ]
}
```

Reverse charge (inversión del sujeto pasivo; requires a complete invoice):

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "Constructora Ejemplo, S.A.",
    "tax_id": "A87654321",
    "address": {
      "line1": "Avenida de la Obra 10",
      "postal_code": "08001",
      "city": "Barcelona",
      "country": "ES"
    }
  },
  "line_items": [
    {
      "description": "Ejecución de obra",
      "quantity": 1,
      "unit_amount": 250000,
      "tax": { "type": "es_inversion_sujeto_pasivo" }
    }
  ]
}
```

Intra-EU B2B service to a VIES-registered business:

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "Beispiel GmbH",
    "tax_id": "DE123456789",
    "address": {
      "line1": "Beispielstrasse 1",
      "postal_code": "10115",
      "city": "Berlin",
      "country": "DE"
    }
  },
  "line_items": [
    {
      "description": "Software development services",
      "quantity": 1,
      "unit_amount": 120000,
      "tax": { "type": "eu_b2b_services" }
    }
  ]
}
```

OSS sale to an EU consumer (destination-country VAT):

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "Jean Dupont",
    "tax_id": "FR12345678901",
    "address": {
      "line1": "1 Rue de l'Exemple",
      "postal_code": "75001",
      "city": "Paris",
      "country": "FR"
    }
  },
  "line_items": [
    {
      "description": "Online subscription",
      "quantity": 1,
      "unit_amount": 2000,
      "tax": { "type": "eu_oss", "rate": 20 }
    }
  ]
}
```

Canary Islands sale (IGIC):

```json theme={null}
{
  "type": "simplified",
  "line_items": [
    {
      "description": "Artículo local",
      "quantity": 3,
      "unit_amount": 1500,
      "tax": { "type": "igic", "rate": 7 }
    }
  ]
}
```

Recargo de equivalencia (the surcharge pairs are computed server-side):

```json theme={null}
{
  "type": "complete",
  "recipient": {
    "name": "Comercio Minorista, S.L.",
    "tax_id": "B11223344",
    "address": {
      "line1": "Plaza del Comercio 5",
      "postal_code": "46001",
      "city": "Valencia",
      "country": "ES"
    }
  },
  "recargo_equivalencia": true,
  "line_items": [
    {
      "description": "Mercancía para reventa",
      "quantity": 10,
      "unit_amount": 2000,
      "tax": { "type": "vat", "rate": 21 }
    }
  ]
}
```

Discount line (negative net amount):

```json theme={null}
{
  "type": "simplified",
  "line_items": [
    {
      "description": "Entrada general",
      "quantity": 4,
      "unit_amount": 2500,
      "tax": { "type": "vat", "rate": 21 }
    },
    {
      "description": "Descuento promoción",
      "quantity": 1,
      "unit_amount": -1000,
      "tax": { "type": "vat", "rate": 21 }
    }
  ]
}
```

## After the 201

The invoice exists and is legally issued the moment you receive the response. Two things are still settling in the background:

* **AEAT registration**: `verifactu.status` starts at `pending` (test environments answer `registered` immediately and never contact AEAT). Poll the invoice until it becomes `registered`, or handle `registered_with_errors` / `rejected` using `verifactu.error`.
* **The PDF**: `pdf_url` is valid immediately; if the PDF has not been rendered yet, the first download simply takes a moment longer.


## OpenAPI

````yaml POST /v1/invoices
openapi: 3.1.0
info:
  title: Finseed API
  version: 1.0.0
  description: >-
    REST API for programmatic Verifactu invoicing. Every request is sent over
    HTTPS and authenticated with an API key passed as a bearer token. Each key
    is scoped to a single environment (test or live). Payloads are JSON with
    snake_case fields: amounts are integer minor units (cents) and timestamps
    are RFC 3339 in UTC. List endpoints are cursor-paginated. Errors return a
    small application/json envelope with a stable, machine-readable `code`.
servers:
  - url: https://api.finseed.es
security:
  - bearerAuth: []
paths:
  /v1/invoices:
    post:
      tags:
        - Invoices
      summary: Create an invoice
      description: >-
        Issues an invoice immediately: the number is assigned from the series,
        the Verifactu record is chained and the issue date is stamped
        server-side (invoices cannot be backdated; use `operation_date` to
        record when the operation itself took place). Registration at the tax
        agency then progresses asynchronously: poll the invoice until
        `verifactu.status` leaves `pending`. Complete invoices validate the
        recipient tax id against the census (AEAT/VIES) before anything is
        persisted, so creation can take a few seconds. Send an `Idempotency-Key`
        so retries can never issue a duplicate.
      operationId: createInvoice
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Optional key that makes the request safe to retry: 1 to 255
            printable ASCII characters. Sending the same key with the same body
            within 24 hours returns the stored response instead of executing
            again; such a replay carries an `Idempotent-Replayed: true` header.
            Reusing a key with a different body is rejected.
          schema:
            type: string
      requestBody:
        description: The invoice to issue.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceCreateRequest'
      responses:
        '201':
          description: The issued invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
          headers:
            Idempotent-Replayed:
              description: >-
                Present with value `true` only when this response is a stored
                replay of an earlier request that used the same
                `Idempotency-Key`.
              schema:
                type: string
        '400':
          description: >-
            The request was rejected during validation. The `errors` array lists
            each failing field with a reason, so you can map the failure back to
            a specific parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: invalid_request
                detail: >-
                  The request is not valid. A parameter is missing, malformed,
                  or out of range. See the `errors` array for the fields that
                  failed.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#invalid_request
        '401':
          description: >-
            Authentication failed: the API key is missing, malformed, or
            revoked. Send a valid key as a bearer token in the `Authorization`
            header. Each key is bound to a single environment (test or live).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: unauthorized
                detail: >-
                  Authentication failed. Send your API key as a bearer token in
                  the `Authorization` header. Keys are scoped to one
                  environment, so a test key cannot read live data and vice
                  versa.
                errors: []
                doc_url: https://www.finseed.es/docs/api-reference/errors#unauthorized
        '402':
          description: >-
            Live invoice issuance requires an active subscription. When the
            account has no active plan, live keys receive this error until a
            subscription is in place. Test-environment keys are unaffected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: no_active_subscription
                detail: >-
                  This account cannot create invoices without an active
                  subscription. Check your plan to continue issuing invoices.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#no_active_subscription
        '403':
          description: >-
            Live invoice issuance requires the company's AEAT representation
            mandate to be approved, which happens during onboarding. Until then,
            live keys receive this error; test-environment keys can issue freely
            (test invoices are never sent to AEAT).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: aeat_mandate_not_approved
                detail: >-
                  This account cannot issue live invoices yet: the AEAT
                  representation mandate is pending approval. Complete the
                  onboarding in the dashboard, or use a test-environment key
                  meanwhile.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#aeat_mandate_not_approved
        '409':
          description: >-
            The supplied `Idempotency-Key` cannot be honored. This happens in
            three situations: the key was already used with a different request
            body; the original request with this key is still being processed,
            in which case retrying with the same key and body once it completes
            replays its response; or the original request ended in an unknown
            state, in which case the key stays blocked for up to 24 hours. If
            you never received a stored response, send the request again with a
            fresh key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: idempotency_conflict
                detail: >-
                  This `Idempotency-Key` cannot be honored: it was already used
                  with a different request body, the original request is still
                  being processed, or that request ended in an unknown state. If
                  the original is still running, retry with the same key and
                  body once it completes to replay its response. If you never
                  received a stored response, the key stays blocked for up to 24
                  hours; send the request again with a fresh key.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#idempotency_conflict
        '422':
          description: >-
            Returned as `external_reference_invalid`: The external original
            reference is malformed: the `number` exceeds 60 characters or
            contains forbidden characters (`"`, `'`, `<`, `>`, `=`), or
            `issued_on` is not a valid calendar date.


            Returned as `external_reference_matches_existing_invoice`: The
            external number matches an invoice that was actually issued through
            Finseed. Rectify it as a local invoice with `rectifies.invoice_id`;
            `rectifies.external` is only for originals that never existed in
            Finseed.


            Returned as `family_balance_below_zero`: A rectificativa por
            diferencias adjusts the original by a delta. This delta would make
            the accumulated total of the correction chain negative, which is not
            a valid invoice. Reduce the delta.


            Returned as `insufficient_recipient_data`: The recipient block does
            not meet the legal minimums for a complete invoice (for example a
            too-short name or tax id, or an unrecognized country code). Fix the
            flagged recipient fields or issue a simplified invoice when no
            identified recipient exists.


            Returned as `invalid_number_series`: The `number_series_id` in the
            request body cannot be used to issue this invoice: it is malformed,
            belongs to another environment, or names a rectifying series
            (reserved for corrective invoices). List the usable series with the
            Number Series endpoints.


            Returned as `invalid_recargo_equivalencia`: The
            `recargo_equivalencia` flag requires every line to carry exactly one
            `vat` tax whose rate has a legal surcharge pairing (21%→5.2%,
            10%→1.4%, 4%→0.5%). Lines with other tax types or unpaired VAT rates
            cannot be invoiced under this regime.


            Returned as `invalid_rectifies_reference`: The `rectifies` block did
            not name exactly one original to correct. Supply either `invoice_id`
            for an invoice issued through Finseed, or `external` for one issued
            elsewhere — not both, and not neither.


            Returned as `invalid_tax_data`: The combination of tax types, rates
            and computed amounts is one the tax agency rejects (for example a
            positive rate that yields a zero tax amount on a non-zero line).
            Review the tax on each line.


            Returned as `invalid_tax_id`: The recipient tax id failed
            just-in-time validation. Either the format is invalid for its type,
            or the census lookup (AEAT for Spanish NIFs, VIES for EU VAT
            numbers) did not recognize the id together with the supplied name.
            Verify the id and use the exact name the recipient is registered
            under.


            Returned as `invalid_tax_rate`: A line item carries a tax rate the
            tax agency (AEAT) would reject for that tax type on the current
            date, a rate on a rate-free type, or a missing rate on a rated type.
            Spanish VAT (`vat`) currently accepts 0, 4, 10 and 21 percent for
            invoices issued today; historical temporary rates (2, 5, 7.5) only
            applied to past operation windows.


            Returned as `invoice_already_replaced`: The referenced invoice has
            already been fully replaced by a rectificativa por sustitución. Only
            the active head of the correction chain can be rectified; rectify
            the replacement instead.


            Returned as `invoice_already_voided`: The referenced invoice was
            voided (anulada). A voided invoice is legally cancelled, so it
            cannot be corrected with a rectificativa.


            Returned as `invoice_not_family_tip`: The referenced invoice is not
            the active head of its correction chain: a later rectificativa
            already corrects it. Rectify the current head of the chain instead.


            Returned as `invoice_not_rectifiable_at_aeat`: The referenced
            invoice is not in a state the tax agency (AEAT) allows a
            rectificativa against: its registration failed, was skipped, or
            never happened. Only invoices that registered successfully can be
            rectified.


            Returned as `invoice_pending_at_aeat`: The referenced invoice has
            not finished registering at the tax agency (AEAT). Poll it until
            `verifactu.status` leaves `pending`, then rectify it.


            Returned as `line_item_without_tax_items`: A rectificativa line item
            was submitted without a tax. Every line must declare its tax so the
            corrective document reconciles with the tax agency.


            Returned as `reason_incompatible_with_recipient`: The chosen
            `reason` restricts which recipient tax id types are allowed.
            `insolvency` accepts a Spanish NIF, an EU VAT number, or an
            unregistered recipient; `uncollectible` accepts a Spanish NIF or an
            unregistered recipient. The recipient on this invoice does not meet
            that restriction.


            Returned as `recipient_overrides_not_allowed_for_differences`: A
            rectificativa por diferencias inherits its recipient from the
            corrected invoice, so a `recipient` block cannot be supplied. Omit
            it, or issue a rectificativa por sustitución (`method:
            "substitution"`) when the recipient must change.


            Returned as `rectified_amounts_required_for_substitution`: When
            replacing an external original by substitution, the tax agency
            requires the original amounts (`ImporteRectificación`), which
            Finseed cannot compute because the original never existed here.
            Supply `rectifies.external.rectified_amounts`.


            Returned as `rectified_invoice_not_found`: The
            `rectifies.invoice_id` does not match any invoice in the environment
            the API key belongs to. Use the opaque `inv_` identifier of an
            invoice issued through Finseed; to correct an invoice issued
            elsewhere, use `rectifies.external` instead.


            Returned as `rectifying_series_invalid`: A rectificativa must be
            issued on a rectifying series. The `number_series_id` is malformed,
            belongs to another environment, or names a standard series. List
            your rectifying series with the Number Series endpoints, or omit it
            to use the environment default.


            Returned as `replacement_total_negative`: A rectificativa por
            sustitución restates the full invoice, so its net total cannot be
            negative. Adjust the line items so the total is at or above zero.


            Returned as `simplified_amount_exceeded`: Spanish law caps
            simplified invoices at 3,000 EUR including tax. Above that amount
            the recipient must be identified: send `type: "complete"` with a
            full recipient block.


            Returned as `simplified_incompatible_tax_type`: The invoice combines
            `type: "simplified"` with a tax type that legally requires an
            identified recipient, such as `es_inversion_sujeto_pasivo` (reverse
            charge). Issue a complete invoice for these operations.


            Returned as `tax_id_type_country_mismatch`: The supplied
            `tax_id_type` and `tax_id_country` contradict each other. Each type
            constrains the country: `es_nif` and `not_registered` require `ES`;
            `eu_vat` requires an EU country other than `ES`;
            `official_document`, `residence_certificate` and `other` require a
            country other than `ES`; `passport` accepts any country. Fix the
            pair, or omit `tax_id_country` when the type implies it (or omit
            both to auto-detect them from the tax id).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                external_reference_invalid:
                  summary: external_reference_invalid
                  value:
                    code: external_reference_invalid
                    detail: >-
                      The `rectifies.external` reference is invalid: the number
                      is too long or contains forbidden characters, or the issue
                      date is not a real date.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#external_reference_invalid
                external_reference_matches_existing_invoice:
                  summary: external_reference_matches_existing_invoice
                  value:
                    code: external_reference_matches_existing_invoice
                    detail: >-
                      The `rectifies.external.number` matches an invoice issued
                      through Finseed in this environment. Reference it with
                      `invoice_id` instead of `external`.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#external_reference_matches_existing_invoice
                family_balance_below_zero:
                  summary: family_balance_below_zero
                  value:
                    code: family_balance_below_zero
                    detail: >-
                      This rectificativa por diferencias would drive the
                      corrected invoice below zero across its whole correction
                      chain. Reduce the delta so the accumulated total stays at
                      or above zero.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#family_balance_below_zero
                insufficient_recipient_data:
                  summary: insufficient_recipient_data
                  value:
                    code: insufficient_recipient_data
                    detail: >-
                      The recipient data is not sufficient for a complete
                      invoice: a required field is missing or too short (name
                      and tax id have legal minimum lengths, and the country
                      must be a valid ISO code).
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#insufficient_recipient_data
                invalid_number_series:
                  summary: invalid_number_series
                  value:
                    code: invalid_number_series
                    detail: >-
                      The number_series_id does not name a usable series: it is
                      malformed, does not exist in this environment, or is a
                      rectifying series. Invoices are issued on standard series;
                      list yours with GET /v1/number_series.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_number_series
                invalid_recargo_equivalencia:
                  summary: invalid_recargo_equivalencia
                  value:
                    code: invalid_recargo_equivalencia
                    detail: >-
                      recargo_equivalencia could not be applied: every line must
                      carry exactly one VAT tax with a rate that has a legal
                      surcharge pairing (21, 10 or 4 percent).
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_recargo_equivalencia
                invalid_rectifies_reference:
                  summary: invalid_rectifies_reference
                  value:
                    code: invalid_rectifies_reference
                    detail: >-
                      The `rectifies` block must reference exactly one original:
                      either `invoice_id` (an invoice issued through Finseed) or
                      `external` (an invoice issued elsewhere), never both and
                      never neither.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_rectifies_reference
                invalid_tax_data:
                  summary: invalid_tax_data
                  value:
                    code: invalid_tax_data
                    detail: >-
                      The tax data on the invoice is inconsistent and the tax
                      agency would reject it. Review each line: the rate, the
                      amounts and the tax type must agree.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_tax_data
                invalid_tax_id:
                  summary: invalid_tax_id
                  value:
                    code: invalid_tax_id
                    detail: >-
                      The recipient tax id failed validation: its format is
                      invalid, or the id and name do not match the tax census
                      (AEAT for Spanish NIF, VIES for EU VAT numbers). Check the
                      id and the exact registered name.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_tax_id
                invalid_tax_rate:
                  summary: invalid_tax_rate
                  value:
                    code: invalid_tax_rate
                    detail: >-
                      A line carries a tax rate the tax agency does not accept
                      for that tax type on the current date. Spanish VAT (`vat`)
                      currently accepts 0, 4, 10 and 21. Rated types require a
                      rate; rate-free types must omit it.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invalid_tax_rate
                invoice_already_replaced:
                  summary: invoice_already_replaced
                  value:
                    code: invoice_already_replaced
                    detail: >-
                      The invoice referenced by `rectifies.invoice_id` has
                      already been replaced by a substitution rectificativa.
                      Rectify the replacement instead.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invoice_already_replaced
                invoice_already_voided:
                  summary: invoice_already_voided
                  value:
                    code: invoice_already_voided
                    detail: >-
                      The invoice referenced by `rectifies.invoice_id` was
                      voided (anulada) and cannot be rectified.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invoice_already_voided
                invoice_not_family_tip:
                  summary: invoice_not_family_tip
                  value:
                    code: invoice_not_family_tip
                    detail: >-
                      The invoice referenced by `rectifies.invoice_id` is not
                      the active head of its correction chain. A later
                      rectificativa already supersedes it; rectify that one
                      instead.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invoice_not_family_tip
                invoice_not_rectifiable_at_aeat:
                  summary: invoice_not_rectifiable_at_aeat
                  value:
                    code: invoice_not_rectifiable_at_aeat
                    detail: >-
                      The invoice referenced by `rectifies.invoice_id` cannot be
                      rectified given its tax-agency registration state: it was
                      rejected, skipped, or was never registered.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invoice_not_rectifiable_at_aeat
                invoice_pending_at_aeat:
                  summary: invoice_pending_at_aeat
                  value:
                    code: invoice_pending_at_aeat
                    detail: >-
                      The invoice referenced by `rectifies.invoice_id` is still
                      pending registration at the tax agency. Wait until its
                      `verifactu.status` leaves `pending` before rectifying it.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#invoice_pending_at_aeat
                line_item_without_tax_items:
                  summary: line_item_without_tax_items
                  value:
                    code: line_item_without_tax_items
                    detail: >-
                      Every line item on a rectificativa must carry a tax. A
                      line was submitted without one.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#line_item_without_tax_items
                reason_incompatible_with_recipient:
                  summary: reason_incompatible_with_recipient
                  value:
                    code: reason_incompatible_with_recipient
                    detail: >-
                      The rectification `reason` is incompatible with the
                      recipient identification. Insolvency (concurso) and
                      uncollectible (incobrable) corrections restrict the
                      accepted recipient tax id types.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#reason_incompatible_with_recipient
                recipient_overrides_not_allowed_for_differences:
                  summary: recipient_overrides_not_allowed_for_differences
                  value:
                    code: recipient_overrides_not_allowed_for_differences
                    detail: >-
                      A `recipient` block is not allowed on a rectificativa por
                      diferencias: the recipient is inherited from the corrected
                      invoice. Omit it, or use `method: "substitution"` to
                      restate the recipient.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#recipient_overrides_not_allowed_for_differences
                rectified_amounts_required_for_substitution:
                  summary: rectified_amounts_required_for_substitution
                  value:
                    code: rectified_amounts_required_for_substitution
                    detail: >-
                      A rectificativa por sustitución against an external
                      original requires `rectified_amounts` (the base, tax and
                      optional surcharge of the original), which the tax agency
                      needs and cannot be inferred.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#rectified_amounts_required_for_substitution
                rectified_invoice_not_found:
                  summary: rectified_invoice_not_found
                  value:
                    code: rectified_invoice_not_found
                    detail: >-
                      No invoice matches the `rectifies.invoice_id` in this
                      environment. Note that test and live keys see different
                      invoices, and the id must be an `inv_`-prefixed Finseed
                      identifier.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#rectified_invoice_not_found
                rectifying_series_invalid:
                  summary: rectifying_series_invalid
                  value:
                    code: rectifying_series_invalid
                    detail: >-
                      The `number_series_id` does not name a usable rectifying
                      series: it is malformed, does not exist in this
                      environment, or is a standard series. Rectificativas are
                      issued on rectifying series.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#rectifying_series_invalid
                replacement_total_negative:
                  summary: replacement_total_negative
                  value:
                    code: replacement_total_negative
                    detail: >-
                      This rectificativa por sustitución has a negative net
                      total. A replacement invoice restates the full amount,
                      which cannot be below zero.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#replacement_total_negative
                simplified_amount_exceeded:
                  summary: simplified_amount_exceeded
                  value:
                    code: simplified_amount_exceeded
                    detail: >-
                      Simplified invoices cannot exceed 3,000 EUR including tax.
                      Issue a complete invoice with an identified recipient
                      instead.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#simplified_amount_exceeded
                simplified_incompatible_tax_type:
                  summary: simplified_incompatible_tax_type
                  value:
                    code: simplified_incompatible_tax_type
                    detail: >-
                      A tax type on this invoice is incompatible with a
                      simplified invoice (reverse charge requires an identified
                      recipient). Issue a complete invoice instead.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#simplified_incompatible_tax_type
                tax_id_type_country_mismatch:
                  summary: tax_id_type_country_mismatch
                  value:
                    code: tax_id_type_country_mismatch
                    detail: >-
                      The tax_id_type is incompatible with the tax_id_country.
                      es_nif and not_registered require ES, eu_vat requires an
                      EU country other than ES, and official_document,
                      residence_certificate and other require a country other
                      than ES.
                    errors: []
                    doc_url: >-
                      https://www.finseed.es/docs/api-reference/errors#tax_id_type_country_mismatch
        '500':
          description: >-
            An unexpected error occurred on our side. No partial work is
            persisted, so the request can be retried safely.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: internal_error
                detail: >-
                  Something went wrong on our side. The request did not complete
                  and can be retried safely.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#internal_error
        '503':
          description: >-
            Complete invoices validate the recipient tax id against the census
            (AEAT or VIES) at creation time. When that external service is down,
            creation fails with this code and nothing is persisted. Retry later;
            sending the same `Idempotency-Key` makes the retry safe.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: tax_id_validation_unavailable
                detail: >-
                  The tax census service (AEAT/VIES) is temporarily unavailable,
                  so the recipient tax id could not be verified and the invoice
                  was not created. Retry in a few minutes; with the same
                  Idempotency-Key the retry is safe.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#tax_id_validation_unavailable
components:
  schemas:
    InvoiceCreateRequest:
      oneOf:
        - type: object
          properties:
            number_series_id:
              description: >-
                Number series to issue on (see the Number Series resource).
                Defaults to the environment default series. For an ordinary
                invoice this must be a standard series; for a rectificativa (a
                `rectifies` block) it must be a rectifying series.
              example: ns_clx456def789
              type: string
            rectifies:
              type: object
              properties:
                method:
                  type: string
                  enum:
                    - differences
                    - substitution
                  description: >-
                    How to correct the original. `differences` books only the
                    delta; `substitution` replaces the original in full.
                  example: differences
                reason:
                  description: >-
                    Why the original is being corrected (drives the AEAT R1-R4
                    code). Defaults to `correction` (R1). Use `insolvency` (R2)
                    for concurso, `uncollectible` (R3) for créditos incobrables,
                    `other` (R4) otherwise. Simplified invoices always register
                    as R5.
                  example: correction
                  type: string
                  enum:
                    - correction
                    - insolvency
                    - uncollectible
                    - other
                invoice_id:
                  description: >-
                    Opaque id of the invoice to correct, when it was issued
                    through Finseed. Mutually exclusive with `external`.
                  example: inv_clx123abc456
                  type: string
                external:
                  type: object
                  properties:
                    number:
                      type: string
                      minLength: 1
                      maxLength: 60
                      description: >-
                        Invoice number of the external original, exactly as it
                        was issued.
                      example: F-2025-091
                    issued_on:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}$
                      description: >-
                        Issue date of the external original as a plain calendar
                        date (YYYY-MM-DD).
                      example: '2025-03-14'
                    rectified_amounts:
                      type: object
                      properties:
                        base:
                          type: integer
                          description: >-
                            Taxable base of the external original, in minor
                            units (cents).
                          example: 100000
                        tax:
                          type: integer
                          description: >-
                            Tax amount of the external original, in minor units
                            (cents).
                          example: 21000
                        surcharge:
                          description: >-
                            Recargo de equivalencia surcharge of the external
                            original, in minor units (cents). Omit when it does
                            not apply.
                          example: 0
                          type: integer
                      required:
                        - base
                        - tax
                      additionalProperties: false
                      description: >-
                        The original amounts the tax agency needs to register a
                        substitution against an external original (its
                        `ImporteRectificación`). Required when `method` is
                        `substitution`.
                  required:
                    - number
                    - issued_on
                  additionalProperties: false
                  description: >-
                    The original this rectificativa corrects when it was NOT
                    issued through Finseed (a pre-Finseed invoice a migrated
                    merchant rectifies).
              required:
                - method
              additionalProperties: false
              description: >-
                Turns this request into a rectificativa (corrective invoice).
                Reference the original with exactly one of `invoice_id` (issued
                through Finseed) or `external` (issued elsewhere). Omit the
                whole block to issue an ordinary invoice.
            operation_date:
              description: >-
                Date the underlying operation took place, as a calendar day
                (`YYYY-MM-DD`) interpreted in the Europe/Madrid timezone. Must
                be an existing calendar day between 2025-01-01 and today. When
                omitted, or when it equals the issue date, the invoice carries
                the issue date as its operation date. Not supported together
                with a `rectifies` block.
              example: '2025-06-15'
              type: string
              pattern: ^(\d{4})-(\d{2})-(\d{2})$
            line_items:
              minItems: 1
              maxItems: 500
              type: array
              items:
                type: object
                properties:
                  description:
                    type: string
                    minLength: 1
                    maxLength: 500
                    description: Description of the goods or service.
                    example: Consulting services
                  quantity:
                    type: integer
                    minimum: 1
                    description: Number of units billed on this line.
                    example: 2
                  unit_amount:
                    type: integer
                    description: >-
                      Net price of a single unit before tax, in minor units
                      (cents). Negative values create discount lines. Line and
                      invoice totals are computed server-side from quantity,
                      unit_amount and the tax rate.
                    example: 4150
                  tax:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - vat
                          - igic
                          - ipsi
                          - es_exempt
                          - es_inversion_sujeto_pasivo
                          - es_non_taxable
                          - es_non_taxable_localization
                          - eu_oss
                          - eu_b2b
                          - eu_b2b_services
                          - export
                        description: >-
                          Tax category for this line. `vat`, `igic`, `ipsi` and
                          `eu_oss` require a `rate`; the remaining types are
                          rate-free (exemptions, reverse charge, non-taxable,
                          intra-EU, export).
                        example: vat
                      rate:
                        description: >-
                          Tax rate as a percentage with up to two decimals (21
                          means 21%); more precision is rejected, never rounded.
                          Required for `vat`, `igic`, `ipsi` and `eu_oss`; omit
                          it for rate-free types.
                        example: 21
                        type: number
                        minimum: 0
                        maximum: 100
                    required:
                      - type
                    additionalProperties: false
                    description: The tax applied to a line.
                required:
                  - description
                  - quantity
                  - unit_amount
                  - tax
                additionalProperties: false
                description: A line to bill.
              description: The lines to bill. At least one.
            recargo_equivalencia:
              description: >-
                Applies the Spanish recargo de equivalencia regime: every VAT
                line gains its legally paired surcharge (21%→5.2%, 10%→1.4%,
                4%→0.5%), computed server-side.
              example: false
              type: boolean
            footer_notes:
              description: Free-form text printed at the bottom of the invoice PDF.
              example: Pago a 30 días.
              type: string
              maxLength: 2000
            type:
              type: string
              const: complete
              description: >-
                A complete invoice: the recipient is identified and their tax id
                is validated against the census. On a linked rectificativa (a
                `rectifies.invoice_id`) the recipient is inherited from the
                corrected invoice and may be omitted; when supplied on a
                substitution it restates the recipient.
            recipient:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: >-
                    Name of the recipient, person or business. Validated against
                    the tax census (AEAT/VIES) together with tax_id.
                  example: ACME, S.L.
                company_name:
                  description: >-
                    Company name when it differs from `name` (e.g. a personal
                    name plus a trade name). Usually omitted.
                  example: ACME Corporación, S.L.
                  type: string
                  maxLength: 200
                tax_id:
                  type: string
                  minLength: 3
                  maxLength: 50
                  description: >-
                    Tax identifier of the recipient (e.g. Spanish NIF/CIF or EU
                    VAT number). Validated just-in-time against AEAT or VIES.
                  example: B12345678
                tax_id_type:
                  description: >-
                    Kind of tax identifier. Omit it together with tax_id_country
                    to auto-detect both from the tax_id format and country. When
                    provided, tax_id_country may be omitted if the type implies
                    it: es_nif and not_registered imply ES, and eu_vat derives
                    it from the VAT prefix. The other types require an explicit
                    tax_id_country.
                  example: es_nif
                  type: string
                  enum:
                    - es_nif
                    - eu_vat
                    - passport
                    - official_document
                    - residence_certificate
                    - other
                    - not_registered
                tax_id_country:
                  description: >-
                    ISO 3166-1 alpha-2 country the tax id belongs to. Optional
                    when derivable from tax_id_type (es_nif and not_registered
                    imply ES; eu_vat derives it from the VAT prefix); required
                    for passport, official_document, residence_certificate and
                    other. A pair that contradicts the tax_id_type is rejected.
                  example: ES
                  type: string
                  minLength: 2
                  maxLength: 2
                email:
                  description: >-
                    Recipient email. When the environment has automatic invoice
                    emails enabled, the invoice is sent to this address once the
                    tax agency accepts it.
                  example: cliente@example.com
                  type: string
                  format: email
                  pattern: >-
                    ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                address:
                  type: object
                  properties:
                    line1:
                      type: string
                      minLength: 1
                      maxLength: 200
                      description: Street address.
                      example: Calle Mayor 1
                    line2:
                      description: Additional address line.
                      example: Planta 2
                      type: string
                      maxLength: 200
                    postal_code:
                      type: string
                      minLength: 1
                      maxLength: 20
                      description: Postal code.
                      example: '28001'
                    city:
                      type: string
                      minLength: 1
                      maxLength: 100
                      description: City.
                      example: Madrid
                    country:
                      type: string
                      minLength: 2
                      maxLength: 2
                      description: ISO 3166-1 alpha-2 country code.
                      example: ES
                  required:
                    - line1
                    - postal_code
                    - city
                    - country
                  additionalProperties: false
                  description: Postal address of the recipient.
              required:
                - name
                - tax_id
                - address
              additionalProperties: false
              description: The identified recipient of a complete invoice.
          required:
            - line_items
            - type
          additionalProperties: false
        - type: object
          properties:
            number_series_id:
              description: >-
                Number series to issue on (see the Number Series resource).
                Defaults to the environment default series. For an ordinary
                invoice this must be a standard series; for a rectificativa (a
                `rectifies` block) it must be a rectifying series.
              example: ns_clx456def789
              type: string
            rectifies:
              type: object
              properties:
                method:
                  type: string
                  enum:
                    - differences
                    - substitution
                  description: >-
                    How to correct the original. `differences` books only the
                    delta; `substitution` replaces the original in full.
                  example: differences
                reason:
                  description: >-
                    Why the original is being corrected (drives the AEAT R1-R4
                    code). Defaults to `correction` (R1). Use `insolvency` (R2)
                    for concurso, `uncollectible` (R3) for créditos incobrables,
                    `other` (R4) otherwise. Simplified invoices always register
                    as R5.
                  example: correction
                  type: string
                  enum:
                    - correction
                    - insolvency
                    - uncollectible
                    - other
                invoice_id:
                  description: >-
                    Opaque id of the invoice to correct, when it was issued
                    through Finseed. Mutually exclusive with `external`.
                  example: inv_clx123abc456
                  type: string
                external:
                  type: object
                  properties:
                    number:
                      type: string
                      minLength: 1
                      maxLength: 60
                      description: >-
                        Invoice number of the external original, exactly as it
                        was issued.
                      example: F-2025-091
                    issued_on:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}$
                      description: >-
                        Issue date of the external original as a plain calendar
                        date (YYYY-MM-DD).
                      example: '2025-03-14'
                    rectified_amounts:
                      type: object
                      properties:
                        base:
                          type: integer
                          description: >-
                            Taxable base of the external original, in minor
                            units (cents).
                          example: 100000
                        tax:
                          type: integer
                          description: >-
                            Tax amount of the external original, in minor units
                            (cents).
                          example: 21000
                        surcharge:
                          description: >-
                            Recargo de equivalencia surcharge of the external
                            original, in minor units (cents). Omit when it does
                            not apply.
                          example: 0
                          type: integer
                      required:
                        - base
                        - tax
                      additionalProperties: false
                      description: >-
                        The original amounts the tax agency needs to register a
                        substitution against an external original (its
                        `ImporteRectificación`). Required when `method` is
                        `substitution`.
                  required:
                    - number
                    - issued_on
                  additionalProperties: false
                  description: >-
                    The original this rectificativa corrects when it was NOT
                    issued through Finseed (a pre-Finseed invoice a migrated
                    merchant rectifies).
              required:
                - method
              additionalProperties: false
              description: >-
                Turns this request into a rectificativa (corrective invoice).
                Reference the original with exactly one of `invoice_id` (issued
                through Finseed) or `external` (issued elsewhere). Omit the
                whole block to issue an ordinary invoice.
            operation_date:
              description: >-
                Date the underlying operation took place, as a calendar day
                (`YYYY-MM-DD`) interpreted in the Europe/Madrid timezone. Must
                be an existing calendar day between 2025-01-01 and today. When
                omitted, or when it equals the issue date, the invoice carries
                the issue date as its operation date. Not supported together
                with a `rectifies` block.
              example: '2025-06-15'
              type: string
              pattern: ^(\d{4})-(\d{2})-(\d{2})$
            line_items:
              minItems: 1
              maxItems: 500
              type: array
              items:
                type: object
                properties:
                  description:
                    type: string
                    minLength: 1
                    maxLength: 500
                    description: Description of the goods or service.
                    example: Consulting services
                  quantity:
                    type: integer
                    minimum: 1
                    description: Number of units billed on this line.
                    example: 2
                  unit_amount:
                    type: integer
                    description: >-
                      Net price of a single unit before tax, in minor units
                      (cents). Negative values create discount lines. Line and
                      invoice totals are computed server-side from quantity,
                      unit_amount and the tax rate.
                    example: 4150
                  tax:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - vat
                          - igic
                          - ipsi
                          - es_exempt
                          - es_inversion_sujeto_pasivo
                          - es_non_taxable
                          - es_non_taxable_localization
                          - eu_oss
                          - eu_b2b
                          - eu_b2b_services
                          - export
                        description: >-
                          Tax category for this line. `vat`, `igic`, `ipsi` and
                          `eu_oss` require a `rate`; the remaining types are
                          rate-free (exemptions, reverse charge, non-taxable,
                          intra-EU, export).
                        example: vat
                      rate:
                        description: >-
                          Tax rate as a percentage with up to two decimals (21
                          means 21%); more precision is rejected, never rounded.
                          Required for `vat`, `igic`, `ipsi` and `eu_oss`; omit
                          it for rate-free types.
                        example: 21
                        type: number
                        minimum: 0
                        maximum: 100
                    required:
                      - type
                    additionalProperties: false
                    description: The tax applied to a line.
                required:
                  - description
                  - quantity
                  - unit_amount
                  - tax
                additionalProperties: false
                description: A line to bill.
              description: The lines to bill. At least one.
            recargo_equivalencia:
              description: >-
                Applies the Spanish recargo de equivalencia regime: every VAT
                line gains its legally paired surcharge (21%→5.2%, 10%→1.4%,
                4%→0.5%), computed server-side.
              example: false
              type: boolean
            footer_notes:
              description: Free-form text printed at the bottom of the invoice PDF.
              example: Pago a 30 días.
              type: string
              maxLength: 2000
            type:
              type: string
              const: simplified
              description: >-
                A simplified invoice (ticket): no identified recipient required.
                Total must not exceed 3,000 EUR.
            recipient:
              type: object
              properties:
                name:
                  description: Recipient name, when known.
                  example: Jane Doe
                  type: string
                  minLength: 1
                  maxLength: 200
                email:
                  description: >-
                    Recipient email. When the environment has automatic invoice
                    emails enabled, the invoice is sent to this address once
                    accepted.
                  example: cliente@example.com
                  type: string
                  format: email
                  pattern: >-
                    ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                address:
                  description: Postal address, when known.
                  type: object
                  properties:
                    line1:
                      type: string
                      minLength: 1
                      maxLength: 200
                      description: Street address.
                      example: Calle Mayor 1
                    line2:
                      description: Additional address line.
                      example: Planta 2
                      type: string
                      maxLength: 200
                    postal_code:
                      type: string
                      minLength: 1
                      maxLength: 20
                      description: Postal code.
                      example: '28001'
                    city:
                      type: string
                      minLength: 1
                      maxLength: 100
                      description: City.
                      example: Madrid
                    country:
                      type: string
                      minLength: 2
                      maxLength: 2
                      description: ISO 3166-1 alpha-2 country code.
                      example: ES
                  additionalProperties: false
              additionalProperties: false
              description: >-
                Optional, unvalidated recipient data on a simplified invoice.
                Unknown fields are rejected: to bill an identified recipient
                with a tax_id, create a complete invoice instead.
          required:
            - line_items
            - type
          additionalProperties: false
      description: >-
        The invoice to issue. The invoice number, issue date and totals are
        assigned server-side; the optional `operation_date` is the only date the
        caller sets. Issuance is immediate and the AEAT registration progresses
        asynchronously (poll `verifactu.status`). Include a `rectifies` block to
        issue a rectificativa instead of an ordinary invoice.
    Invoice:
      type: object
      properties:
        id:
          type: string
          description: Opaque, prefixed invoice identifier.
          example: inv_clx123abc456
        status:
          type: string
          description: >-
            Lifecycle status of the invoice. This is an extensible enum: new
            values may be added in the future, so clients must tolerate values
            not listed here. Known values: issued, voided.
          example: issued
        number:
          type: string
          description: Human-readable invoice number.
          example: 2026-000123
        currency:
          type: string
          description: Lowercase ISO 4217 currency code.
          example: eur
        subtotal:
          type: integer
          description: Net total before tax, in minor units (cents) of the currency.
          example: 8300
        tax:
          type: integer
          description: Total tax, in minor units (cents) of the currency.
          example: 1743
        total:
          type: integer
          description: >-
            Gross total including tax, in minor units (cents) of the currency.
            Always equals subtotal + tax.
          example: 10043
        recipient_name:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Fiscal name of the invoice recipient (company or person), or null
            when none is recorded.
          example: ACME, S.L.
        recipient_tax_id:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Tax identifier of the recipient (e.g. NIF/CIF), or null when none is
            recorded.
          example: B12345678
        email:
          anyOf:
            - type: string
            - type: 'null'
          description: Recipient email, or null when none is recorded.
          example: cliente@example.com
        external_customer_id:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Customer identifier from the originating integration, or null when
            unavailable.
          example: cus_9aZ
        invoice_date:
          type: string
          description: Invoice issue date, RFC 3339 in UTC.
          example: '2026-06-01T09:30:00Z'
        operation_date:
          type: string
          description: >-
            Date the underlying operation took place, RFC 3339 in UTC. Often
            equal to invoice_date.
          example: '2026-06-01T09:30:00Z'
        created_at:
          type: string
          description: Creation timestamp, RFC 3339 in UTC.
          example: '2026-06-01T09:30:00Z'
        type:
          type: string
          description: >-
            Whether this is a complete invoice (identified recipient) or a
            simplified invoice (ticket). This is an extensible enum: new values
            may be added in the future, so clients must tolerate values not
            listed here. Known values: complete, simplified.
          example: complete
        number_series_id:
          type: string
          description: >-
            Identifier of the number series the invoice was issued on. See the
            Number Series resource.
          example: ns_clx456def789
        recipient:
          anyOf:
            - $ref: '#/components/schemas/InvoiceRecipient'
            - type: 'null'
          description: >-
            Full recipient block as recorded on the document, or null when no
            recipient data exists (simplified invoices). The flat
            recipient_name/recipient_tax_id/email fields remain as convenience
            aliases.
        pdf_url:
          type: string
          description: >-
            Signed link to the invoice PDF, valid for at least 24 hours from the
            moment this response was produced. Fetch a fresh one anytime by
            re-reading the invoice, or use the download endpoint. The PDF is
            generated shortly after creation; downloading earlier just takes a
            moment longer.
          example: https://api.finseed.es/v1/invoices/inv_clx123abc456/file?token=...
        verifactu:
          anyOf:
            - $ref: '#/components/schemas/InvoiceVerifactu'
            - type: 'null'
          description: >-
            Verifactu artifacts and AEAT registration state. Null only for
            legacy invoices imported before Verifactu tracking existed.
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItem'
          description: The lines that make up the invoice.
        kind:
          type: string
          description: >-
            Whether this is an original invoice or a rectifying (corrective)
            one, and by which method. `rectifying_differences` corrects by the
            delta; `rectifying_substitution` replaces the original in full. This
            is an extensible enum: new values may be added in the future, so
            clients must tolerate values not listed here. Known values:
            original, rectifying_differences, rectifying_substitution.
          example: original
        rectifies:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceRectifiedReference'
          description: >-
            The invoices this invoice rectifies. Empty for originals. A
            rectificativa issued against invoices in Finseed carries one `{
            invoice_id }` entry per corrected invoice; one issued against an
            external original carries a single `{ external: { number, issued_on
            } }` entry.
        rectified_by:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceReference'
          description: >-
            The rectifying invoices that correct this invoice, one `{ invoice_id
            }` entry each. Empty when nothing rectifies it. Voided
            rectificativas are excluded.
      required:
        - id
        - status
        - number
        - currency
        - subtotal
        - tax
        - total
        - recipient_name
        - recipient_tax_id
        - email
        - external_customer_id
        - invoice_date
        - operation_date
        - created_at
        - type
        - number_series_id
        - recipient
        - pdf_url
        - verifactu
        - line_items
        - kind
        - rectifies
        - rectified_by
      additionalProperties: false
      description: A tax invoice as exposed by the public API.
      example:
        id: inv_clx123abc456
        status: issued
        number: 2026-000123
        currency: eur
        subtotal: 8300
        tax: 1743
        total: 10043
        recipient_name: ACME, S.L.
        recipient_tax_id: B12345678
        email: cliente@example.com
        external_customer_id: cus_9aZ
        invoice_date: '2026-06-01T09:30:00Z'
        operation_date: '2026-06-01T09:30:00Z'
        created_at: '2026-06-01T09:30:00Z'
        type: complete
        number_series_id: ns_clx456def789
        recipient:
          name: ACME, S.L.
          company_name: null
          tax_id: B12345678
          tax_id_type: es_nif
          tax_id_country: ES
          email: cliente@example.com
          address:
            line1: Calle Mayor 1
            line2: null
            postal_code: '28001'
            city: Madrid
            country: ES
        pdf_url: https://api.finseed.es/v1/invoices/inv_clx123abc456/file?token=abc
        verifactu:
          status: registered
          hash: B11F3A0151ADA655A9A0A4A64F32F440BE0EE0F5A695BB2E4DC5C0C0AF6E8D2A
          qr_url: >-
            https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?nif=B12345678&numserie=2026-000123&fecha=01-06-2026&importe=100.43
          error: null
        line_items:
          - id: ili_clx789def012
            description: Consulting services
            sku: SVC-01
            quantity: 2
            unit_amount: 4150
            subtotal: 8300
            tax: 1743
            total: 10043
            tax_items:
              - name: IVA 21%
                type: vat
                rate: 21
                amount: 1743
        kind: original
        rectifies: []
        rectified_by: []
    ErrorEnvelope:
      type: object
      properties:
        code:
          type: string
          description: >-
            Stable, machine-readable error code. The branch key. This is an
            extensible enum: new values may be added in the future, so clients
            must tolerate values not listed here. Known values: invalid_request,
            unauthorized, invoice_not_found, download_link_expired,
            number_series_not_found, number_series_prefix_taken,
            number_series_in_use, customer_not_found, customer_ambiguous,
            idempotency_conflict, rate_limited, invalid_number_series,
            invalid_tax_rate, invalid_tax_data, invalid_tax_id,
            tax_id_type_country_mismatch, insufficient_recipient_data,
            simplified_amount_exceeded, simplified_incompatible_tax_type,
            invalid_recargo_equivalencia, aeat_mandate_not_approved,
            no_active_subscription, tax_id_validation_unavailable,
            invalid_rectifies_reference, rectified_invoice_not_found,
            invoice_already_voided, invoice_already_replaced,
            invoice_not_family_tip, invoice_pending_at_aeat,
            invoice_not_rectifiable_at_aeat, family_balance_below_zero,
            replacement_total_negative, reason_incompatible_with_recipient,
            recipient_overrides_not_allowed_for_differences,
            rectifying_series_invalid, external_reference_invalid,
            external_reference_matches_existing_invoice,
            rectified_amounts_required_for_substitution,
            line_item_without_tax_items, internal_error.
          example: invalid_request
        detail:
          type: string
          description: Human-readable, context-specific explanation.
          example: The query parameters are not valid.
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                description: Location of the offending value (JSON path).
                example: limit
              code:
                type: string
                description: Machine-readable validation issue code.
                example: too_big
              message:
                type: string
                description: Human-readable explanation of the field-level issue.
                example: Number must be less than or equal to 100
            required:
              - field
              - code
              - message
            additionalProperties: false
          description: >-
            Field-level issues. Always present; empty unless this is a
            validation failure.
        doc_url:
          type: string
          description: Link to the reference documentation for this error code.
          example: https://www.finseed.es/docs/api-reference/errors#invalid_request
      required:
        - code
        - detail
        - errors
        - doc_url
      additionalProperties: false
      description: >-
        Uniform error body returned for every non-2xx response
        (application/json).
    InvoiceRecipient:
      type: object
      properties:
        name:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Name of the recipient (person or business), or null when none is
            recorded.
          example: ACME, S.L.
        company_name:
          anyOf:
            - type: string
            - type: 'null'
          description: Company name when it was recorded separately from `name`, or null.
          example: null
        tax_id:
          anyOf:
            - type: string
            - type: 'null'
          description: Tax identifier (e.g. NIF/CIF), or null.
          example: B12345678
        tax_id_type:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Kind of tax identifier, or null when none is recorded. This is an
            extensible enum: new values may be added in the future, so clients
            must tolerate values not listed here. Known values: es_nif, eu_vat,
            passport, official_document, residence_certificate, other,
            not_registered.
          example: es_nif
        tax_id_country:
          anyOf:
            - type: string
            - type: 'null'
          description: ISO 3166-1 alpha-2 country the tax id belongs to, or null.
          example: ES
        email:
          anyOf:
            - type: string
            - type: 'null'
          description: Recipient email, or null.
          example: cliente@example.com
        address:
          anyOf:
            - $ref: '#/components/schemas/InvoiceRecipientAddress'
            - type: 'null'
          description: Postal address, or null when no address field is recorded.
      required:
        - name
        - company_name
        - tax_id
        - tax_id_type
        - tax_id_country
        - email
        - address
      additionalProperties: false
      description: >-
        The invoice recipient as recorded on the document. Null on simplified
        invoices without any recipient data.
    InvoiceVerifactu:
      type: object
      properties:
        status:
          type: string
          description: >-
            AEAT registration status. `pending` means the record is queued for
            submission; `registered` means AEAT accepted it;
            `registered_with_errors` means AEAT accepted it but flagged issues
            that need a correction; `rejected` means AEAT refused it; `skipped`
            means the record was deliberately never submitted. Registration is
            asynchronous: poll the invoice until it leaves `pending`. This is an
            extensible enum: new values may be added in the future, so clients
            must tolerate values not listed here. Known values: pending,
            registered, registered_with_errors, rejected, skipped.
          example: registered
        hash:
          type: string
          description: >-
            Chained Verifactu fingerprint (huella) of the invoice record,
            computed at issue time. Part of the legal record; safe to archive.
          example: B11F3A0151ADA655A9A0A4A64F32F440BE0EE0F5A695BB2E4DC5C0C0AF6E8D2A
        qr_url:
          type: string
          description: >-
            AEAT verification URL encoded in the invoice QR. Encode this URL as
            a QR code if you render your own documents; the PDF from this API
            already includes it. Test-environment invoices point at a simulator
            instead of AEAT.
          example: >-
            https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?nif=B12345678&numserie=F-000123&fecha=01-06-2026&importe=100.43
        error:
          anyOf:
            - $ref: '#/components/schemas/InvoiceVerifactuError'
            - type: 'null'
          description: >-
            Present when `status` is `registered_with_errors` or `rejected` and
            the tax agency reported a reason; null otherwise.
      required:
        - status
        - hash
        - qr_url
        - error
      additionalProperties: false
      description: Verifactu artifacts and AEAT registration state of the invoice.
    InvoiceLineItem:
      type: object
      properties:
        id:
          type: string
          description: Opaque, prefixed line-item identifier.
          example: ili_clx789def012
        description:
          type: string
          description: Description of the goods or service.
          example: Consulting services
        sku:
          anyOf:
            - type: string
            - type: 'null'
          description: Stock-keeping unit, or null when none is recorded.
          example: SVC-01
        quantity:
          type: integer
          description: Number of units billed on this line.
          example: 2
        unit_amount:
          type: integer
          description: Net price of a single unit before tax, in minor units (cents).
          example: 4150
        subtotal:
          type: integer
          description: Net total for this line before tax, in minor units (cents).
          example: 8300
        tax:
          type: integer
          description: Tax total for this line, in minor units (cents).
          example: 1743
        total:
          type: integer
          description: Gross total for this line including tax, in minor units (cents).
          example: 10043
        tax_items:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceTaxItem'
          description: The taxes applied to this line, broken down by category.
      required:
        - id
        - description
        - sku
        - quantity
        - unit_amount
        - subtotal
        - tax
        - total
        - tax_items
      additionalProperties: false
      description: A single line on an invoice.
    InvoiceRectifiedReference:
      anyOf:
        - $ref: '#/components/schemas/InvoiceReference'
        - $ref: '#/components/schemas/InvoiceExternalReference'
      description: >-
        An invoice a rectificativa corrects: either a local invoice (`{
        invoice_id }`) or an external original (`{ external: { number, issued_on
        } }`).
    InvoiceReference:
      type: object
      properties:
        invoice_id:
          type: string
          description: Opaque, prefixed identifier of the referenced invoice.
          example: inv_clx123abc456
      required:
        - invoice_id
      additionalProperties: false
      description: A reference to another invoice by its opaque id.
    InvoiceRecipientAddress:
      type: object
      properties:
        line1:
          anyOf:
            - type: string
            - type: 'null'
          description: Street address, or null when none is recorded.
          example: Calle Mayor 1
        line2:
          anyOf:
            - type: string
            - type: 'null'
          description: Additional address line, or null.
          example: null
        postal_code:
          anyOf:
            - type: string
            - type: 'null'
          description: Postal code, or null.
          example: '28001'
        city:
          anyOf:
            - type: string
            - type: 'null'
          description: City, or null.
          example: Madrid
        country:
          anyOf:
            - type: string
            - type: 'null'
          description: ISO 3166-1 alpha-2 country code, or null.
          example: ES
      required:
        - line1
        - line2
        - postal_code
        - city
        - country
      additionalProperties: false
      description: Postal address of the invoice recipient.
    InvoiceVerifactuError:
      type: object
      properties:
        code:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Error code reported by the tax agency (AEAT), verbatim, or null when
            only a message is available.
          example: '1142'
        message:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Error message reported by the tax agency, verbatim (Spanish), or
            null.
          example: El NIF del destinatario no está identificado en el censo de la AEAT.
      required:
        - code
        - message
      additionalProperties: false
      description: The tax-agency error behind a problematic registration.
    InvoiceTaxItem:
      type: object
      properties:
        name:
          type: string
          description: >-
            Human-readable tax label as it appears on the invoice, e.g. "IVA
            21%".
          example: IVA 21%
        type:
          type: string
          description: >-
            Tax category this line is subject to. This is an extensible enum:
            new values may be added in the future, so clients must tolerate
            values not listed here. Known values: vat, igic, ipsi,
            es_recargo_equivalencia, es_exempt, es_inversion_sujeto_pasivo,
            es_non_taxable, es_non_taxable_localization, eu_oss, eu_b2b,
            eu_b2b_services, export, other.
          example: vat
        rate:
          type: number
          description: >-
            Tax rate as a percentage. For example 21 means 21%, and 10.5 means
            10.5%. Zero for exempt or non-taxable lines.
          example: 21
        amount:
          type: integer
          description: >-
            Tax charged for this line, in minor units (cents) of the invoice
            currency.
          example: 1743
      required:
        - name
        - type
        - rate
        - amount
      additionalProperties: false
      description: A single tax applied to an invoice line.
    InvoiceExternalReference:
      type: object
      properties:
        external:
          type: object
          properties:
            number:
              type: string
              description: Invoice number of the external original, as recorded.
              example: F-2025-091
            issued_on:
              type: string
              description: >-
                Issue date of the external original, as a plain calendar date
                (YYYY-MM-DD).
              example: '2025-03-14'
          required:
            - number
            - issued_on
          additionalProperties: false
          description: >-
            The external original this invoice rectifies, identified by its
            number and issue date because it was not issued through Finseed.
      required:
        - external
      additionalProperties: false
      description: >-
        A reference to an invoice that lives outside Finseed (e.g. a pre-Finseed
        original a migrated merchant rectifies).
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key sent as a bearer token in the `Authorization` header.

````