Skip to main content

Spain Fiscalization Guide

Spain has three fiscalization systems. FiscalAPI supports all of them:

  • TicketBAI -- Real-time invoice reporting for the Basque Country
  • Verifactu -- Invoice verification for the rest of Spain
  • SII -- Real-time invoice reporting for large businesses (annual revenue >= EUR 6M)

TicketBAI vs Verifactu vs SII

FeatureTicketBAIVerifactuSII
ScopeBasque Country territoriesAll of SpainLarge businesses (>= EUR 6M)
TerritoriesGipuzkoa, Araba, BizkaiaNationwideNationwide
AuthorityRegional tax authoritiesAEAT (national)AEAT (national)
SubmissionReal-time XML (Gipuzkoa/Araba) or LROE batch (Bizkaia)SOAP to AEATSOAP to AEAT
SigningXAdES-EPESSHA-256 hash chainingMutual TLS
DeadlineReal-timeReal-time4 calendar days
StatusActive (mandatory in Basque Country)Rolling outActive

When to use TicketBAI

Use TicketBAI for merchants operating in the Basque Country:

  • Gipuzkoa -- Real-time XML POST with XAdES-EPES signature
  • Araba -- Real-time XML POST with XAdES-EPES signature
  • Bizkaia -- LROE batch submission (daily at 2 AM UTC)

When to use Verifactu

Use Verifactu for merchants operating in the rest of Spain or for nationwide compliance. Verifactu submits invoices via SOAP to AEAT with SHA-256 hash chaining for invoice integrity.

When to use SII

Use SII for large businesses with annual turnover exceeding EUR 6,336,000, businesses enrolled in the monthly VAT refund scheme (REDEME), or groups filing consolidated VAT returns. SII submits invoice records to AEAT via SOAP with mutual TLS authentication within a four-day window. See the SII guide for full details.

Country config fields

The country_config object for Spanish locations supports the following fields:

Common fields

FieldTypeRequiredDescription
systemstringYesticketbai, verifactu, or sii
nifstringYesSpanish tax ID (NIF/CIF)
legal_namestringYesCompany legal name
certificate_idstringYesReference to an uploaded certificate
tsa_urlstringNoRFC 3161 TSA endpoint for XAdES-T timestamps

TicketBAI fields

FieldTypeRequiredDescription
territorystringYesgipuzkoa, araba, or bizkaia
tbai_licensestringYesTicketBAI software license code

Verifactu fields

FieldTypeRequiredDescription
software_nifstringYesSoftware developer's NIF
installation_numberstringNoVerifactu installation identifier

SII fields

SII configuration is simpler -- it requires only the NIF and legal name. See the SII guide for full configuration and metadata details.

FieldTypeRequiredDescription
nifstringYesSpanish tax ID (NIF/CIF) of the obligated party
legal_namestringYesFull legal name (razón social)
certificate_idstringYesReference to an uploaded certificate for mutual TLS

Configuration examples

TicketBAI location (Gipuzkoa)

curl -X POST https://api.fiscalapi.com/v1/locations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fsk_test_abc123def456..." \
-d '{
"name": "Donostia Store",
"country": "ES",
"address": "Calle Mayor 1, 20003 San Sebastián",
"tax_id": "B12345674",
"country_config": {
"system": "ticketbai",
"territory": "gipuzkoa",
"nif": "B12345674",
"legal_name": "Acme Corp SL",
"certificate_id": "spain-prod-2026",
"tbai_license": "TBAILIC123456"
}
}'

TicketBAI location (Bizkaia)

Bizkaia uses LROE batch submission instead of real-time. Transactions are queued with pending_lroe status and submitted in batches (daily at 2 AM UTC).

curl -X POST https://api.fiscalapi.com/v1/locations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fsk_test_abc123def456..." \
-d '{
"name": "Bilbao Store",
"country": "ES",
"address": "Gran Vía de Don Diego López de Haro 1, 48001 Bilbao",
"tax_id": "B12345674",
"country_config": {
"system": "ticketbai",
"territory": "bizkaia",
"nif": "B12345674",
"legal_name": "Acme Corp SL",
"certificate_id": "spain-prod-2026",
"tbai_license": "TBAILIC123456"
}
}'

