TicketBAI Guide

Comply with TicketBAI and Spain Anti-Fraud Law by using B2Brouter API

The Anti-Fraud Law (Law 11/2021) and its subsequent technical regulation Royal Decree 1007/2023 mandates that businesses must ensure their invoicing and accounting systems meet strict technical standards to prevent data manipulation. These regulations require businesses to adopt systems capable of securely generate, store, and transmit invoices and tax reports. For business located in Euskadi, Spain Anti-Fraud flaw mandates the use of TicketBAI. B2Brouter's TicketBAI REST API is a technical solution that allows your business to easily be 100% compliant offloading the complexities to B2Brouter and focusing on the business logic of your system.

B2Brouter provides a convenient API for submitting TicketBAI tax reports so you can easily comply with the legislation of the three Basque Tax Authorities (Araba, Bizkaia, and Gipuzkoa). Our API abstracts away the differences between them and offers you an unified interface that is fully compliant with all three Tax Authorities. You can check the status of B2Brouter as "software garante" in all three Tax Authorities: Araba, Bizkaia, Gipuzkoa.

What is TicketBAI?

TicketBAI is a joint project of the Basque Provincial Councils (Gipuzkoa, Bizkaia, and Araba) and the Basque Government to control invoicing and ensure tax compliance. It requires all self-employed individuals and companies to use certified invoicing software that generates a unique code and a QR code for each invoice. This system aims to prevent tax fraud by ensuring that all economic transactions are recorded and transmitted to the tax authorities in real-time or near real-time.

TicketBAI involves:

  • Generating a unique TicketBAI identifier, a QR code for each invoice, and a tax report that includes the relevant information of the invoice.
  • Digitally signing each tax report using a qualified electronic certificate.
  • Chaining tax reports together cryptographically to ensure immutability and prevent tampering.
  • Submitting the tax report to the relevant Basque Tax Authority (Hacienda Foral) in a specified format in a timely manner.
  • Processing the responses from the Tax Authority for each submission.

With B2Brouter, you can abstract much of the complexities of this process, and comply with the Anti-Fraud Law by issuing just a few REST calls to the API. You will not need your own qualified electronic certificate because B2Brouter is a Social Collaborator in Tax Management. You just need a valid B2Brouter API Key.

B2Brouter provides two modalities of operation depending on whether you are using B2Brouter for both issuing invoices and reporting them to the Tax Authority, or just for tax reporting.

Setting up and working with B2Brouter API

The first step is to set up the configuration for TicketBAI for each one of the Companies for which you want to submit tax reports. You can refer to the TaxReportSettingins Guide for a full description of the process. The call for configuring an account is as follows:

curl --location 'https://app.b2brouter.net/accounts/{account_id}/tax_report_setting' \
--header 'X-B2B-API-Key: xxxxxxx' \
--header 'Content-Type: application/json' \
{
  "tax_report_setting": {
    "code": "tbai",
    "start_date": "2025-04-06",
    "auto_generate": true,
    "auto_send": true,
    "reason_vat_exempt": "E1",
    "special_regime_key": "01",
    "reason_no_subject": "OT",
    "credit_note_code": "R1",
    "delegation": "gipuzkoa",
    "type_operation": "services"
  }
}

Invoice API

If you are using B2Brouter for both issuing invoices and reporting them to the Tax Authority, once you have correctly configured your account, you can operate as you'd normally do for issuing invoices.

The issued invoices will contain the mandatory QR code, and the TicketBAI tax report will be sent automatically to the relevant Tax Authority. This is an example of a call to create and issue an Invoice:

curl --request POST \
     --url https://app-staging.b2brouter.net/projects/account/invoices.json \
     --header 'content-type: application/json' \
     --data '
{
  "send_after_import": true,
  "project_id": "3-enterprise",
  "invoice": {
    "date": "2025-04-15",
    "due_date": "2025-05-15",
    "number": 48,
    "payment_method": 1,
    "client": {
      "name": "client.name",
      "address": "client.address",
      "address2": "client.address2",
      "city": "client.city",
      "province": "client.province",
      "postalcode": "28938",
      "country": "es",
      "email": "[email protected]",
      "language": "es",
      "currency": "EUR",
      "website": "client.website",
      "terms": "15",
      "payment_method": 1,
      "tin_scheme": 9920,
      "tin_value": "ESA28388510",
      "notes": "client.notes",
      "description": "client.description"
    },
    "invoice_lines_attributes": [
      {
        "quantity": 10.0,
        "description": "line.description",
        "price": 11.0,
        "unit": 9,
        "taxes_attributes": [
          {
            "name": "IVA",
            "percent": 21.0,
            "category": "S"
          }
        ]
      }
    ]
  }
}'

