GuíaEjemplosReferencia API
apisunat.netIngresar

Primeros pasos

  • API SUNAT
  • Inicio rápido
  • Integra con IA
  • Autenticación
  • Planes y límites

Configurar el RUC

  • Emisores
  • Establecimientos y series

Emitir

  • Documentos
  • Idempotencia
  • Estados
  • Correos
  • Catálogos

Integración

  • Errores
  • Webhooks
  • Cambios

Documentos

Facturas, boletas, notas de crédito y débito y comprobantes de retención con POST /documents.

Un solo endpoint emite todos los comprobantes de venta. El tipo se elige con documentType.

documentTypeComprobanteEjemplo
01FacturaFactura
03Boleta de ventaBoleta
07Nota de créditoNota de crédito
08Nota de débitoNota de débito
20Comprobante de retenciónRetención
http
POST /api/v1/issuer/documents
X-API-Key: asu_live_...
Idempotency-Key: venta-2026-000123
Content-Type: application/json

El header Idempotency-Key es obligatorio. Ver Idempotencia.

Campos principales

documentTypestringrequired

01, 03, 07, 08 o 20.

currencystringrequired

PEN o USD. En USD también es obligatorio exchangeRate.

issueDatestringrequired

Fecha de emisión AAAA-MM-DD. No puede ser mayor a dos días desde hoy.

customerobjectrequired

Cliente. Ver Cliente.

itemsarrayrequired

Líneas del comprobante, al menos una. Ver Líneas.

rucstringoptional

RUC emisor. Opcional si el workspace tiene un solo RUC activo.

seriesstringoptional

Serie de 4 caracteres. Si se omite, se usa la serie por defecto.

numberinteger | nulloptional

Correlativo. Omítelo en series automáticas; es obligatorio en series manuales.

establishmentCodestringoptional

Establecimiento que emite (por defecto 0000, el domicilio fiscal).

issueTimestringoptional

Hora de emisión HH:MM:SS.

operationTypestringoptional

Tipo de operación (catálogo 51): 0101 venta interna (por defecto), 0200 exportación de bienes, 0201 exportación de servicios, 1001 operación sujeta a detracción (se usa sola si envías detraction) y 2001 operación sujeta a percepción (se usa sola si envías perception).

igvRatenumberoptional

Tasa del IGV de las líneas gravadas: 18 (por defecto) o 10.5 para restaurantes y hoteles MYPE inscritos en el régimen especial.

exchangeRatenumberoptional

Tipo de cambio, mínimo 0.001. Obligatorio en USD.

notesstringoptional

Observaciones, hasta 1000 caracteres.

Cliente

  • La factura exige un cliente con RUC de 11 dígitos (documentType: "6"), salvo en exportación, que usa 0 o 7.
  • Una boleta mayor a S/ 700 debe identificar al cliente; no admite documentType: "0".
  • El DNI tiene 8 dígitos. Pasaportes y carnés se envían con sus letras.
customer.documentTypestringrequired

Catálogo 06: 6 RUC, 1 DNI, 4 carnet de extranjería, 7 pasaporte, 0 sin documento o no domiciliado.

customer.documentNumberstringrequired

Número del documento.

customer.namestringoptional

Nombre o razón social. Con RUC o DNI puedes omitirlo y la API lo busca; si no lo encuentra, responde CUSTOMER_NOT_FOUND. Con otros tipos es obligatorio.

customer.addressstringoptional

Dirección.

customer.emailstringoptional

Correo. Se usa como destinatario por defecto en Correos.

Líneas

items[].descriptionstringrequired

Descripción, hasta 500 caracteres.

items[].quantitynumberrequired

Cantidad, mayor que 0.

items[].unitPricenumberrequired

Precio unitario.

items[].includesTaxbooleanoptional

Si unitPrice incluye IGV. Por defecto true.

items[].taxCodestringoptional

Afectación del IGV (catálogo 07). Por defecto 10 (gravado). Ver Catálogos.

