Tipos de comprobante
Qué emite la plataforma, por qué ruta va cada cosa y qué exige cada una.
El quickstart recorre una factura. Ésta es la lista completa, con la ruta de cada tipo y lo que lo distingue.
El mapa
| Comprobante | Código | Se crea en | Camino SUNAT |
|---|---|---|---|
| Factura | 01 | POST /api/v2/documents | Síncrono (sendBill) |
| Boleta de venta | 03 | POST /api/v2/documents | Síncrono |
| Nota de crédito | 07 | POST /api/v2/documents | Síncrono |
| Nota de débito | 08 | POST /api/v2/documents | Síncrono |
| Resumen diario | — | POST /api/v2/summaries | Ticket (sendSummary) |
| Comunicación de baja | — | POST /api/v2/voided | Ticket |
| Comprobante de retención | 20 | POST /api/v2/retentions | Síncrono |
| Comprobante de percepción | 40 | POST /api/v2/perceptions | Síncrono |
Los cuatro primeros comparten ruta porque comparten forma: cambian los campos obligatorios, no el contrato. Los cuatro últimos tienen ruta propia porque son documentos distintos, con su propio UBL y su propio ciclo.
Todos los POST de creación piden el scope documents:create y exigen Idempotency-Key. Todos
los GET piden documents:read. Cada colección tiene además su
POST .../{id}/submissions con documents:submit.
Factura y boleta
La diferencia que más sorprende no es fiscal, es de destino: la factura va a un RUC, la boleta puede ir a un DNI o incluso a un cliente genérico. Lo demás —líneas, impuestos, totales— es la misma estructura.
Los totales no se envían: se calculan. POST /api/v2/documents/validations te devuelve los
totals que la plataforma calculó a partir de tus líneas, y ésa es la forma barata de comprobar que
tu mapeo cuadra con el suyo antes de emitir nada.
Notas de crédito y débito
Una nota siempre apunta a un comprobante anterior, y ese vínculo es parte del documento: tipo, serie y número del afectado, más el código de motivo del catálogo de SUNAT.
La nota de crédito parcial existe y está soportada: no hace falta anular una factura entera para corregir una línea.
Una nota sobre una boleta no es lo mismo que una nota sobre una factura, y la plataforma lo sabe: el camino de envío que le corresponde depende del comprobante afectado.
Resumen diario y comunicación de baja
Estos dos son los que van por ticket. SUNAT no contesta con el CDR: contesta con un identificador
y el resultado se consulta después. En la máquina de estados es el ramal
SUBMITTED → TICKET_PENDING → … que describe Ciclo de vida.
- Resumen diario (
POST /api/v2/summaries) informa boletas y sus notas: acepta los tipos03,07y08. - Comunicación de baja (
POST /api/v2/voided) da de baja comprobantes ya emitidos: acepta01,07y08.
La comunicación de baja es la única forma de retirar un comprobante que SUNAT ya aceptó. Por
eso importa tanto no reenviar un documento en AMBIGUOUS: deshacer un duplicado cuesta una baja
aceptada, no una llamada de borrado.
Retenciones y percepciones
POST /api/v2/retentions y POST /api/v2/perceptions, cada una con su GET y su submissions.
Son regímenes de pago: no facturan una venta, documentan una retención o una percepción sobre
comprobantes que ya existen.
Van por su propio Workflow, con su propio UBL, y usan los mismos scopes que el resto de la emisión.
Lo que todos comparten
El correlativo lo pones tú. La plataforma no inventa números: la unicidad es
(empresa, entorno, tipo, serie, número) y la impone la base de datos. Reenviar el mismo número con
otro contenido no lo sobrescribe: lo rechaza.
El entorno lo decide la empresa, no el comprobante. El mismo cuerpo emitido por una empresa en
BETA va a homologación y por una en PRODUCTION va a SUNAT de verdad. No hay un campo que lo
cambie, y eso es lo que hace imposible mandar a producción por accidente. Ver
Entornos.
La cuota se cobra una vez, al aceptar. Un replay de la misma Idempotency-Key no cobra dos
veces, y un documento que después es rechazado por SUNAT ya consumió su unidad: se cobra por aceptar
y hacer durable, no por el veredicto. Ver Errores, idempotencia y cuotas.