Verifactu location

curl -X POST https://api.fiscalapi.com/v1/locations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fsk_test_abc123def456..." \
-d '{
"name": "Barcelona Store",
"country": "ES",
"address": "Passeig de Gracia 1, 08007 Barcelona",
"tax_id": "B87654321",
"country_config": {
"system": "verifactu",
"nif": "B87654321",
"legal_name": "Acme Corp SL",
"certificate_id": "spain-prod-2026",
"software_nif": "B99999999",
"installation_number": "001"
}
}'

SII location

curl -X POST https://api.fiscalapi.com/v1/locations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fsk_test_abc123def456..." \
-d '{
"name": "Madrid HQ",
"country": "ES",
"address": "Calle de Alcalá 50, 28014 Madrid",
"tax_id": "A12345674",
"country_config": {
"system": "sii",
"nif": "A12345674",
"legal_name": "Gran Empresa SL",
"certificate_id": "spain-sii-prod-2026"
}
}'

Submission flows

TicketBAI (Gipuzkoa / Araba)

  1. Transaction is created via POST /v1/transactions
  2. FiscalAPI generates the TicketBAI XML with invoice chaining (per-NIF)
  3. XML is signed with XAdES-EPES using the uploaded certificate
  4. Signed XML is POSTed to the regional tax authority in real-time
  5. On success, fiscal_id (TBAI ID) is set and a QR code URL is generated
  6. Transaction status transitions to success

TicketBAI (Bizkaia -- LROE)

  1. Transaction is created via POST /v1/transactions
  2. Inline XML generation and signing succeeds
  3. Transaction status transitions to pending_lroe (not yet submitted)
  4. LROE batch processor collects pending transactions and submits them as a batch
  5. On acceptance, transaction status transitions to success

You can monitor LROE batch processing via the batch stats endpoint.

Verifactu

  1. Transaction is created via POST /v1/transactions
  2. FiscalAPI generates the Verifactu record with SHA-256 hash chaining
  3. Record is submitted via SOAP to AEAT
  4. On success, fiscal_id is set and transaction status transitions to success

SII

  1. Transaction is created via POST /v1/transactions
  2. FiscalAPI builds a SOAP envelope with the invoice record
  3. Envelope is submitted to AEAT via mutual TLS
  4. AEAT responds with a status and CSV (Código Seguro de Verificación)
  5. On success, fiscal_id is set to the CSV and transaction status transitions to success

Invoices must be reported within four calendar days. See the SII guide for metadata fields, book types, and endpoint details.

Invoice chaining

Both TicketBAI and Verifactu use invoice chaining to ensure integrity. Each invoice references the hash of the previous invoice for the same NIF, creating a tamper-evident chain. FiscalAPI manages this automatically -- you don't need to track chain state.

Switching systems

You can change a location's fiscalization system using the update endpoint:

curl -X PATCH https://api.fiscalapi.com/v1/locations/{id} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fsk_test_abc123def456..." \
-d '{
"country_config": {
"system": "verifactu",
"nif": "B12345674",
"legal_name": "Acme Corp SL",
"certificate_id": "spain-prod-2026",
"software_nif": "B99999999"
}
}'

Validation rules

FiscalAPI enforces these rules for Spanish locations:

  1. country_config is required -- Spain locations must include a country_config with a system field
  2. Valid systems -- system must be ticketbai, verifactu, or sii
  3. Territory -- Required for TicketBAI; must be gipuzkoa, araba, or bizkaia
  4. NIF -- Spanish tax ID (CIF/NIF) for the merchant
  5. Legal name -- Required for SII (the obligated party's full legal name)
  6. Certificate -- A valid signing certificate must be uploaded and referenced by certificate_id

Error examples

Missing country config:

{
"error": "Spain locations require country_config with system field (ticketbai, verifactu, or sii)"
}

Invalid system:

{
"error": "system must be \"ticketbai\", \"verifactu\", or \"sii\", got \"invalid\""
}

Territories

TerritorySystemSubmission
GipuzkoaTicketBAIReal-time XML POST
ArabaTicketBAIReal-time XML POST
BizkaiaTicketBAILROE batch