items[].unitCodestringoptional

Unidad de medida (catálogo 03). Por defecto NIU; para servicios usa ZZ.

items[].codestringoptional

Código interno del producto.

items[].discountAmountnumberoptional

Descuento de la línea en importe.

items[].discountPercentnumberoptional

Descuento de la línea en porcentaje.

items[].sunatProductCodestringoptional

Código de producto SUNAT (catálogo 25, UNSPSC de 8 dígitos).

items[].icbperbooleanoptional

Bolsa plástica sujeta al ICBPER (tributo 7152, S/ 0.50 por bolsa). quantity es el número de bolsas y debe ser entero. Se suma aparte, fuera de la base del IGV.

items[].iscobjectoptional

ISC (tributo 2000), solo con taxCode 10: { "system": "01", "rate": 30 } (al valor, en %) o { "system": "02", "amountPerUnit": 2.7 } (específico, por unidad). El IGV se calcula sobre valor + ISC.

taxCode 17 es IVAP (4 %, arroz pilado): todas las líneas del comprobante deben usarlo y se agrega sola la leyenda 2007. Con IVAP o ISC aplica los descuentos por ítem; no se admiten descuento global ni anticipos.

Para revisar los totales antes de emitir, envía las mismas líneas a POST /calculations.

Pago

paymentConditionstringoptional

cash (contado, por defecto) o credit (crédito). En crédito es obligatorio installments.

installmentsarrayoptional

Cuotas: [{ "date": "2026-11-27", "amount": 590 }].

dueDatestringoptional

Fecha de vencimiento.

paymentsarrayoptional

Pagos recibidos (solo facturas y boletas). methodCode es el código de tu sistema para el medio de pago y methodName el texto que aparece en el PDF; amount es lo aplicado y receivedAmount lo recibido (para calcular el vuelto). También admite destinationCode y reference. La suma aplicada no puede superar el total.

Notas de crédito y débito

  • El comprobante afectado debe estar aceptado por SUNAT, en la misma moneda y con fecha igual o anterior a la nota.
  • La serie de la nota empieza con F si afecta a una factura y con B si afecta a una boleta.
  • Una nota de crédito no puede superar el total del comprobante afectado.
  • Las notas no llevan descuentos ni cargos aparte en el XML: los descuentos de línea y el global se restan del valor de cada línea.
  • Nota de crédito 13 (corrige el monto pendiente o las cuotas): solo sobre una factura al crédito, con unitPrice: 0 en todas las líneas y las cuotas nuevas en installments. La suma de cuotas no puede superar el total de la factura.
affectedDocumentIdstringoptional

id de la factura o boleta emitida con esta API que corrige la nota. Debe ser del mismo RUC.

noteReasonCodestringoptional

Motivo. Crédito (catálogo 09): 01 a 10 y 13. Débito (catálogo 10): 01 a 03 (13 desde el 01/01/2027, solo con líneas inafectas).

noteReasonstringoptional

Descripción del motivo, hasta 500 caracteres.

Descuentos y cargos

discountAmountnumberoptional

Descuento global en importe.

discountPercentnumberoptional

Descuento global en porcentaje.

chargesarrayoptional

Cargos globales que no afectan la base del IGV (catálogo 53): 45 FISE, 46 recargo al consumo o propinas, 50 otros cargos. Cada uno con code, description, amount y base (mayor que 0).

prepaymentsarrayoptional

Anticipos ya facturados que se deducen: [{ "documentType": "02", "number": "F001-120", "amount": 590 }]. 02 para facturas y 03 para boletas; todas las líneas deben ser gravadas (10).

Tributos especiales

detractionobjectoptional

Solo facturas. Todos obligatorios: code (catálogo 54), percentage, amount, paymentMethod (catálogo 59, por ejemplo 001 depósito en cuenta) y bankAccount (cuenta del Banco de la Nación). Se agrega sola la leyenda 2006.

cargoTransportobjectoptional

