Documentación

Enviar facturas

El endpoint central de la API. Cada llamada crea un registro de facturación de alta conforme al RD 1007/2023: FactuBridge calcula la huella encadenada, genera el QR y remite el registro a la AEAT.

POST/v1/create
POST /v1/create
Authorization: Bearer $FACTUBRIDGE_API_KEY
Content-Type: application/json

{
  "serie": "A",
  "numero": "2026-0001",
  "fecha_expedicion": "01-10-2026",
  "tipo_factura": "F1",
  "descripcion": "Servicios de consultoría — octubre 2026",
  "nif": "B87654321",
  "nombre": "CLIENTE EJEMPLO SL",
  "lineas": [
    {
      "base_imponible": "1000.00",
      "tipo_impositivo": "21.00",
      "cuota_repercutida": "210.00"
    },
    {
      "base_imponible": "500.00",
      "tipo_impositivo": "10.00",
      "cuota_repercutida": "50.00"
    }
  ],
  "importe_total": "1760.00"
}

La respuesta es síncrona:

{
  "uuid": "9b2e7c1a-4f6d-4c1e-9a3b-2f8e5d7c0a11",
  "estado": "Pendiente",
  "url": "https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?...",
  "qr": "iVBORw0KGgoAAAANSUhEUgAA...",
  "huella": "3AD5CA54A0DE383B0C1F79E1B2C4D6E8..."
}
  • huella — hash SHA-256 encadenado con el registro anterior del mismo obligado. Es lo que hace la factura inmutable.
  • qr — imagen PNG en Base64, lista para incrustar en el PDF o el ticket. El reglamento exige imprimirla entre 30×30 y 40×40 mm, al inicio de la factura.
  • url — URL de cotejo de la AEAT codificada en el QR.
  • estadoPendiente: el registro está aceptado por FactuBridge y en cola de remisión. El resultado AEAT llega después (ver estados).

No esperes a la AEAT para entregar la factura. La norma permite emitir en el momento; la remisión del registro es responsabilidad del sistema (nuestra). Tu flujo de caja o de venta no depende de la latencia de la Agencia Tributaria.

Tipos de factura

CódigoTipoDestinatario
F1Factura completaObligatorio (nombre + nif o id_otro)
F2Simplificada (ticket), máx. 3.000 €Prohibido
F3Sustitución de simplificadasObligatorio
R1R4Rectificativas (art. 80 LIVA, error fundado, concurso, incobrables, resto)Obligatorio
R5Rectificativa de simplificadaProhibido

Para rectificar una simplificada (F2) usa siempreR5. Las rectificativas requieren tipo_rectificativa(I por diferencias, S por sustitución — esta última con importe_rectificativa) y la listafacturas_rectificadas:

{
  "serie": "R",
  "numero": "2026-0003",
  "fecha_expedicion": "15-10-2026",
  "tipo_factura": "R1",
  "tipo_rectificativa": "I",
  "facturas_rectificadas": [
    { "serie": "A", "numero": "2026-0001", "fecha_expedicion": "01-10-2026" }
  ],
  "descripcion": "Rectificación por descuento no aplicado",
  "nif": "B87654321",
  "nombre": "CLIENTE EJEMPLO SL",
  "lineas": [
    {
      "base_imponible": "-100.00",
      "tipo_impositivo": "21.00",
      "cuota_repercutida": "-21.00"
    }
  ],
  "importe_total": "-121.00"
}

Líneas de detalle

Cada factura admite hasta 12 líneas; cada línea agrupa los importes con el mismo tipo impositivo. Campos principales:base_imponible, tipo_impositivo,cuota_repercutida; opcionales para casos especiales:operacion_exenta, clave_regimen,calificacion_operacion, recargo de equivalencia (tipo_recargo_equivalencia, cuota_recargo_equivalencia).

importe_total debe cuadrar con la suma de las líneas (tolerancia ±10 €, la misma que aplica la AEAT). Los importes se envían como cadenas decimales con dos decimales; las fechas aceptan DD-MM-YYYY oYYYY-MM-DD.

Envío en lote

POST/v1/create_bulk

Acepta un array de facturas y las registra en orden, en una única transacción: todo o nada. Si una factura del lote es inválida, el lote completo se rechaza con 400 y ningún registro queda creado — la cadena de huellas nunca queda a medias.

POST /v1/create_bulk
Content-Type: application/json

[
  { "serie": "A", "numero": "2026-0002", ... },
  { "serie": "A", "numero": "2026-0003", ... }
]

La respuesta devuelve resultados (uno por factura, en el mismo orden) y total. Es la vía recomendada para migraciones y para software que factura por tandas.

Duplicados y reintentos

La clave natural de un registro es serie + numero +fecha_expedicion por obligado. Reenviar la misma factura no crea un segundo registro: la API responde 409 Conflict incluyendo el registro ya existente (con su huella, su QR y su estado actual), de modo que reintentar una llamada que se cortó por red es seguro — adopta el registro devuelto como éxito y continúa.

Si prefieres un reintento sin lógica de 409, envía la cabecera opcional Idempotency-Key: el reintento con la misma clave y el mismo cuerpo devuelve directamente 200 con el estado actual del registro y la cabecera de respuesta Idempotent-Replayed: true. En /create_bulk la clave cubre el lote completo: el replay devuelve el array de respuestas íntegro, en el orden original y con el estado actual de cada registro. Por qué la protección no caduca nunca y cómo elegir una clave determinista:guía de idempotencia.

¿Dudas de integración? Escríbenos asoporte@factubridge.es — te responde un técnico, no un bot.