Inicio rápido de España
Este inicio rápido te guía para firmar tu primera factura conforme con fiskaly SIGN ES, cubriendo tanto TicketBAI (País Vasco) como Verifactu (resto de España).
Antes de comenzar
Sección titulada «Antes de comenzar»SIGN ES es la API de fiskaly solo software, independiente de la plataforma para el cumplimiento fiscal español. Cubre Verifactu y SII en la mayor parte de España, TicketBAI en el País Vasco y NaTicket en Navarra (próximamente) — todo a través de una única API REST.
Verifactu
Regulación nacional para la mayor parte de España bajo la Ley Antifraude, Real Decreto 1007/2023 y Orden HAC/1177/2024.
TicketBAI
Marco de fiscalización del País Vasco para Álava, Bizkaia y Gipuzkoa.
SII
Declaración electrónica del IVA a la AEAT para grandes contribuyentes en España peninsular. Incompatible con Verifactu.
NaTicket
Sistema de control de facturas de Navarra, anunciado en septiembre de 2025. Previsto para 2026–2027.
Flujo API en tiempo real
SIGN ES genera el XML de la factura, lo firma, lo encadena y lo transmite a la autoridad fiscal correspondiente.
| Regulación | Se aplica a | Salida principal |
|---|---|---|
| Verifactu | Mayor parte de España, excluido País Vasco y actualmente Navarra | XML firmado, transmisión AEAT en tiempo real, frase Verifactu y código QR |
| TicketBAI | Álava, Bizkaia, Gipuzkoa | XML firmado, transmisión a autoridad fiscal regional, ID TicketBAI y código QR |
| SII | España peninsular (grandes contribuyentes de IVA) | Registros de IVA electrónicos enviados a la AEAT en 4 días; sin código QR |
| NaTicket | Navarra (próximamente, ~2026–2027) | Previsto: XML firmado transmitido a la Hacienda Foral de Navarra |
Consulta la Introducción para obtener el contexto completo de Verifactu, TicketBAI, BATUZ y LROE antes de comenzar los pasos de integración.
Requisitos previos
Sección titulada «Requisitos previos»- Una cuenta de fiskaly con una organización española (regístrese en hub.fiskaly.com)
- Una clave API y secreto generados en el entorno TEST
- Información del contribuyente: nombre legal, NIF (número fiscal) y territorio
Tu secreto de API se muestra solo una vez. Guárdelo inmediatamente en un lugar seguro.
Autenticarse
curl -X POST https://test.es.sign.fiskaly.com/api/v1/auth \ -H "Content-Type: application/json" \ -d '{ "content": { "api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET" } }'const BASE = "https://test.es.sign.fiskaly.com/api/v1"; const response = await fetch(`${BASE}/auth`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: { api_key: "YOUR_API_KEY", api_secret: "YOUR_API_SECRET", }, }), }); const { access_token } = await response.json(); const headers = { "Authorization": `Bearer ${access_token}`, "Content-Type": "application/json", };import requests, uuid BASE = "https://test.es.sign.fiskaly.com/api/v1" resp = requests.post(f"{BASE}/auth", json={ "content": {"api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET"} }) access_token = resp.json()["access_token"] hdrs = {"Authorization": f"Bearer {access_token}"}// POST https://test.es.sign.fiskaly.com/api/v1/auth // Body: {"content":{"api_key":"...","api_secret":"..."}} // Response: { "access_token": "..." }using var client = new HttpClient(); var authResp = await client.PostAsJsonAsync( "https://test.es.sign.fiskaly.com/api/v1/auth", new { content = new { api_key = "YOUR_API_KEY", api_secret = "YOUR_API_SECRET" } }); var token = (await authResp.Content.ReadFromJsonAsync<JsonElement>()) .GetProperty("access_token").GetString();📘NoteSIGN ES envuelve todos los cuerpos de solicitud en un sobre
content. Esto se aplica a la autenticación y a todas las llamadas API posteriores.Crear un contribuyente
Registra la información del contribuyente. El
territorydetermina qué regulación se aplica:ARABA,BIZKAIA,GIPUZKOA→ TicketBAISPAIN_OTHER,CANARY_ISLANDS,CEUTA,MELILLA→ Verifactu
curl -X PUT "https://test.es.sign.fiskaly.com/api/v1/taxpayer" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "content": { "issuer": { "tax_number": "B12345678", "legal_name": "My Company S.L." }, "territory": "SPAIN_OTHER", "sii": { "state": "ENABLED" } } }'await fetch(`${BASE}/taxpayer`, { method: "PUT", headers, body: JSON.stringify({ content: { issuer: { tax_number: "B12345678", legal_name: "My Company S.L.", }, territory: "SPAIN_OTHER", sii: { state: "ENABLED", }, }, }), });requests.put(f"{BASE}/taxpayer", headers=hdrs, json={ "content": { "issuer": {"tax_number": "B12345678", "legal_name": "My Company S.L."}, "territory": "SPAIN_OTHER", "sii": {"state": "ENABLED"}, } })// PUT /taxpayer // Body: {"content":{"issuer":{"tax_number":"B12345678","legal_name":"My Company S.L."},"territory":"SPAIN_OTHER","sii":{"state":"ENABLED"}}}await client.PutAsJsonAsync($"{BASE}/taxpayer", new { content = new { issuer = new { tax_number = "B12345678", legal_name = "My Company S.L." }, territory = "SPAIN_OTHER", sii = new { state = "ENABLED", }, } });Crear un firmante
El firmante gestiona la firma electrónica de las facturas. Se asigna automáticamente un certificado según el territorio.
SIGNER_ID=$(uuidgen) curl -X PUT "https://test.es.sign.fiskaly.com/api/v1/signers/${SIGNER_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"content": {}}'const signerId = crypto.randomUUID(); await fetch(`${BASE}/signers/${signerId}`, { method: "PUT", headers, body: JSON.stringify({ content: {} }), });signer_id = str(uuid.uuid4()) requests.put(f"{BASE}/signers/{signer_id}", headers=hdrs, json={"content": {}})// PUT /signers/{signerId} // Body: {"content":{}}var signerId = Guid.NewGuid().ToString(); await client.PutAsJsonAsync($"{BASE}/signers/{signerId}", new { content = new {} });Crear un cliente
CLIENT_ID=$(uuidgen) curl -X PUT "https://test.es.sign.fiskaly.com/api/v1/clients/${CLIENT_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"content": {"signer_id": "'${SIGNER_ID}'"}}'const clientId = crypto.randomUUID(); await fetch(`${BASE}/clients/${clientId}`, { method: "PUT", headers, body: JSON.stringify({ content: { signer_id: signerId } }), });client_id = str(uuid.uuid4()) requests.put(f"{BASE}/clients/{client_id}", headers=hdrs, json={"content": {"signer_id": signer_id}})// PUT /clients/{clientId} // Body: {"content":{"signer_id":"<signerId>"}}var clientId = Guid.NewGuid().ToString(); await client.PutAsJsonAsync($"{BASE}/clients/{clientId}", new { content = new { signer_id = signerId } });Crear tu primera factura
INVOICE_ID=$(uuidgen) curl -X PUT "https://test.es.sign.fiskaly.com/api/v1/clients/${CLIENT_ID}/invoices/${INVOICE_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "content": { "type": "SIMPLIFIED", "number": "INV-001", "text": "Sales receipt", "full_amount": "12.10", "items": [ { "text": "Product A", "quantity": "1", "unit_amount": "10.00", "full_amount": "12.10", "system": { "type": "REGULAR", "rate": "21.00" } } ] } }'const invoiceId = crypto.randomUUID(); const invoice = await fetch( `${BASE}/clients/${clientId}/invoices/${invoiceId}`, { method: "PUT", headers, body: JSON.stringify({ content: { type: "SIMPLIFIED", number: "INV-001", text: "Sales receipt", full_amount: "12.10", items: [ { text: "Product A", quantity: "1", unit_amount: "10.00", full_amount: "12.10", system: { type: "REGULAR", rate: "21.00" }, }, ], }, }), } ).then(r => r.json()); console.log("Signed invoice:", invoice);invoice_id = str(uuid.uuid4()) invoice = requests.put( f"{BASE}/clients/{client_id}/invoices/{invoice_id}", headers=hdrs, json={ "content": { "type": "SIMPLIFIED", "number": "INV-001", "text": "Sales receipt", "full_amount": "12.10", "items": [{ "text": "Product A", "quantity": "1", "unit_amount": "10.00", "full_amount": "12.10", "system": {"type": "REGULAR", "rate": "21.00"}, }], } }, ).json() print("Signed:", invoice)// PUT /clients/{clientId}/invoices/{invoiceId} // Body: {"content":{"type":"SIMPLIFIED","number":"INV-001",...}} // Response contains the signed, compliant invoice datavar invoiceId = Guid.NewGuid().ToString(); var inv = await client.PutAsJsonAsync( $"{BASE}/clients/{clientId}/invoices/{invoiceId}", new { content = new { type = "SIMPLIFIED", number = "INV-001", text = "Sales receipt", full_amount = "12.10", items = new[] { new { text = "Product A", quantity = "1", unit_amount = "10.00", full_amount = "12.10", system = new { type = "REGULAR", rate = "21.00" }, }}, }});La respuesta contiene los datos de la factura firmada y conforme, incluyendo toda la información requerida por las regulaciones TicketBAI o Verifactu.
Ejecutar el script
Sección titulada «Ejecutar el script»¿Quiere ejecutar todos los pasos automáticamente? Descarga y ejecuta nuestro script de inicio rápido:
# Descargar y ejecutar
curl -O https://workspace.fiskaly.com/scripts/sign-es-quickstart.sh
export API_KEY="your_api_key"
export API_SECRET="your_api_secret"
bash sign-es-quickstart.sh# Descargar y ejecutar
curl -O https://workspace.fiskaly.com/scripts/sign-es-quickstart.mjs
API_KEY="your_key" API_SECRET="your_secret" node sign-es-quickstart.mjsPróximos pasos
Sección titulada «Próximos pasos»Was this page helpful?