API de facturación electrónica · SUNAT (Perú)
La factura electrónica, en una petición.
POST /v1/invoicesSUNAT: accepted
Envías lo que vendiste. Emitay calcula los impuestos, numera, firma, envía a SUNAT y te avisa del resultado. El certificado, el diseño de la factura, el correo y los avisos siguen siendo tuyos, y se configuran sin código.
Con una llave de prueba funciona de inmediato, sin certificado ni configuración. Se entrega al registrar tu empresa: RUC, razón social y dirección.
curl https://api.emitay.com/v1/invoices \
-H "Authorization: Bearer $EMITAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"series": "F001",
"customer": {
"document_number": "20100066603",
"name": "CLIENTE S.A."
},
"items": [
{
"description": "Servicio de consultoría",
"quantity": 2,
"unit_price": "50.00"
}
]
}'curl https://api.emitay.com/v1/invoices \ -H "Authorization: Bearer $EMITAY_API_KEY" \ -H "Content-Type: application/json" \ -H "Prefer: wait=10" \ -d '{ "series": "F001", "customer": { "document_number": "20100066603", "name": "CLIENTE S.A." }, "items": [ { "description": "Servicio de consultoría", "quantity": 2, "unit_price": "50.00" } ] }'{ "id": "doc_…", "object": "document", "type": "01", "series": "F001", "number": 1, "status": "pending", "currency": "PEN", "total": "118.00", "amounts": { "taxed": "100.00", "exempt": "0.00", "unaffected": "0.00", "igv": "18.00" }, "sunat": null, "links": { "pdf": "https://files.emitay.com/files/…/F001-1.pdf", "xml": "https://files.emitay.com/files/…/F001-1.xml", "cdr": null }}{ "id": "doc_…", "object": "document", "type": "01", "series": "F001", "number": 1, "status": "accepted", "currency": "PEN", "total": "118.00", "amounts": { "taxed": "100.00", "exempt": "0.00", "unaffected": "0.00", "igv": "18.00" }, "sunat": { "code": "0", "description": "La Factura numero F001-1, ha sido aceptada" }, "links": { "pdf": "https://files.emitay.com/files/…/F001-1.pdf", "xml": "https://files.emitay.com/files/…/F001-1.xml", "cdr": "https://files.emitay.com/files/…/R-F001-1.zip" }}{ "id": "doc_…", "object": "document", "type": "01", "series": "F001", "number": 1, "status": "accepted", "currency": "PEN", "total": "118.00", "amounts": { "taxed": "100.00", "exempt": "0.00", "unaffected": "0.00", "igv": "18.00" }, "sunat": { "code": "0", "description": "La Factura numero F001-1, ha sido aceptada" }, "links": { "pdf": "https://files.emitay.com/files/…/F001-1.pdf", "xml": "https://files.emitay.com/files/…/F001-1.xml", "cdr": "https://files.emitay.com/files/…/R-F001-1.zip" }}{ "id": "evt_…", "object": "event", "type": "document.accepted", "created_at": "2026-10-08T22:32:56.000Z", "livemode": false, "data": { "object": { "id": "doc_…", "object": "document", "series": "F001", "number": 1, "status": "accepted", "sunat": { "code": "0", "description": "La Factura numero F001-1, ha sido aceptada" } } }}El recorrido de una factura, paso a paso: quién habla con quién y qué viaja en cada momento. La API responde sin esperar a SUNAT; Prefer: wait=10 espera su veredicto en la misma llamada. De cada respuesta se muestran los campos principales.
Lo que deja de ser tu problema
- CalculaEl IGV, los totales, los descuentos y las detracciones, con decimales exactos.
- NumeraToma el siguiente número de la serie. Un comprobante inválido no consume correlativo.
- FirmaArma el XML UBL 2.1 y lo firma con el certificado de tu empresa.
- EnvíaA los servicios de SUNAT, y reintenta por su cuenta si SUNAT no responde.
- AvisaCon un webhook firmado cuando SUNAT acepta, observa o rechaza.
- EntregaEl PDF, el XML firmado y el CDR, con enlaces listos para tu cliente.
Errores
Un error que dice qué campo, por qué y cómo arreglarlo
Lo que SUNAT rechazaría, la API lo niega antes de numerar, en español y con la ruta del campo. Un nombre en camelCase recibe su forma correcta. Un 422 nunca consume correlativo: corriges y vuelves a enviar.
Cada error enlaza a una página que explica qué significa y cómo resolverlo.
Cómo responde la API a un error{ "type": "https://docs.emitay.com/errors/invalid_request", "title": "La petición no es válida", "status": 422, "detail": "Revisa 3 campos: customer.document_type, items.0.unit_price, items.0.unitPrice. El motivo de cada uno está en errors", "errors": [ { "field": "customer.document_type", "message": "Indica el tipo de documento (catálogo 06 de SUNAT: \"1\" DNI, \"4\" carné de extranjería, \"7\" pasaporte, \"0\" sin documento…): solo se deduce cuando el número es un RUC válido" }, { "field": "items.0.unit_price", "message": "Es obligatorio" }, { "field": "items.0.unitPrice", "message": "Campo no reconocido. Los campos de la API se escriben en snake_case: prueba con unit_price" } ]}Webhooks
El veredicto llega firmado, y lo pruebas en localhost
SUNAT responde cuando responde. Emitay llama a tu servidor con el comprobante completo y una firma Standard Webhooks, y lo intenta hasta ocho veces si tu servidor no contesta.
emitay listen reenvía cada evento a tu máquina, firmado igual que una entrega real. Sin túnel y sin URL pública.
import { verifyWebhook } from "emitay";
export async function POST(request: Request) {
const event = await verifyWebhook({
payload: await request.text(),
headers: request.headers,
secret: process.env.EMITAY_WEBHOOK_SECRET!,
});
if (event.type === "document.accepted") {
const factura = event.data.object; // un Document, con su tipo
console.log(factura.series, factura.number, factura.links.pdf);
}
return new Response(null, { status: 204 });
}$ npx emitay listen --forward-to http://localhost:3000Escuchando los eventos de MI EMPRESA S.A.C. (RUC 20…), en modo de pruebaReenviando a http://localhost:3000/Secreto de firma: whsec_… 17:32:56 document.accepted Factura F001-2 (doc_…) — SUNAT 0 → 204 No Content (16 ms)Modo de prueba
Tu primera factura, antes de tener certificado
Una llave sk_test_… no pide nada más: ni certificado digital ni usuario SOL. Emitay firma con un certificado de prueba y envía al ambiente beta de SUNAT, que valida de verdad la estructura, la firma y los cálculos.
Lo que no se puede probar contra SUNAT, se dice: las guías de remisión no tienen ambiente de pruebas, así que su aceptación en modo de prueba llega marcada como simulada.
Qué hace el modo de pruebask_test_…- Certificado de prueba · SUNAT beta · sin valor tributario
sk_live_…- El certificado y el usuario SOL de tu empresa · SUNAT producción
El código no cambia: cambia la llave.
Lo que recibe tu cliente
Tu factura, tu correo y tu servidor de correo
El comprobante sale con el nombre y el logo de tu empresa. El diseño del PDF, la redacción del correo y el servidor que lo envía se configuran en el panel, sin código. Prueba aquí lo que cambia.
Configura tu correo
Emitay envía el comprobante al correo de tu cliente con el PDF, el XML firmado y el CDR adjuntos. Tú decides desde qué dirección sale y qué dice.
Con el nombre de tu empresa. Las respuestas de tu cliente llegan al correo de tu empresa.
Desde tu propia dirección, con los datos que da tu proveedor: Google Workspace, Microsoft 365, Amazon SES, tu hosting… La contraseña se guarda cifrada, y desde el panel te envías un mensaje de prueba para comprobarlo.
- De
- MI EMPRESA S.A.C. desde el correo de EmitayMI EMPRESA S.A.C. <[email protected]> por smtp.miempresa.pe
- Responder a
- [email protected]
- Asunto
- Factura electrónica F001-1 de MI EMPRESA S.A.C.
MI EMPRESA S.A.C.RUC 20123456786
Factura electrónica F001-1
- Comprobante
- Factura electrónica F001-1
- Fecha de emisión
- 08/10/2026
- Cliente
- CLIENTE S.A.
- Importe total
- S/ 118.00
- 20123456786-01-F001-1.pdf
- 20123456786-01-F001-1.xml
- R-20123456786-01-F001-1.zip
POST /v1/documents/{id}/emails.Configura tu factura
Cada comprobante tiene su PDF en A4 y en ticket de 80 y de 58 mm. Si quieres otro diseño, lo armas en un editor visual, colocando cada dato donde va: sin código y sin plantillas HTML.
El mismo motor dibuja la vista previa y el PDF final, y una plantilla no se puede guardar sin los datos que SUNAT exige en la representación impresa.
Hoja A4, las que haga falta. Es el formato por defecto.
El mismo enlace los sirve todos:…/F001-1.pdf?format=a4
document_idSerie y númeroCobertura
Todos los comprobantes, directo a SUNAT
Cada empresa emite con su propio certificado digital y su propio usuario SOL, y Emitay envía sus comprobantes directamente a los servicios de SUNAT. Emitay no es un PSE ni un OSE: es la API con la que tu sistema emite.
- 01Factura
- 03Boleta de venta
- 07Nota de crédito
- 08Nota de débito
- 09Guía de remisión de remitente
- 31Guía de remisión de transportista
- 20Comprobante de retención
- 40Comprobante de percepción
Casos tributarios
- Operaciones gratuitas
- Descuentos por línea y globales
- Exoneradas e inafectas
- Exportación
- Detracción
- Anticipos
- Venta al crédito y cuotas
- ICBPER
- ISC e IVAP
- Percepción
- Otras monedas
Y después de emitir
- Anulación con una sola llamada: baja, resumen diario o reversión, según el comprobante.
- Envío por correo con PDF, XML y CDR, a pedido o automático al aceptar SUNAT.
- Idempotencia en toda creación: un reintento no emite dos veces.
- SDK de TypeScript sin dependencias, con tipos generados del contrato.
Lo que aún no se ofrece está escrito en la documentación de cada comprobante, no escondido.
Casos de uso
Para el sistema que ya tienes
Tienda en línea
Cuando el pago se confirma, tu tienda envía lo que vendió. Emitay calcula el IGV, numera, firma, envía a SUNAT y le manda el comprobante a tu cliente.
Boletas y facturas electrónicas para tu tienda en líneaPunto de venta
En el mostrador no se puede esperar. Tu sistema envía la venta, recibe el comprobante numerado al instante e imprime el ticket; Emitay se encarga de SUNAT.
Comprobantes electrónicos para tu punto de ventaSoftware y ERP
Tu producto ya sabe qué se vendió. Emitay le añade la emisión ante SUNAT sin que tengas que armar XML, firmar ni seguir los cambios de las reglas.
Facturación electrónica dentro de tu software o ERPTransporte y logística
Tu sistema conoce el traslado: qué bienes, de dónde, a dónde y quién los lleva. Emitay arma la guía, la firma, la envía a SUNAT y te avisa cuando responde.
Guías de remisión electrónicas desde tu sistema
¿Dudas antes de integrar? Están en las preguntas frecuentes.
Cómo se empieza
De la cuenta a producción, en tres pasos
Crea tu cuenta
Registra tu empresa con su RUC, razón social y dirección fiscal. El panel te entrega una llave de prueba en ese momento.
Emite en modo de prueba
Con
curlo con el SDK. La factura va al ambiente beta de SUNAT y vuelve con su respuesta. Integra webhooks conemitay listen.Pasa a producción
Carga el certificado digital y el usuario secundario SOL de tu empresa, crea una llave de producción y cámbiala en tu configuración.