In the response of the POST REST call for creating an invoice, if send_after_import is set to true, you will find a section tax_report_ids in which you'll find the ID of the tax report associated with the invoice. Note that tax_report_ids is an array because each invoice can have more than one tax report for cancellations and corrections. However, when the invoice is freshly created there is only one tax report ID in the tax_report_ids section:

{
  "invoice": {
    "id": 4919734,
    "type": "IssuedInvoice",
    "number": "48",
    "from_net": "api",
    "from_net_id": null,
    "project": {
      "id": 107926,
      "name": "3 - Enterprise Company"
    },
    "company": {
      "id": 100446,
      "name": "3 - Enterprise Company",
      "taxcode": "ES77167394W",
      "address": null,
      "address2": null,
    "postalcode": "08080",
      "city": null,
      "province": null,
      "country": "es"
    },
    "client": {
      "id": 483183,
      "name": "client.name",
      "taxcode": "ESA28388510",
      "address": "client.address",
      "address2": "client.address2",
      "postalcode": "28938",
      "city": "client.city",
      "province": "client.province",
      "country": "es",
      "party_identification": null
    },
    "state": "sending",
    "date": "2025-04-15",
    "due_date": "2025-05-15",
    "ponumber": null,
    "file_reference": null,
    "payment_method_info": "Pagament en efectiu",
    "contact_iban": "NL35ABNA1749777983",
    "contact_bic": "clientbic",
    "is_credit_note": false,
    "adjustment_in_cents": 0,
    "charge_reason": null,
    "charge_amount": 0.0,
    "charge_percent": 0.0,
    "discount_text": null,
    "discount_percent": 0.0,
    "discount_amount": 0.0,
    "subtotal": 110.0,
    "taxes": [
      {
        "name": "IVA 21,00%",
        "percent": 21.0,
        "base": 110.0,
        "amount": 23.1
      }
    ],
    "total": 133.1,
    "currency": "EUR",
    "amounts_withheld_reason": null,
    "withheld_percent": 0.0,
    "amounts_withheld": 0.0,
    "payable_amount": 133.1,
    "extra_info": null,
    "tax_report_ids": [
        15
    ],
    "created_at": "2025-04-15T09:54:42Z",
    "updated_at": "2025-04-15T09:54:45Z",
    "state_updated_at": "2025-04-15T09:54:45Z",
    "ack_at": null,
    "apply_taxes_to_charge": false,
    "charge_is_reimbursable_expense": false
  }
}

You can access the complete tax report, including the QR code, its identifier, its state, and all other fields, by calling the get tax report endpoint with the tax report ID provided in the response of the create invoice call.

Note that both the chaining process and the sending process of the tax report are asynchronous processes, that is, are performed on the background outside the main process that creates the invoice and generates the tax report.

Therefore, the state of the tax report will always be processing in the response of the POST call to create an invoice because the background process that chains and sends the tax report is performed independently of the process of creating the invoice and its associated tax report.

This is the reason why you must check the life cycle of the tax report. The state field of the tax report after issuing the invoice will change. You have two options to accomplish this:

  • The recommended way is using the tax report web hook. The web hook will issue a POST call to your system each time the state of the tax report reaches a final state. These states are: registered, error, and registered_with_errors

  • Pooling the state of the tax report with get tax report endpoint until the state field is registered, error or registered_with_errors.

[BETA] Tax Report API for TicketBAI

If you are not using B2Brouter for issuing invoices, need more control over the process of generating and processing tax reports, or expect a high volume of tax reports, as in a Point of Sale ("Terminal Punto de Venta" in Spanish), you can use the new Tax Report API. This API is designed for maximum control by the user and high availability.

The structure of the JSON format for B2Brouter tax reports is based on PEPPOL Continuous Transaction Control (CTC). That means that the fields used in the JSON payload have not the same name as in the XML representation of a TicketBAI tax report. The reason behind this design decision is that B2Brouter Tax Report API is an universal API not only geared towards TicketBAI but designed to handle tax reporting around the World. You can check the equivalences between B2Brouter's representation of a Tax Report and TicketBAI XML nodes in the section Equivalence between B2Brouter internal tax report fields and TicketBAI XML nodes.

