Ejemplos de la API
Peticiones listas para copiar, de la más sencilla a los casos fiscales menos habituales. El mismo JSON sirve para TicketBAI (Araba, Bizkaia y Gipuzkoa) y para Verifactu: la API aplica las diferencias de cada sistema según el NIF emisor.
https://api-test.ticketbaiws.eus con las cabeceras Token (tu token de test) y Nif (el NIF emisor). Los importes de las líneas van sin IVA.
¿Quieres probarlos sin cuenta? Ábrelos en el terminal de pruebas.
Factura simplificada (ticket)
El caso más habitual en TPV y comercio electrónico: venta a un consumidor final sin datos del cliente. Con simplificada: true no hace falta enviar NIF, nombre ni dirección.
Los importes de las líneas van sin IVA. Puedes enviar hasta 4 decimales en importe_unitario para que el total con IVA cuadre al céntimo.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "T2026",
"numero": "1024",
"simplificada": true,
"lineas": [
{
"descripcion": "Café con leche",
"cantidad": 2,
"importe_unitario": 1.3636,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Pintxo de tortilla",
"cantidad": 1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": 6.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-AwEuY60NNrUch-187",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-AwEuY60NNrUch-187&s=T2026&nf=1024&i=6&cr=255"
},
"msg": null
}Factura completa a una empresa
Factura ordinaria con los datos del destinatario. En Araba y Gipuzkoa la dirección y el código postal son obligatorios; en Bizkaia y Verifactu basta con NIF y nombre, pero te recomendamos enviarlos siempre.
fecha_operacion es opcional: úsala cuando el servicio o la entrega se hicieron en una fecha distinta a la de emisión (nunca posterior).
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"fecha_operacion": "31/10/2026",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-FXDupidVrH0Ro-097",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-FXDupidVrH0Ro-097&s=A2026&nf=000153&i=308.55&cr=028"
},
"msg": null
}Varios tipos de IVA y descuentos
Cada línea lleva su tipo de IVA y la API agrupa las bases por tipo en el desglose. descuento es un porcentaje sobre la línea.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000154",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Auriculares",
"cantidad": 1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
},
{
"descripcion": "Caja de galletas",
"cantidad": 4,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Libro de texto",
"cantidad": 2,
"importe_unitario": 19.2308,
"tipo_iva": 4,
"tipo_req": 0
}
],
"total_factura": 106.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-TozgSJYApu614-042",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-TozgSJYApu614-042&s=A2026&nf=000154&i=106&cr=049"
},
"msg": null
}Venta de bienes a empresa de la UE
Entrega intracomunitaria exenta: el cliente tiene NIF-IVA válido en otro país de la UE. Marca intracomunitaria: true, indica el país en pais_cliente y envía las líneas con IVA 0.
Comprueba antes el NIF del cliente en el VIES (tienes el endpoint POST de validación VIES en la API). tipo_documento por defecto es 02 (NIF-IVA) para clientes de la UE.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "512345678",
"tipo_documento": "02",
"nombre": "Exemplo Comércio, Lda",
"direccion": "Rua das Flores 25",
"cp": "4050-262",
"pais_cliente": "PT",
"serie": "A2026",
"numero": "000155",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Pinza ER32 Ø21",
"cantidad": 10,
"importe_unitario": 15,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 150.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-MOEpzspQu+/T4-017",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-MOEpzspQu%2B%2FT4-017&s=A2026&nf=000155&i=150&cr=200"
},
"msg": null
}Servicios a empresa de la UE
Prestación de servicios B2B a una empresa de otro país de la UE: la operación no está sujeta al IVA español y la autoliquida el cliente. Igual que en bienes, pero con tipo_operacion: "servicios"; la API la declara como no sujeta por reglas de localización.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "FR12345678901",
"tipo_documento": "02",
"nombre": "Exemple Conseil SARL",
"direccion": "10 Rue de la Paix",
"cp": "75002",
"pais_cliente": "FR",
"serie": "A2026",
"numero": "000156",
"simplificada": false,
"rectificativa": false,
"intracomunitaria": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Consultoría — septiembre",
"cantidad": 1,
"importe_unitario": 1800,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 1800.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-x3c4Ml2OxShyU-141",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-x3c4Ml2OxShyU-141&s=A2026&nf=000156&i=1800&cr=093"
},
"msg": null
}Venta a distancia a particular de la UE (OSS)
Si superas el umbral de 10.000 € anuales de ventas a distancia en la UE, cobras el IVA del país del comprador y lo declaras en la ventanilla única (OSS). Envía regimen_iva: 17, el país de destino en pais_cliente y el tipo de IVA de ese país en las líneas. La API añade la causa IE (impuesto extranjero) automáticamente.
Usa el país de entrega, no el de facturación: es el que determina la tributación.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "W2026",
"numero": "8812",
"simplificada": true,
"pais_cliente": "PT",
"regimen_iva": 17,
"tipo_operacion": "bienes",
"lineas": [
{
"descripcion": "Zapatillas trail T42",
"cantidad": 1,
"importe_unitario": 89.4309,
"tipo_iva": 23,
"tipo_req": 0
}
],
"total_factura": 110.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-Ir1Hq7Kbb6Qlb-202",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-Ir1Hq7Kbb6Qlb-202&s=W2026&nf=8812&i=110&cr=125"
},
"msg": null
}Exportación de bienes fuera de la UE
Mercancía que sale de la UE: exenta por el artículo 21 (causa_exencion: "E2"). Marca exportacion: true. Para un documento de identificación que no es NIF-IVA, usa tipo_documento: "06" (por defecto fuera de la UE).
Si en la venta se ha cobrado IVA español (por ejemplo, el cliente recoge en tienda), no es una exportación: envíala como factura nacional.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "93-1995874",
"tipo_documento": "06",
"nombre": "Example Bearings Inc.",
"direccion": "16 Main Street, Unit 500",
"cp": "01862",
"pais_cliente": "US",
"serie": "A2026",
"numero": "000157",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"causa_exencion": "E2",
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Rodamiento HC7016",
"cantidad": 10,
"importe_unitario": 442.99,
"tipo_iva": 0,
"tipo_req": 0
},
{
"descripcion": "Portes",
"cantidad": 1,
"importe_unitario": 135,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 4564.9
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-WytYrI2ZEd9MT-197",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-WytYrI2ZEd9MT-197&s=A2026&nf=000157&i=4564.9&cr=038"
},
"msg": null
}Servicios a empresa de fuera de la UE
Servicios B2B a una empresa establecida fuera de la UE (por ejemplo, Reino Unido): no sujetos al IVA español. Se envían con exportacion: true y tipo_operacion: "servicios".
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "GB123456789",
"tipo_documento": "06",
"nombre": "Example Clinical Ltd",
"direccion": "100 Long Avenue, Reading",
"cp": "RG2 6GP",
"pais_cliente": "GB",
"serie": "A2026",
"numero": "000158",
"simplificada": false,
"rectificativa": false,
"exportacion": true,
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Estudio clínico — fase 2, centro 246",
"cantidad": 1,
"importe_unitario": 8764.78,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 8764.78
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-Ht+pDMFpkdvzq-030",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-Ht%2BpDMFpkdvzq-030&s=A2026&nf=000158&i=8764.78&cr=180"
},
"msg": null
}Operación exenta (art. 20)
Servicios exentos de IVA a clientes en España: sanidad, enseñanza, seguros… Envía causa_exencion: "E1" y las líneas a IVA 0. No marques exportacion: es una operación nacional.
Causas disponibles: E1 a E6, OT, RL, IE y VT. Si no indicas ninguna en una línea a IVA 0, la API la determina.
En Verifactu la causa de exención la calcula la API a partir del resto de datos; no hace falta enviarla.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Ane Etxeberria Garai",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "C2026",
"numero": "0071",
"simplificada": false,
"rectificativa": false,
"exportacion": false,
"regimen_iva": "01",
"causa_exencion": "E1",
"tipo_operacion": "servicios",
"retencion": 0,
"lineas": [
{
"descripcion": "Sesión de fisioterapia",
"cantidad": 4,
"importe_unitario": 45,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 180.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-yKRli0KZPxRyO-114",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-yKRli0KZPxRyO-114&s=C2026&nf=0071&i=180&cr=004"
},
"msg": null
}Venta a un comercio con recargo de equivalencia
Cuando vendes a un minorista acogido al recargo de equivalencia, repercutes además el recargo. Va por línea en tipo_req: 5,2 % con IVA 21, 1,4 % con IVA 10 y 0,5 % con IVA 4.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "12345678Z",
"nombre": "Mikel Lasa Ugarte (Ferretería Lasa)",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000159",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "bienes",
"retencion": 0,
"lineas": [
{
"descripcion": "Taladro percutor",
"cantidad": 2,
"importe_unitario": 64.9,
"tipo_iva": 21,
"tipo_req": 5.2
},
{
"descripcion": "Bolsa de pienso 3 kg",
"cantidad": 6,
"importe_unitario": 8.5,
"tipo_iva": 10,
"tipo_req": 1.4
}
],
"total_factura": 220.62
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-KAl1Xy6lGfYEw-008",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-KAl1Xy6lGfYEw-008&s=A2026&nf=000159&i=220.62&cr=199"
},
"msg": null
}Emisor en recargo de equivalencia
Si tú eres el comercio minorista en recargo de equivalencia, marca modo_recargo_equivalencia: true. Si alguna línea va en régimen general (por ejemplo, un servicio), márcala con regimen_general: true.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "243",
"simplificada": true,
"modo_recargo_equivalencia": true,
"lineas": [
{
"descripcion": "Batido de vainilla 780 g",
"cantidad": 4,
"importe_unitario": 44.4545,
"tipo_iva": 10,
"tipo_req": 0
},
{
"descripcion": "Asesoramiento nutricional",
"cantidad": 1,
"importe_unitario": 20,
"tipo_iva": 21,
"tipo_req": 0,
"regimen_general": true
}
],
"total_factura": 219.8
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-WwZLeL0SWJXAt-203",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-WwZLeL0SWJXAt-203&s=BS2026&nf=243&i=219.8&cr=195"
},
"msg": null
}Inversión del sujeto pasivo
Operaciones en las que el IVA lo autoliquida el cliente (ejecuciones de obra, chatarra, oro de inversión…). Marca inversion_sujeto_pasivo: true y envía las líneas a IVA 0.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000160",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"inversion_sujeto_pasivo": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Rehabilitación de fachada — certificación 2",
"cantidad": 1,
"importe_unitario": 12500,
"tipo_iva": 0,
"tipo_req": 0
}
],
"total_factura": 12500.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-v5iayi+3jljzw-171",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-v5iayi%2B3jljzw-171&s=A2026&nf=000160&i=12500&cr=237"
},
"msg": null
}Profesional con retención de IRPF
retencion es el importe retenido en euros (no el porcentaje): aquí, el 15 % de 850 €. total_factura es base + IVA, sin restar la retención: así lo exige el registro de Hacienda. El líquido a pagar (base + IVA − retención) es cosa de tu factura en PDF.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "P2026",
"numero": "042",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"retencion": 127.5,
"lineas": [
{
"descripcion": "Dirección de obra",
"cantidad": 1,
"importe_unitario": 850.0,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 1028.5
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-fudnOFfRlaSlT-070",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-fudnOFfRlaSlT-070&s=P2026&nf=042&i=1028.5&cr=153"
},
"msg": null
}Factura emitida por un tercero o por el destinatario
Si la factura la expide una gestoría o plataforma en tu nombre, usa emitida_terceros: "T". Si la emite el propio cliente (autofacturación), usa "D". Por defecto es "N".
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "T2026",
"numero": "0005",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"emitida_terceros": "T",
"retencion": 0,
"lineas": [
{
"descripcion": "Comisión de venta — octubre",
"cantidad": 1,
"importe_unitario": 310,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 375.1
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-oUX3+gSWR/ELZ-012",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-oUX3%2BgSWR%2FELZ-012&s=T2026&nf=0005&i=375.1&cr=072"
},
"msg": null
}Persona física en Bizkaia con varios epígrafes
En Batuz (LROE modelo 140), una persona física con varias actividades indica en cada factura a qué epígrafe corresponde. Si no lo envías, se usa el de la ficha de la empresa. También puedes indicarlo por línea con epigrafe dentro de cada línea.
Consulta los códigos con el endpoint de listado de epígrafes de Bizkaia.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "BS2026",
"numero": "244",
"simplificada": true,
"epigrafe": "165240",
"lineas": [
{
"descripcion": "Clase de yoga — bono 5 sesiones",
"cantidad": 1,
"importe_unitario": 41.3223,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 50.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-8eVWhrhWQFbDK-196",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-8eVWhrhWQFbDK-196&s=BS2026&nf=244&i=50&cr=048"
},
"msg": null
}Abono o rectificativa por diferencias
Devolución parcial o total: envías solo la diferencia, en negativo. tipo_rectificativa: "I" (por diferencias, valor por defecto) y clave_rectificativa: "R1" (error fundado en derecho o devolución; por defecto). En rectificadas va la factura original.
Si la original se emitió con Ticketbai WS, basta con serie, número y fecha: la API recupera el resto.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0031",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000154",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: auriculares",
"cantidad": -1,
"importe_unitario": 49.5868,
"tipo_iva": 21,
"tipo_req": 0,
"descuento": 10
}
],
"total_factura": -54.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-TElBuC/qKDRRg-093",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-TElBuC%2FqKDRRg-093&s=R2026&nf=0031&i=-54&cr=230"
},
"msg": null
}Rectificativa por sustitución
Sustituye por completo la factura original: las líneas son las correctas, no la diferencia. tipo_rectificativa: "S". La API informa además del importe de la original (bloque ImporteRectificacionSustitutiva); si no quieres que lo haga, usa "SN".
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0032",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "S",
"tipo_operacion": "servicios",
"retencion": 0,
"rectificadas": [
{
"serie": "A2026",
"numero": "000153",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 2,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 254.1
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-dp/cLRcyY+JiD-057",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-dp%2FcLRcyY%2BJiD-057&s=R2026&nf=0032&i=254.1&cr=055"
},
"msg": null
}Devolución de un ticket (R5)
Para rectificar una factura simplificada se usa la clave R5, y la rectificativa también es simplificada.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"serie": "TR2026",
"numero": "0012",
"simplificada": true,
"rectificativa": true,
"clave_rectificativa": "R5",
"tipo_rectificativa": "I",
"rectificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
}
],
"lineas": [
{
"descripcion": "Devolución: pintxo de tortilla",
"cantidad": -1,
"importe_unitario": 2.7273,
"tipo_iva": 10,
"tipo_req": 0
}
],
"total_factura": -3.0
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-StrSWgmqdi8Uq-219",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-StrSWgmqdi8Uq-219&s=TR2026&nf=0012&i=-3&cr=140"
},
"msg": null
}Rectificar una factura emitida con otro programa
Si la factura original no se envió a través de Ticketbai WS (por ejemplo, la emitiste antes de cambiar de software), indica también su base, cuota y recargo en rectificadas.
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "R2026",
"numero": "0033",
"simplificada": false,
"rectificativa": true,
"clave_rectificativa": "R1",
"tipo_rectificativa": "I",
"tipo_operacion": "bienes",
"retencion": 0,
"rectificadas": [
{
"serie": "SS",
"numero": "800255",
"fecha": "15/09/2026",
"base": 593.96,
"cuota": 124.73,
"recargo": 0
}
],
"lineas": [
{
"descripcion": "Abono: 5 uds. ref. 16ER-AG60",
"cantidad": -5,
"importe_unitario": 28.38,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": -171.7
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-WePvoiTs8pO1s-017",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-WePvoiTs8pO1s-017&s=R2026&nf=0033&i=-171.7&cr=030"
},
"msg": null
}Subsanar una factura rechazada (Zuzendu)
Si Hacienda rechazó una factura o la registró con datos erróneos que no cambian serie, número ni importe total (NIF o nombre del cliente, causa de exención…), reenvíala con los datos corregidos y zuzendu: true.
En Bizkaia también funciona con zuzendu: true para las facturas que Batuz rechazó. Batuz no tiene Zuzendu propiamente dicho: la API envía la corrección por el subcapítulo 1.2 del LROE y conserva el identificador TBAI, la huella y el QR de la factura que entregaste. Si vuelves a corregirla, se envía como modificación del mismo registro. Si la factura fue aceptada y hay que cambiar sus datos, emite una rectificativa.
Si envías una factura que ya existe con datos distintos sin zuzendu, la API responde OK con la huella ya registrada y te avisa en msg: "Previously sent with different values… Set zuzendu to true in case you want to change it".
{
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "31/10/2026",
"hora": "10:30:00",
"nif": "B87654323",
"nombre": "Nombre Corregido S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"serie": "A2026",
"numero": "000153",
"simplificada": false,
"rectificativa": false,
"tipo_operacion": "servicios",
"zuzendu": true,
"retencion": 0,
"lineas": [
{
"descripcion": "Mantenimiento web — octubre",
"cantidad": 1,
"importe_unitario": 120,
"tipo_iva": 21,
"tipo_req": 0
},
{
"descripcion": "Horas de soporte",
"cantidad": 3,
"importe_unitario": 45,
"tipo_iva": 21,
"tipo_req": 0
}
],
"total_factura": 308.55
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-311026-Hw2pWJm9amS1R-088",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-311026-Hw2pWJm9amS1R-088&s=A2026&nf=000153&i=308.55&cr=123"
},
"msg": null
}Convertir tickets en factura completa
El cliente pide factura de uno o varios tickets ya emitidos. Envía sus datos y la lista de simplificadas en simplificadas; la API genera la factura completa con las líneas de los tickets (factura en sustitución de simplificadas).
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
} curl -X POST 'https://api-test.ticketbaiws.eus/tbai-completar/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
}
JSON <?php
$json = <<<'JSON'
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai-completar/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
}
""")
r = requests.request(
"POST",
"https://api-test.ticketbaiws.eus/tbai-completar/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai-completar/", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"fecha": "01/11/2026",
"hora": "10:30:00",
"nif": "B12345674",
"nombre": "Cliente Ejemplo S.L.",
"direccion": "Calle Mayor 1",
"cp": "01001",
"pais_cliente": "ES",
"simplificada": false,
"serie": "F2026",
"numero": "0088",
"zuzendu": false,
"simplificadas": [
{
"serie": "T2026",
"numero": "1024",
"fecha": "31/10/2026"
},
{
"serie": "T2026",
"numero": "1031",
"fecha": "31/10/2026"
}
]
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("POST"), "https://api-test.ticketbaiws.eus/tbai-completar/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-I495Nd6GC/RZo-088",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-I495Nd6GC%2FRZo-088&s=F2026&nf=0088&i=0&cr=131"
},
"msg": null
}Anular una factura
Anula una factura emitida por error (por ejemplo, duplicada o enviada a un cliente equivocado). Solo necesitas serie y número. Si la operación existió y hay que devolver dinero, no anules: emite una rectificativa.
La respuesta incluye la huella del registro de anulación.
{
"serie": "A2026",
"numero": "000160"
} curl -X DELETE 'https://api-test.ticketbaiws.eus/tbai/' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Token: TU_TOKEN_DE_TEST' \
-H 'Nif: B89670855' \
--data-binary @- <<'JSON'
{
"serie": "A2026",
"numero": "000160"
}
JSON <?php
$json = <<<'JSON'
{
"serie": "A2026",
"numero": "000160"
}
JSON;
$ch = curl_init('https://api-test.ticketbaiws.eus/tbai/');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'Token: TU_TOKEN_DE_TEST',
'Nif: B89670855',
],
]);
$respuesta = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($respuesta['result'] === 'ERROR') {
throw new RuntimeException($respuesta['msg']);
}
// $respuesta['return']['qr'] es el PNG del QR en base64 para imprimir en la factura
import json
import requests
datos = json.loads(r"""
{
"serie": "A2026",
"numero": "000160"
}
""")
r = requests.request(
"DELETE",
"https://api-test.ticketbaiws.eus/tbai/",
headers={"Token": "TU_TOKEN_DE_TEST", "Nif": "B89670855", "Accept": "application/json"},
json=datos,
timeout=30,
)
respuesta = r.json()
if respuesta["result"] == "ERROR":
raise Exception(respuesta["msg"])
print(respuesta["return"])
const datos = {
"serie": "A2026",
"numero": "000160"
};
const r = await fetch("https://api-test.ticketbaiws.eus/tbai/", {
method: "DELETE",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Token": "TU_TOKEN_DE_TEST",
"Nif": "B89670855",
},
body: JSON.stringify(datos),
});
const respuesta = await r.json();
if (respuesta.result === "ERROR") throw new Error(respuesta.msg);
console.log(respuesta.return);
using System.Net.Http;
using System.Text;
var json = """
{
"serie": "A2026",
"numero": "000160"
}
""";
using var http = new HttpClient();
var peticion = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api-test.ticketbaiws.eus/tbai/")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
peticion.Headers.Add("Token", "TU_TOKEN_DE_TEST");
peticion.Headers.Add("Nif", "B89670855");
var respuesta = await http.SendAsync(peticion);
Console.WriteLine(await respuesta.Content.ReadAsStringAsync());
Respuesta de ejemplo
{
"result": "OK",
"return": {
"huella_tbai": "TBAI-B89670855-011126-YmMgkIPqt6WQ5-093",
"qr": "iVBORw0KGgo… (PNG en base64)",
"url": "https://batuz.eus/QRTBAI/?id=TBAI-B89670855-011126-YmMgkIPqt6WQ5-093&s=A2026&nf=000160&i=0&cr=188"
},
"msg": null
}Cómo leer la respuesta
- La API responde siempre con HTTP 200. Mira el campo
result:OK,PENDING(Verifactu en cola) oERROR. - En TicketBAI,
return.huella_tbaies el identificador TBAI que va impreso en la factura. En Verifactu recibesreturn.huella(SHA-256 encadenado). return.qres el código QR en PNG (base64), listo para imprimir.return.urles la URL de cotejo que contiene.- Si hay avisos de Hacienda en una factura aceptada, llegan en
msg. ConERROR,msgtrae los motivos separados por;. - El envío a Hacienda se hace en segundo plano. Para enterarte de un rechazo posterior, da de alta un webhook (puedes pedir que solo avise de errores con
solo_errores).