Servicio de transporte de carga (operación 1004, detracción 027): origin y destination ({ "ubigeo": "150101", "address": "..." }), tripDetail, serviceReferenceValue, effectiveLoadReferenceValue y nominalLoadReferenceValue.

perceptionobjectoptional

Facturas y boletas: code (catálogo 22: 01 2 %, 02 1 %, 03 0.5 %), percentage (la del régimen), base, amount (= base × tasa) y total (opcional, base + percepción).

retentionobjectoptional

Solo retenciones (20): code, percentage, base, amount. Ver Retención.

perception (40)objectoptional

En el comprobante de percepción (40) el mismo objeto lleva el régimen, base (total cobrado) y amount (total percibido). Ver Percepción.

Percepción y detracción no se combinan en un mismo documento. Una retención no admite percepción, detracción ni pago a crédito.

Información adicional

relatedDocumentsarrayoptional

Documentos relacionados: { "documentType", "number", "amount" }.

legendsarrayoptional

Leyendas: { "code", "value" }.

purchaseOrderstringoptional

Orden de compra, hasta 100 caracteres.

vehiclePlatestringoptional

Placa, hasta 20 caracteres.

additionalInformationstringoptional

Texto adicional, hasta 1000 caracteres.

Respuesta

POST /documents responde 202 con el documento. Muchas veces SUNAT ya respondió y status es accepted; si sigue en processing, consulta Estados.

Recurso Document

json
{
  "id": "3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f",
  "type": "01",
  "series": "F001",
  "number": 125,
  "fullNumber": "F001-125",
  "status": "accepted",
  "environment": "produccion",
  "test": false,
  "issuerRuc": "20123456789",
  "issueDate": "2026-10-27",
  "currency": "PEN",
  "total": 118,
  "customer": { "documentType": "6", "documentNumber": "20100066603", "name": "CLIENTE S.A.C." },
  "sunat": {
    "ticket": null,
    "responseCode": "0",
    "description": "La Factura numero F001-125, ha sido aceptada",
    "errorCode": null,
    "errorMessage": null,
    "attempts": 1
  },
  "links": {
    "self": "/api/v1/issuer/documents/3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f",
    "pdf": "/api/v1/issuer/documents/3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f/pdf",
    "xml": "/api/v1/issuer/documents/3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f/xml",
    "zip": "/api/v1/issuer/documents/3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f/zip",
    "cdr": "/api/v1/issuer/documents/3f8c1d2e-6b1a-4c55-9d0e-2a7b3c4d5e6f/cdr"
  },
  "createdAt": "2026-10-27T15:04:05.000Z",
  "updatedAt": "2026-10-27T15:04:06.000Z"
}
CampoDescripción
idIdentificador del documento en API SUNAT. Úsalo en las demás rutas.
fullNumberSerie y correlativo.
totalImporte total (en retenciones, el importe retenido).
sunat.responseCodeCódigo del CDR. 0 = aceptado.
sunat.errorCodeCódigo de error de SUNAT cuando la emisión falla.
linksxml, zip y cdr son null mientras no existan.

Listar y consultar

bash
curl "https://api.apisunat.net/api/v1/issuer/documents?type=01&status=accepted&from=2026-10-01&to=2026-10-31&limit=50" \
  -H "X-API-Key: $APISUNAT_KEY"
json
{ "data": [ { "id": "...", "type": "01", "fullNumber": "F001-125" } ], "nextCursor": "9f23ef1c-c831-4376-b750-97f2bb7adbbb" }

Los resultados van del más reciente al más antiguo. Para la página siguiente envía ?cursor= con el nextCursor recibido; es null en la última página. limit va de 1 a 100 (por defecto 50).

Un documento se consulta con GET /documents/{id}.

Establecimientos y series< PreviousIdempotenciaNext >

Powered by heyo

On this page

Campos principalesClienteLíneasPagoNotas de crédito y débitoDescuentos y cargosTributos especialesInformación adicionalRespuestaRecurso DocumentListar y consultar