It's important to notice that for TicketBAI, tax reports have tax report lines which represent the individual lines of the original invoice. The TaxReport model does not perform any calculations. You must provide all relevant figures in the tax report. B2Brouter will perform error checking on these figures, but will not fill the gaps in incomplete data.

Create a Tax Report

In order to create a tax report you have to call the create tax report endpoint. Please refer to the section Equivalence between B2Brouter internal tax report fields and TicketBAI XML nodes for a complete list of equivalences.

As an example, a minimal and valid tax report can be created by the following POST call:

curl -X POST --location 'https://app.b2brouter.net/api/v1/accounts/{account_id}/tax_reports' \
--header 'X-B2B-API-Key: xxxxxxx' \
--header 'Content-Type: application/json' \
--data
'{
  tax_report: {
    type: 'TicketBai',
    invoice_date: '2025-04-03',
    invoice_number: '11',
    description: 'Lorem ipsum...', 
    customer_party_tax_id: 'B63354613',
    customer_party_country: 'es',
    customer_party_postalcode: '08080',
    customer_party_address: 'casa seva',
    customer_party_name: 'Ingent Grup Systems, SL',
    tax_inclusive_amount: 121.0,
    tax_amount: 21.0,
    invoice_type_code: 'F1',
    currency: 'EUR',
    tax_report_lines: [
      {
        quantity: 1.0,
        description: 'Item 1',
        price: 100.0,
        tax_inclusive_amount: 121.0,
        tax_exclusive_amount: 100.0,
        tax_amount: 21.0
      }
    ]
  }
}'

The response of this POST call to the create tax report endpoint will already contain the field qr with the QR code (codified in base64) that you must include in the invoice for your customer. The content of this QR code is a URL that will allow your customer to check that the Tax Authority has received and processed the tax report derived from their invoice. This URL is also included in the response to the POST in the field identifier.

You can see the response to the above call:

{
  "tax_report": {
    "invoice_id": null,
    "state": "processing",
    "sent_at": null,
    "contact_name": null,
    "label": "TicketBai 11",
    "has_errors": false,
    "has_warnings": false,
    "from_net": null,
    "from_net_id": null,
    "to_net": null,
    "to_net_id": null,
    "ledger_id": null,
    "document_type_code": "xml.tax_report.ticketbai.alta",
    "transport_type_code": "es.ticketbai",
    "generation_timestamp": null,
    "tax_point_date": null,
    "chained_at": null,
    "invoice_date": "2025-04-03",
    "invoice_number": "11",
    "invoice_series_code": null,
    "fiscal_year": null,
    "fiscal_period": null,
    "amended_number": null,
    "amended_series_code": null,
    "amended_date": null,
    "amend_type": null,
    "amended_line_extension": null,
    "amended_tax_amount": null,
    "amended_tax_exclusive": null,
    "amended_tax_inclusive": null,
    "amended_charge_total": null,
    "amended_payable": null,
    "amended_quota_recargo_equivalencia": null,
    "invoice_type_code": "F1",
    "operation_type": null,
    "external_reference": null,
    "description": "Lorem ipsum...",
    "annullation": false,
    "correction": false,
    "ticket": false,
    "issued_by_third_party_or_receiver": false,
    "customer_party_name": "Ingent Grup Systems, SL",
    "customer_party_id": null,
    "customer_party_scheme": null,
    "customer_party_tax_id": "B63354613",
    "customer_party_tax_scheme": null,
    "customer_party_country": "es",
    "customer_party_endpoint_id": null,
    "supplier_party_name": "B2Brouter Global S.L.",
    "supplier_party_id": null,
    "supplier_party_scheme": null,
    "supplier_party_tax_id": "B63276174",
    "supplier_party_tax_scheme": null,
    "supplier_party_country": null,
    "supplier_party_endpoint_id": null,
    "third_party_name": null,
    "third_party_id": null,
    "third_party_scheme": null,
    "third_party_tax_id": null,
    "third_party_tax_scheme": null,
    "third_party_country": null,
    "third_party_endpoint_id": null,
    "line_extension_amount": null,
    "tax_amount": 21,
    "tax_exclusive_amount": null,
    "tax_inclusive_amount": 121,
    "charge_total": null,
    "payable_amount": null,
    "quota_recargo_equivalencia": null,
    "currency": "EUR",
    "original_currency": "EUR",
    "created_at": "2025-04-03T12:49:53.020Z",
    "updated_at": "2025-04-03T12:49:53.086Z",
    "identifier": "https://www.euskadi.eus/ticketbai/qr?id=...", 
    "qr": "iVBORw0KVGgoAAAANS[...]", 
    "previous_id": null,
    "previously_refused": null,
    "simplified_art7273": false,
    "macrodata": "N",
    "huella": null,
    "digested_at": null,
    "annulled_at": null,
    "coupon": false,
    "base_imponible_a_coste": null,
    "tax_report_lines": [
      {
        "id": 320703,
        "quantity": 1.0,
        "description": "Item 1",
        "price": 100.0,
        "discount_amount": null,
        "charge_amount": null,
        "tax_inclusive_amount": 121.0,
        "tax_exclusive_amount": 100.0,
        "tax_amount": 21.0
      }
    ]
  }
}

