Facturar en España
Tu primera factura
En cinco minutos vas a emitir una factura española, ver su registro en la cadena VERI*FACTU y descargar su PDF.
1. Comprueba que puedes emitir
Sección titulada «1. Comprueba que puedes emitir»curl https://olympus.atharix.com/api/v1/me \ -H "X-API-Key: $OLYMPUS_API_KEY"{ "negocio": { "id": "8f2c…", "ruc": "B12345678", "razon_social": "COMERCIAL IBÉRICA S.L.", "pais": "ES" }, "regimen": "VERI*FACTU", "ambiente": "pruebas", "listo_para_emitir": true, "requisitos_faltantes": [], "clave": { "nombre": "ERP Holded", "prefijo": "dlt_a1b2c3d4", "scopes": ["invoices:write", "invoices:read"] }, "limites": { "lectura_por_minuto": 600, "escritura_por_minuto": 120 }}Si listo_para_emitir es false, requisitos_faltantes dice qué falta y como_resolverlo dónde
resolverlo. Lo más habitual es verifactu_enabled: el negocio tiene que activar VERI*FACTU en
Olympus → Configuración → VERI*FACTU.
2. Emite la factura
Sección titulada «2. Emite la factura»curl -X POST https://olympus.atharix.com/api/v1/invoices/issue \ -H "X-API-Key: $OLYMPUS_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: primera-factura-001" \ -d '{ "referencia_externa": "SO-2026-0912", "comprador": { "identificacion": "12345678Z", "razon_social": "CLIENTE EJEMPLO S.L.", "email": "facturas@ejemplo.es" }, "items": [ { "codigo_principal": "SRV-001", "descripcion": "Servicio de soporte mensual", "cantidad": 1, "precio_unitario": 100.00, "impuestos": [{ "codigo_impuesto": "ES_IVA_21" }] } ], "totales": { "total_sin_impuestos": 100.00, "importe_total": 121.00 } }'import os, httpx
client = httpx.Client( base_url="https://olympus.atharix.com/api/v1", headers={"X-API-Key": os.environ["OLYMPUS_API_KEY"]}, timeout=20,)
respuesta = client.post( "/invoices/issue", headers={"Idempotency-Key": "primera-factura-001"}, json={ "referencia_externa": "SO-2026-0912", "comprador": { "identificacion": "12345678Z", "razon_social": "CLIENTE EJEMPLO S.L.", "email": "facturas@ejemplo.es", }, "items": [ { "codigo_principal": "SRV-001", "descripcion": "Servicio de soporte mensual", "cantidad": 1, "precio_unitario": 100.00, "impuestos": [{"codigo_impuesto": "ES_IVA_21"}], } ], "totales": {"total_sin_impuestos": 100.00, "importe_total": 121.00}, },)respuesta.raise_for_status()factura = respuesta.json()print(factura["secuencial"], factura["huella"])const respuesta = await fetch("https://olympus.atharix.com/api/v1/invoices/issue", { method: "POST", headers: { "X-API-Key": process.env.OLYMPUS_API_KEY, "Content-Type": "application/json", "Idempotency-Key": "primera-factura-001", }, body: JSON.stringify({ referencia_externa: "SO-2026-0912", comprador: { identificacion: "12345678Z", razon_social: "CLIENTE EJEMPLO S.L.", email: "facturas@ejemplo.es", }, items: [ { codigo_principal: "SRV-001", descripcion: "Servicio de soporte mensual", cantidad: 1, precio_unitario: 100.0, impuestos: [{ codigo_impuesto: "ES_IVA_21" }], }, ], totales: { total_sin_impuestos: 100.0, importe_total: 121.0 }, }),});
const factura = await respuesta.json();console.log(factura.secuencial, factura.huella);$payload = [ "referencia_externa" => "SO-2026-0912", "comprador" => [ "identificacion" => "12345678Z", "razon_social" => "CLIENTE EJEMPLO S.L.", "email" => "facturas@ejemplo.es", ], "items" => [[ "codigo_principal" => "SRV-001", "descripcion" => "Servicio de soporte mensual", "cantidad" => 1, "precio_unitario" => 100.00, "impuestos" => [["codigo_impuesto" => "ES_IVA_21"]], ]], "totales" => ["total_sin_impuestos" => 100.00, "importe_total" => 121.00],];
$ch = curl_init("https://olympus.atharix.com/api/v1/invoices/issue");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "X-API-Key: " . getenv("OLYMPUS_API_KEY"), "Content-Type: application/json", "Idempotency-Key: primera-factura-001", ],]);$factura = json_decode(curl_exec($ch), true);Respuesta 201 Created:
{ "id": "6f1e8a24-91cd-4c73-9a1f-2b0f5d7e4c88", "tipo": "factura", "pais": "ES", "estado": "registrado", "secuencial": "F2026-0001", "huella": "3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9D2CF5C7BCBFB9A2D62FB", "huella_anterior": "", "referencia_aeat": null, "fecha_registro": "2026-09-25T10:31:07+02:00", "tipo_factura": "F1", "ambiente": "pruebas", "totales": { "total_sin_impuestos": 100.0, "descuento": 0.0, "iva": 21.0, "importe_total": 121.0 }, "urls": { "detalle": "https://olympus.atharix.com/api/v1/invoices/6f1e8a24-…", "pdf": "https://olympus.atharix.com/api/v1/invoices/6f1e8a24-…/pdf", "xml": null, "verificacion": "https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=B12345678&numserie=F2026-0001&…" }}Guarda el id, el secuencial y la huella: son la referencia del comprobante.
3. Descarga el PDF
Sección titulada «3. Descarga el PDF»Disponible ya, sin esperar a la AEAT:
curl https://olympus.atharix.com/api/v1/invoices/6f1e8a24-…/pdf \ -H "X-API-Key: $OLYMPUS_API_KEY" \ -o factura.pdfLleva el código QR que permite a cualquiera comprobar la factura en la sede de la AEAT.
4. Comprueba el envío
Sección titulada «4. Comprueba el envío»Un minuto después:
curl https://olympus.atharix.com/api/v1/invoices/6f1e8a24-… \ -H "X-API-Key: $OLYMPUS_API_KEY"{ "estado": "autorizado", "referencia_aeat": "CSV-AB12CD34EF56", "fecha_envio": "2026-09-25T10:32:11+02:00", "mensajes": []}autorizado significa que la AEAT aceptó el registro. Ver
Estados de un comprobante.
Ya está
Sección titulada «Ya está»- Emitir una factura: el payload campo a campo.
- IVA, exenciones e ISP: cómo declarar cada tipo.
- Retención de IRPF y recargo de equivalencia.
- Clientes de otros países.