Guía rápida de integración
De cero a facturar en producción en siete pasos. Las pruebas son gratuitas y no necesitas certificado digital en tu servidor: Ticketbai WS firma y envía las facturas por ti.
-
Crea tu cuenta y consigue tus tokens
Regístrate gratis y da de alta tu empresa (o la de tu cliente). En el área privada de cada empresa tienes dos tokens:
- Token de test, para
https://api-test.ticketbaiws.eus. Las facturas van a los entornos de pruebas de Hacienda y no tienen validez fiscal. - Token real, para
https://api.ticketbaiws.eus. Se activa al contratar la licencia.
Cada petición lleva dos cabeceras:
TokenyNif(el NIF de la empresa emisora). Con el NIF, la API sabe a qué Hacienda enviar: Araba, Bizkaia, Gipuzkoa o la AEAT (Verifactu).
Área privada → API → Tokens: el NIF de la empresa y sus tokens de producción y de test, con un botón para copiarlos. Desde aquí también tienes la colección de Postman y el Swagger. Si gestionas muchas empresas (gestorías, fabricantes de software), puedes darlas de alta por API con los endpoints de Empresas y Licencias.
- Token de test, para
-
Envía tu primera factura de prueba
Una factura simplificada (un ticket) es lo más sencillo: no lleva datos del cliente. Sustituye el token y el NIF por los tuyos:
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 facturaimport 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());{ "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 }La respuesta llega en milisegundos, con el identificador TBAI, el QR en PNG (base64) y la URL de cotejo:
{ "result": "OK", "return": { "huella_tbai": "TBAI-B89670855-011126-AwEuY60NNrUch-187", "qr": "iVBORw0KGgo… (PNG en base64)", "url": "https://tbai.egoitza.gipuzkoa.eus/qr/?id=TBAI-B89670855-011126-AwEuY60NNrUch-187&s=T2026&nf=1024&i=6&cr=242" }, "msg": null }Imprime en la factura el QR y el identificador TBAI (en Verifactu, el QR y la leyenda «VERI*FACTU»). Es obligatorio.
¿Sin cuenta todavía? Prueba esta misma petición en el terminal de pruebas.
-
Comprueba que Hacienda la ha aceptado
Por defecto la API responde al momento y envía la factura a Hacienda en segundo plano, con reintentos automáticos si Hacienda no responde. Para saber el resultado final tienes tres opciones:
- Webhooks (recomendado): te avisamos cuando una factura pasa de pendiente a OK o a ERROR. Si solo te interesan los problemas, créalo con
solo_errores. - Consulta:
GET /tbai/con serie y número devuelve el estado y la respuesta de Hacienda. - Panel: el log de envíos del área privada muestra cada envío, el XML generado y la respuesta de la diputación.
Si prefieres esperar a Hacienda en la propia petición, añade
"sincrono": true. En Verifactu, sin ese parámetro la respuesta esPENDING.
Área privada → API → LOG TBAI: cada envío a Hacienda con su entorno, su origen, el estado y el tiempo de respuesta. Los iconos abren la petición, la respuesta de Hacienda y el JSON recibido. 
Respuesta de Hacienda a una factura aceptada: estado 00 (Recibido), el identificador TBAI y el CSV. - Webhooks (recomendado): te avisamos cuando una factura pasa de pendiente a OK o a ERROR. Si solo te interesan los problemas, créalo con
-
Prueba los casos de tu negocio
Antes de pasar a producción, envía al entorno de test las facturas que vas a emitir de verdad: con y sin cliente, rectificativas, devoluciones, clientes extranjeros, operaciones exentas… En la página de ejemplos tienes el JSON de cada caso.
Recuerda:
- La API devuelve HTTP 200 también en los errores: comprueba siempre
result(OK,PENDINGoERROR) y muestramsgal usuario. - La numeración debe ser correlativa dentro de cada serie, y la fecha y hora las de emisión real.
- Cada territorio tiene un plazo de envío: Araba admite facturas de las últimas 24 horas, Gipuzkoa de los últimos 7 días y Bizkaia hasta el día 25 del mes siguiente al trimestre (31 de enero para el cuarto).
- Para corregir una factura ya enviada no la vuelvas a mandar: usa una rectificativa, una subsanación (
zuzendu) o una anulación, según el caso.
- La API devuelve HTTP 200 también en los errores: comprueba siempre
-
Autoriza a Ticketbai WS ante tu Hacienda
Para enviar en producción en tu nombre, tu Hacienda tiene que saber que lo hacemos con tu permiso. Depende del territorio:
TICKETBAIAraba
Registra el certificado de dispositivo de Ticketbai WS en la sede de la Diputación Foral de Álava. Te guiamos paso a paso desde el área privada.
BATUZBizkaia
Firma el documento de representación que te facilitamos. No necesitas adjuntar copia del DNI.
TICKETBAIGipuzkoa
Berein es colaborador social de la Diputación Foral de Gipuzkoa: no tienes que registrar ningún certificado.
AEATVerifactu
Firma el documento de representación. Puedes descargarlo y subirlo firmado desde el área privada o por API (endpoints Documento de representación).

Área privada → Configuración → Certificado Digital (ejemplo de Verifactu): rellena los datos del representante, descarga el modelo, fírmalo digitalmente y súbelo. También puedes cargar tu propio certificado. -
Contrata la licencia y pasa a producción
Elige el plan que encaje con tu volumen. Para pasar a producción solo cambian dos cosas:
Pruebas Producción URL base https://api-test.ticketbaiws.eushttps://api.ticketbaiws.eusCabecera TokenToken de test Token real El formato de las peticiones y de las respuestas es el mismo. Guárdalos en la configuración de tu aplicación para cambiar de entorno sin tocar el código.
¿Eres revendedor o integras a varios clientes? Escríbenos para condiciones de partner.
-
Antes de la primera factura real
- Guarda en tu base de datos la huella, la URL y el QR de cada factura: los necesitarás para reimprimirla.
- Da de alta un webhook en producción para enterarte de cualquier rechazo.
- Si tu TPV puede quedarse sin conexión, prepara el caso: la factura se envía en cuanto vuelve la conexión, respetando el plazo del territorio.
- Consulta el estado del servicio si notas lentitud: muestra en tiempo real cómo responden nuestra API y cada Hacienda.