This minimal example covers only the most basic requirements, to generate a valid TicketBAI for more complex use cases, you must understand some of its idiosyncrasies. B2Brouter's Tax Report API gives you the flexibility to handle TicketBAI's specific requirements, but it also means that you are responsible for performing all the necessary calculations.

The key points to consider are:

  • Line-level Tax Calculation: TicketBAI requires that all taxes are calculated on a per-line basis. This means that for each line in your invoice, you must calculate the corresponding tax amount and provide it in the tax_report_lines. The total tax amount for the invoice will be the sum of the tax amounts of each line.

  • Global Discounts and Charges as Lines: Global discounts and charges must be treated as separate lines in the tax_report_lines array.

    • For a global discount, you should create a new line with a negative price and tax_inclusive_amount.
    • For a global charge, you should create a new line with a positive price and tax_inclusive_amount.
    • Taxes must be applied to these lines just like any other line, unless the charge is a "suplido" (a payment made on behalf of the customer). In that case, the charge should be reported as a line with its own tax breakdown indicating it is not subject to tax.
    • Withheld taxes (like IRPF) are not applied to these lines.
  • Withheld Taxes: Withheld taxes (e.g., IRPF) are not part of the line calculations. They are reported at the document level using the tax_amount_withheld field in the TaxReport object. This amount is sent in the RetencionSoportada tag of the TicketBAI XML.

Important: The B2Brouter TaxReport, TaxBreakdown, and TaxReportLine models are designed to be flexible and accommodate different regulations. They do not perform any calculations. You, as the API user, are responsible for providing all the correct values for prices, taxes, totals, etc.

The following is a more complex example of a TicketBAI with two lines, a global discount, IVA of 21%, and IRPF of 15% that illustrates how to perform the calculations necessary to successfully generate a valid TicketBAI with complex requirements:

curl -X POST --location 'https://app.b2brouter.net/api/v1/accounts/{account_id}/tax_reports' \
--header 'X-B2B-API-Key: xxxxxxx' \
--header 'Content-Type: application/json' \
--data
'{
  tax_report: {
    type: "TicketBai",
    invoice_date: "2025-08-13",
    invoice_number: "2025-128",
    description: "Invoice with multiple lines, global discount, IVA, and IRPF (tax withheld)",
    customer_party_tax_id: "B63354613",
    customer_party_country: "es",
    customer_party_postalcode: '08080',
    customer_party_address: 'casa seva',
    customer_party_name: "Ingent Grup Systems, SL",
    tax_inclusive_amount: 217.8,
    tax_amount: 37.8,
    tax_amount_withheld: 27,
    invoice_type_code: "F1",
    currency: "EUR",
    tax_report_lines: [
      {
        quantity: 1,
        description: "Product A",
        price: 100,
        tax_inclusive_amount: 121,
        tax_exclusive_amount: 100,
        tax_amount: 21
      },
      {
        quantity: 2,
        description: "Product B",
        price: 50,
        tax_inclusive_amount: 121,
        tax_exclusive_amount: 100,
        tax_amount: 21
      },
      {
        quantity: 1,
        description: "Global Discount 10%",
        price: -20,
        tax_inclusive_amount: -24.2,
        tax_exclusive_amount: -20,
        tax_amount: -4.2
      }
    ],
    tax_breakdowns: [
      {
        category: "S",
        non_exempt: true,
        non_exemption_code: "S1",
        percent: 21,
        taxable_base: 180,
        tax_amount: 37.8
      }
    ]
  }
}'

