Desarrolladores

API de facturación electrónica (SUNAT)

Tu sistema manda la venta y nosotros la numeramos, la firmamos con tu certificado digital y la enviamos a SUNAT con tu RUC. Recibes la respuesta de SUNAT (la constancia o CDR) en la misma llamada.

Cómo empezarAutenticaciónEmitirEnviarConsultarErroresCobro

Cómo empezar

  1. Con tu cuenta y el servicio de facturación activo, entra a Fiscal → Configuración y completa los 4 pasos: datos de tu empresa, usuario SOL y certificado, numeración y paso a Producción (cada paso tiene su tutorial).
  2. En Fiscal → API toca Nueva llave y guárdala: se muestra una sola vez.
  3. Prueba en modo de pruebas: los comprobantes van al ambiente de pruebas de SUNAT, sin valor tributario y sin costo.
  4. Cuando todo esté en verde, pasa a Producción desde Configuración. Desde ahí cada comprobante vale ante SUNAT.

Autenticación

Base de la API: https://mercurius33.app/api/fiscal/v1. Manda tu llave en cada pedido y una clave de idempotencia en cada POST:

AuthorizationBearer fk_… (también vale el encabezado X-Api-Key).
Idempotency-KeyObligatoria en cada POST, hasta 240 caracteres (por ejemplo el número de tu venta). Repetir el pedido con la misma clave devuelve el mismo comprobante: no se numera ni se cobra dos veces. Usar la misma clave con otros datos responde 409.
X-Correlation-IdOpcional: un identificador tuyo para rastrear el pedido; vuelve como requestId.

Emitir una boleta o factura

POST /documents

documentType"03" boleta · "01" factura.
issueDateFecha de emisión, AAAA-MM-DD.
customer.documentTypeCatálogo 06 de SUNAT: "6" RUC (obligatorio en factura), "1" DNI, "4" carné de extranjería, "7" pasaporte. Boleta sin datos del cliente: "1", número "00000000" y nombre "Cliente varios". Si la boleta pasa de S/ 700, SUNAT pide el documento del cliente.
customer.documentNumberNúmero del documento del cliente.
customer.legalNameNombre o razón social.
items[].descriptionLo que se vende.
items[].quantityCantidad (mayor que 0).
items[].unitPricePrecio unitario con IGV. El IGV y la base se calculan solos.
items[].unitCodeUnidad de medida de SUNAT: "NIU" unidades, "ZZ" servicios.
items[].taxAffectationCode"10" (gravado con IGV). Por ahora es el único que se emite.
sendOpcional. true = además de numerar, firma y envía a SUNAT en la misma llamada.
curl -X POST https://mercurius33.app/api/fiscal/v1/documents \
  -H "Authorization: Bearer fk_TU_LLAVE" \
  -H "Idempotency-Key: venta-000123" \
  -H "Content-Type: application/json" \
  -d '{
    "documentType": "01",
    "issueDate": "2026-10-10",
    "customer": { "documentType": "6", "documentNumber": "20123456789", "legalName": "CLIENTE S.A.C." },
    "items": [{ "description": "Menú ejecutivo", "quantity": 2, "unitPrice": 23.6, "unitCode": "NIU", "taxAffectationCode": "10" }],
    "send": true
  }'

Respuesta 201:

{
  "ok": true,
  "requestId": "…",
  "reused": false,
  "mode": "PRODUCTION",
  "document": { "id": "cm…", "formattedNumber": "F001-00000124", "status": "NUMBER_ASSIGNED",
                "taxableAmount": "40", "igvAmount": "7.2", "totalAmount": "47.2", … },
  "sunat": {
    "status": "ACCEPTED",
    "accepted": true,
    "cdr": { "code": "0", "description": "La Factura numero F001-00000124, ha sido aceptada", "notes": [] },
    "error": null,
    "numberTaken": false
  }
}

Los montos llegan como texto (por ejemplo "47.2"). Guarda document.id. Si el envío falla (SUNAT no responde), el comprobante igual queda numerado: vuelve a enviarlo con la ruta de abajo. Si numberTaken es true, otro sistema ya usó ese número: la serie queda en pausa hasta corregir la numeración en Fiscal → Configuración.

Enviar a SUNAT

POST /documents/{id}/send — firma (si hace falta) y envía una boleta o factura ya numerada. Responde 200 si SUNAT la aceptó y 422 si no, con el mismo bloque sunat. Necesita su propia Idempotency-Key.

Consultar

GET /documentsTus comprobantes, con número, cliente, totales y estado. Filtros opcionales: search, type (INVOICE, RECEIPT) y status.
GET /documents/{id}/xmlEl XML firmado del comprobante.
GET /documents/{id}/lifecycleSu estado y su historial de eventos.

Errores

Los errores llegan como { "ok": false, "error": { "code": "…", "message": "…" } }.

401 API_KEY_INVALIDLa llave no existe o fue revocada.
400 IDEMPOTENCY_KEY_REQUIREDFalta Idempotency-Key en un POST.
400 DOCUMENT_VALIDATION_ERRORFaltan datos o no son válidos (vienen los detalles).
402 INSUFFICIENT_BALANCENo hay saldo para emitir en Producción.
409 IDEMPOTENCY_CONFLICTLa misma Idempotency-Key con otros datos.
422 SERIES_NUMBERING_NOT_CONFIRMED…La serie está en pausa: revisa la numeración en Configuración.
422 DOCUMENT_NOT_ALLOWED_FOR_TAX_REGIMETu régimen no permite ese comprobante.
422 TAX_AFFECTATION_NOT_SUPPORTEDUn ítem no es gravado (por ahora solo "10").
503 FISCAL_API_PRICE_NOT_CONFIGUREDLa API todavía no está activa en Producción.

Cobro

En modo de pruebas no se cobra. En Producción, cada comprobante emitido se descuenta de tu saldo prepago; el precio está en Fiscal → API. Un pedido repetido con la misma Idempotency-Key no se cobra dos veces, y enviar o reenviar a SUNAT no se cobra.