Emitir un comprobante
Emitir y firmar CPE desde JSON, con idempotencia.
El endpoint principal genera el UBL, lo firma, lo valida y encola su envío a SUNAT/OSE. Responde enseguida, sin esperar el CDR.
Emitir (firma + encolado)
curl -X POST https://api.xmlperu.dev/v1/cpe \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: fac-F001-123" \
-H "Content-Type: application/json" \
-d @factura.json
Responde 202 con el XML firmado y un external_id. El comprobante ya es válido
—la firma es lo que lo hace válido— y su envío corre por su cuenta.
Idempotency-Key(recomendado): identifica la operación. Si reintentas con la misma clave, se devuelve la misma respuesta sin volver a emitir.- El
factura.jsondebe incluir el emisor encompany(RUC, razón social y dirección), además declient,detailsy las leyendas. Ver el ejemplo en Primeros pasos.
Consultar el resultado
El veredicto de SUNAT llega al consultar, no al emitir:
curl https://api.xmlperu.dev/v1/cpe/$EXTERNAL_ID \
-H "Authorization: Bearer $TOKEN"
Mira resolved: mientras sea false, el comprobante sigue en camino. Cuando sea
true, status trae el desenlace y result el motivo si hubo rechazo.
Conviene esperar unos segundos antes de la primera consulta: la mayoría de los envíos se resuelven en ese lapso.
Por qué el envío va por separado
Porque SUNAT no siempre responde rápido, y una emisión que espera su respuesta deja al cliente parado frente a la caja. Firmando primero, la impresión no depende de que SUNAT esté disponible.
De los reintentos nos encargamos nosotros, con una regla importante: un timeout no se reintenta, porque el comprobante pudo haber llegado y reenviarlo lo duplicaría. Ese caso se resuelve consultando, no reenviando.
Tipos soportados (tipoDoc)
| Código | Documento |
|---|---|
01 |
Factura |
03 |
Boleta |
07 |
Nota de crédito |
08 |
Nota de débito |
| — | Resúmenes (RC/RA/RR) y guías (GRE 09/31) |
Qué se valida antes de firmar
- Plan por comprobante (01): que la cuenta tenga cupo disponible; si no,
402. - Plan por certificado (02): que la empresa tenga un certificado asignado y vigente;
en el primer uso en producción arranca su vigencia. Sin certificado o vencido:
402. - En demo nunca se bloquea.
Errores
| Código | Significado |
|---|---|
202 |
Firmado y encolado. No es aceptación de SUNAT. |
422 |
El comprobante no pasó la validación. No se firmó, y te decimos qué corregir. |
402 |
Sin cupo (plan 01) o certificado no vigente (plan 02). |
Los fallos de envío —SUNAT caída, timeout, rechazo— no llegan en la respuesta de emisión: se ven al consultar el comprobante.
El catálogo completo — formato de cada respuesta, todos los códigos HTTP y la
clasificación origin/action para automatizar reintentos — está en
Errores y respuestas.