We cannot cover here the wide range of use cases possible for TicketBAI. If you struggle to generate a valid XML representation of a TicketBAI by issuing calls to our API, we recommend to use B2Brouter's itself to generate illustrative examples.

In the staging environment of B2Brouter, you can generate an invoice via the web UI that fulfills all your requirements (eg different kinds of equivalent surcharge taxes, specific regional rules, etc ...). Once the TicketBAI is generated, you can call the get tax report endpoint to obtain the JSON representation of the TicketBAI. The responses to GET calls to our API can be used as payloads for POST calls provided you change the values that must be unique (eg invoice_number).

Check the state of a Tax Report

Notice the that state field of the tax report will always be processing after a successful creation of a tax report. This is because both the chaining process among tax reports and the sending process of the ledger are asynchronous processes, that is, are performed on the background outside the main process that creates the tax report.

This is the reason why you must check the life cycle of the tax report, that is the evolution of the field state of the tax report after issuing the invoice. You have two options to accomplish this:

  • The recommended way is using the tax report web hook. The web hook will issue a POST call to your system each time the state of the tax report reaches a final state. These states are: registered, error, annulled, and registered_with_errors

  • Pooling the state of the tax report by calling the manually the get tax report endpoint until the state field of the tax report is any of: registered, error, annulled, and registered_with_errors.

Get the XML representation of the tax report

If you need the XML representation of the tax report, that is, in the case of TicketBAI, the XML that B2Brouter will send to the Tax Authority, you have available a download tax report endpoint. For your convenience, B2Brouter also includes a field named xml_base64 in the response to the GET call to the get tax report endpoint that includes the XML codified in base64. Thus, you can both check the state of the tax report, and get the XML representation in just one call.

Note however that, for the case of TicketBAI, the XML representation of the tax report can only be generated after the tax report has been chained. Which, as discussed above, is an asynchronous process. This process is usually fast, as it happens entirely in B2Brouter systems without need to communicate with the Tax Authority. But there is no guarantee that the tax report will already be chained if you call the get tax report endpoint just after creating the tax report. If the tax report is still in the chaining queue its state will be processing and the xml_base64 field will be nil.

Error checking

It is specially difficult for client systems to deal with all the errors that the Tax Authority may return. To avoid this potential issues, B2Brouter has implemented an exhaustive set of validations of TicketBAI tax reports. This allows early error detection and stops an erroneous (or slightly incorrect) tax report before sending it to the Tax Authority.

For the TicketBAI case, there are exhaustive validations based on the specifications published by the Basque Tax Authorities. If there is a validation error the tax report will not be created, and therefore will not be sent to the Tax Authority. You'll receive a 422: Unprocessable Entity response with all errors in JSON format. You'll have to correct the errors and create a new tax report.

Cancel a Tax Report

In order to cancel a tax report ("anulación" in Spanish) you have to use the DELETE verb calling the annullation endpoint. As in the creation case, you'll have to to check the evolution of the cancellation by ether processing the tax report web hook on your system, or pooling the state of the tax report by calling the get tax report endpoint until the state field of the tax report is error or annulled.

Correct a Tax Report

The Zuzendu service is currently not suported by B2Brouter's Tax Report API.

List Tax Reports

To list your tax reports use the GET verb in list tax reports endpoint.

Equivalence between B2Brouter internal tax report fields and TicketBAI XML nodes

The structure of the JSON format for B2Brouter tax reports is based on PEPPOL Continuous Transaction Control (CTC). That means that the fields used in the JSON payload have not the same name as in the XML representation of a TicketBAI tax report. The reason behind this design decision is that B2Brouter Tax Report API is an universal API not only geared towards TicketBAI but designed to handle tax reporting around the World.

This is a table with the equivalence between the internal B2Brouter representation of a tax report and the TicketBAI fields used in the XML that is sent to the Tax Authority.

