Skip to main content
POST
Create an invoice
Alpha endpointThis 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.
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.
  • 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.
  • 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.

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.

Examples

Standard domestic sale at 21% VAT:
Simplified ticket (no recipient):
Exempt operation (for example training):
Reverse charge (inversión del sujeto pasivo; requires a complete invoice):
Intra-EU B2B service to a VIES-registered business:
OSS sale to an EU consumer (destination-country VAT):
Canary Islands sale (IGIC):
Recargo de equivalencia (the surcharge pairs are computed server-side):
Discount line (negative net amount):

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.

Autorizaciones

Authorization
string
header
requerido

API key sent as a bearer token in the Authorization header.

Encabezados

Idempotency-Key
string

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.

Cuerpo

application/json

The invoice to issue.

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.

line_items
object[]
requerido

The lines to bill. At least one.

Required array length: 1 - 500 elements
type
string
requerido

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.

Allowed value: "complete"
number_series_id
string

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.

Ejemplo:

"ns_clx456def789"

rectifies
object

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
string

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.

Pattern: ^(\d{4})-(\d{2})-(\d{2})$
Ejemplo:

"2025-06-15"

recargo_equivalencia
boolean

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.

Ejemplo:

false

Free-form text printed at the bottom of the invoice PDF.

Maximum string length: 2000
Ejemplo:

"Pago a 30 días."

recipient
object

The identified recipient of a complete invoice.

Respuesta

The issued invoice.

A tax invoice as exposed by the public API.

id
string
requerido

Opaque, prefixed invoice identifier.

Ejemplo:

"inv_clx123abc456"

status
string
requerido

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.

Ejemplo:

"issued"

number
string
requerido

Human-readable invoice number.

Ejemplo:

"2026-000123"

currency
string
requerido

Lowercase ISO 4217 currency code.

Ejemplo:

"eur"

subtotal
integer
requerido

Net total before tax, in minor units (cents) of the currency.

Ejemplo:

8300

tax
integer
requerido

Total tax, in minor units (cents) of the currency.

Ejemplo:

1743

total
integer
requerido

Gross total including tax, in minor units (cents) of the currency. Always equals subtotal + tax.

Ejemplo:

10043

recipient_name
string | null
requerido

Fiscal name of the invoice recipient (company or person), or null when none is recorded.

Ejemplo:

"ACME, S.L."

recipient_tax_id
string | null
requerido

Tax identifier of the recipient (e.g. NIF/CIF), or null when none is recorded.

Ejemplo:

"B12345678"

email
string | null
requerido

Recipient email, or null when none is recorded.

Ejemplo:

"cliente@example.com"

external_customer_id
string | null
requerido

Customer identifier from the originating integration, or null when unavailable.

Ejemplo:

"cus_9aZ"

invoice_date
string
requerido

Invoice issue date, RFC 3339 in UTC.

Ejemplo:

"2026-06-01T09:30:00Z"

operation_date
string
requerido

Date the underlying operation took place, RFC 3339 in UTC. Often equal to invoice_date.

Ejemplo:

"2026-06-01T09:30:00Z"

created_at
string
requerido

Creation timestamp, RFC 3339 in UTC.

Ejemplo:

"2026-06-01T09:30:00Z"

type
string
requerido

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.

Ejemplo:

"complete"

number_series_id
string
requerido

Identifier of the number series the invoice was issued on. See the Number Series resource.

Ejemplo:

"ns_clx456def789"

recipient
object | null
requerido

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
string
requerido

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.

Ejemplo:

"https://api.finseed.es/v1/invoices/inv_clx123abc456/file?token=..."

verifactu
object | null
requerido

Verifactu artifacts and AEAT registration state. Null only for legacy invoices imported before Verifactu tracking existed.

line_items
object[]
requerido

The lines that make up the invoice.

kind
string
requerido

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.

Ejemplo:

"original"

rectifies
object[]
requerido

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.

An invoice a rectificativa corrects: either a local invoice ({ invoice_id }) or an external original ({ external: { number, issued_on } }).

rectified_by
object[]
requerido

The rectifying invoices that correct this invoice, one { invoice_id } entry each. Empty when nothing rectifies it. Voided rectificativas are excluded.