B2Brouter Field (based on PEPPOL CTC)TicketBAI XML Node
supplier_party_tax_idSujetos > Emisor > NIF
supplier_party_nameSujetos > Emisor > ApellidosNombreRazonSocial
customer_party_tax_id (if customer_party_tax_scheme is nil)Sujetos > Destinatarios > IDDestinatario > NIF
customer_party_countrySujetos > Destinatarios > IDDestinatario > IDOtro > CodigoPais
customer_party_tax_schemeSujetos > Destinatarios > IDDestinatario > IDOtro > IDType
customer_party_tax_id (if customer_party_tax_scheme is present)Sujetos > Destinatarios > IDDestinatario > IDOtro > ID
customer_party_nameSujetos > Destinatarios > IDDestinatario > ApellidosNombreRazonSocial
customer_party_postalcodeSujetos > Destinatarios > IDDestinatario > CodigoPostal
customer_party_addressSujetos > Destinatarios > IDDestinatario > Direccion
invoice_series_codeFactura > CabeceraFactura > SerieFactura
invoice_numberFactura > CabeceraFactura > NumFactura
invoice_dateFactura > CabeceraFactura > FechaExpedicionFactura
ticketFactura > CabeceraFactura > FacturaSimplificada
is_amendFactura > CabeceraFactura > FacturaRectificativa
invoice_type_code (if is_amend)Factura > CabeceraFactura > FacturaRectificativa > Codigo
amended_series_codeFactura > CabeceraFactura > FacturasRectificadasSustituidas > IDFacturaRectificadaSustituida > SerieFactura
amended_numberFactura > CabeceraFactura > FacturasRectificadasSustituidas > IDFacturaRectificadaSustituida > NumFactura
amended_dateFactura > CabeceraFactura > FacturasRectificadasSustituidas > IDFacturaRectificadaSustituida > FechaExpedicionFactura
tax_point_dateFactura > DatosFactura > FechaOperacion
descriptionFactura > DatosFactura > DescripcionFactura
tax_report_lines[].descriptionFactura > DatosFactura > DetallesFactura > IDDetalleFactura > DescripcionDetalle
tax_report_lines[].quantityFactura > DatosFactura > DetallesFactura > IDDetalleFactura > Cantidad
tax_report_lines[].priceFactura > DatosFactura > DetallesFactura > IDDetalleFactura > ImporteUnitario
tax_report_lines[].discount_amountFactura > DatosFactura > DetallesFactura > IDDetalleFactura > Descuento
tax_report_lines[].tax_inclusive_amountFactura > DatosFactura > DetallesFactura > IDDetalleFactura > ImporteTotal
tax_inclusive_amountFactura > DatosFactura > ImporteTotalFactura
tax_amount_withheldFactura > DatosFactura > RetencionSoportada
special_regime_keyFactura > DatosFactura > Claves > IDClave > ClaveRegimenIvaOpTrascendencia
special_regime_key_additionalFactura > DatosFactura > Claves > IDClave > ClaveRegimenIvaOpTrascendencia (second occurrence)
tax_breakdowns[].exemptFactura > TipoDesglose > DesgloseFactura > Sujeta > Exenta
tax_breakdowns[].exemption_codeFactura > TipoDesglose > DesgloseFactura > Sujeta > Exenta > DetalleExenta > CausaExencion
tax_breakdowns[].taxable_base (exempt)Factura > TipoDesglose > DesgloseFactura > Sujeta > Exenta > DetalleExenta > BaseImponible
tax_breakdowns[].non_exemptFactura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta
tax_breakdowns[].non_exemption_codeFactura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > TipoNoExenta
tax_breakdowns[].taxable_base (non-exempt)Factura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > DesgloseIVA > DetalleIVA > BaseImponible
tax_breakdowns[].percentFactura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > DesgloseIVA > DetalleIVA > TipoImpositivo
tax_breakdowns[].tax_amountFactura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > DesgloseIVA > DetalleIVA > CuotaImpuesto
tax_breakdowns[].percent (RE)Factura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > DesgloseIVA > DetalleIVA > TipoRecargoEquivalencia
tax_breakdowns[].tax_amount (RE)Factura > TipoDesglose > DesgloseFactura > Sujeta > NoExenta > DetalleNoExenta > DesgloseIVA > DetalleIVA > CuotaRecargoEquivalencia
tax_breakdowns[].no_subjectFactura > TipoDesglose > DesgloseFactura > NoSujeta
tax_breakdowns[].no_subject_codeFactura > TipoDesglose > DesgloseFactura > NoSujeta > DetalleNoSujeta > Causa
tax_breakdowns[].taxable_base (no-subject)Factura > TipoDesglose > DesgloseFactura > NoSujeta > DetalleNoSujeta > Importe
type_operationUsed to determine DesgloseTipoOperacion structure

XSD files

TicketBAI schemas provided by the Basque Tax Authorities.

| XSD file | Description |
|-------------------------------------|-----------------------------------------------------------------------------------------------|
| ticketbaiv1-2-2.xsd | Esquema principal de TicketBAI |
| anula_ticketbaiv1-2-2.xsd | Esquema para el suministro de facturas |

Code descriptions for specific fields

Invoice type codes

Type of invoice codes.
Param: invoice_type_code

CodeDescription
F1Factura (art. 6, 7.2 y 7.3 del RD 1619/2012)
F2Factura Simplificada y Facturas sin identificación del destinatario (art. 6.1.d) RD 1619/2012
F3Factura emitida en sustitución de facturas simplificadas facturadas y declaradas
R1Factura Rectificativa (Error fundado en derecho y Art. 80 Uno Dos y Seis LIVA)
R2Factura Rectificativa (Art. 80.3)
R3Factura Rectificativa (Art. 80.4)
R4Factura Rectificativa (Resto)
R5Factura Rectificativa en facturas simplificadas

Special regime key codes

Description of each tax regime code for breakdowns subject to IVA.
If not provided the default set in TaxReportSettingins will be used.
Param: special_regime_key

CodeDescription
01Operación de régimen general.
02Exportación.
03Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección.
04Régimen especial del oro de inversión.
05Régimen especial de las agencias de viajes.
06Régimen especial grupo de entidades en IVA (Nivel Avanzado)
07Régimen especial del criterio de caja.
08Operaciones sujetas al IPSI / IGIC (Impuesto sobre la Producción, los Servicios y la Importación / Impuesto General Indirecto Canario).
09Facturación de las prestaciones de servicios de agencias de viaje que actúan como mediadoras en nombre y por cuenta ajena (D.A.4ª RD1619/2012)
10Cobros por cuenta de terceros de honorarios profesionales o de derechos derivados de la propiedad industrial, de autor u otros por cuenta de sus socios, asociados o colegiados efectuados por sociedades, asociaciones, colegios profesionales u otras entidades que realicen estas funciones de cobro.
11Operaciones de arrendamiento de local de negocio.
12Operaciones de arrendamiento de local de negocio no sujetos a retención.
13Operaciones de arrendamiento de local de negocio sujetas y no sujetas a retención.
14Factura con IVA pendiente de devengo en certificaciones de obra cuyo destinatario sea una Administración Pública.
15Factura con IVA pendiente de devengo en operaciones de tracto sucesivo.
17Operación acogida a alguno de los regímenes previstos en el Capítulo XI del Título IX (OSS e IOSS)
19Operaciones de actividades incluidas en el Régimen Especial de Agricultura, Ganadería y Pesca (REAGYP)
51Operaciones en recargo de equivalencia.
52Operaciones en régimen simplificado.
53Operaciones realizadas por personas o entidades que no tengan la consideración de empresarios o profesionales a efectos del IVA.
54Operaciones realizadas desde Establecimientos Permanentes situados en Canarias, Ceuta y Melilla.

Non exemption codes

Reason codes for taxable status.
If not provided the default set in TaxReportSettingins will be used.
Param: non_exemption_code

CodeDescription
S1Operación Sujeta y No exenta - Sin inversión del sujeto pasivo.
S2Operación Sujeta y No exenta - Con Inversión del sujeto pasivo.

Non subject codes

Reason codes for non taxable status.
If not provided the default set in TaxReportSettingins will be used.
Param: no_subject_code

CodeDescription
OTNo sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no sujeción.
RLNo sujeto por reglas de localización.
VTNo sujeto, ventas realizadas por cuenta de terceros (importe no computable a efectos de IVA ni de IRPF).
IENo sujeto en el TAI por reglas de localización, pero repercute impuesto extranjero, IPS/IGIC o IVA de otro estado miembro UE.

Exemption codes

Reason codes for IVA Exemption.
If not provided the default set in TaxReportSettingins will be used.
Param: exemption_code

CodeDescription
E1Exenta por el artículo 20
E2Exenta por el artículo 21
E3Exenta por el artículo 22
E4Exenta por los artículos 23 y 24
E5Exenta por el artículo 25
E6Exenta por otros