Resumen Diario
El Resumen Diario (tipo RC) consolida las boletas de venta (03) y notas asociadas emitidas en un día. SUNAT lo exige para dar validez a las boletas electrónicas.
Campos requeridos
Sección titulada «Campos requeridos»| Campo | Tipo | Descripción | Validación |
|---|---|---|---|
numero | int | Número correlativo del resumen diario. | > 0 |
fechaEmisionComprobantes | date | Fecha de emisión de los comprobantes incluidos. | Obligatorio |
proveedor | Proveedor | Datos del emisor. | RUC válido |
comprobantes | list[SummaryDocumentsItem] | Lista de comprobantes a declarar. | Mínimo 1 |
Campos opcionales
Sección titulada «Campos opcionales»El modelo SummaryDocuments no tiene campos opcionales a nivel raíz. Los totales se declaran explícitamente por comprobante.
Ítem del resumen (SummaryDocumentsItem)
Sección titulada «Ítem del resumen (SummaryDocumentsItem)»| Campo | Tipo | Descripción | Validación |
|---|---|---|---|
tipoOperacion | str | Tipo de operación: 1 adicionar, 2 modificar, 3 anular. | Catálogo 19 |
comprobante | Comprobante | Datos del comprobante resumido. | Obligatorio |
Comprobante
Sección titulada «Comprobante»| Campo | Tipo | Descripción | Validación |
|---|---|---|---|
tipoComprobante | str | Tipo de comprobante (03, 07, 08). | Catálogo 1 |
serieNumero | str | Serie y número (B001-123). | Formato SUNAT |
cliente | Cliente | Adquirente o usuario. | Obligatorio |
impuestos | ComprobanteImpuestos | IGV e ISC. | Obligatorio |
valorVenta | ComprobanteValorVenta | Valor de venta por tipo. | Obligatorio |
ComprobanteAfectado
Sección titulada «ComprobanteAfectado»| Campo | Tipo | Descripción |
|---|---|---|
tipoComprobante | str | Tipo de comprobante afectado. |
serieNumero | str | Serie y número del comprobante afectado. |
Reglas SUNAT aplicables
Sección titulada «Reglas SUNAT aplicables»| Código / Regla | Descripción |
|---|---|
RC | Resumen diario de boletas electrónicas. |
| Tipo de operación | 1 Adicionar, 2 Modificar, 3 Anular. |
| Validez | Las boletas solo tienen validez tras ser comunicadas en un RC aceptado por SUNAT. |
Ejemplo completo
Sección titulada «Ejemplo completo»from openubl.models import ( SummaryDocuments, SummaryDocumentsItem, Comprobante, ComprobanteImpuestos, ComprobanteValorVenta, Proveedor, Cliente,)from openubl.renderer import render_summary_documentsfrom openubl.validator import SunatValidatorfrom decimal import Decimalfrom datetime import date
summary = SummaryDocuments( numero=1, fechaEmisionComprobantes=date(2025, 6, 10), proveedor=Proveedor( ruc="20100100100", razonSocial="Mi Empresa S.A.C.", ), comprobantes=[ SummaryDocumentsItem( tipoOperacion="1", # Adicionar comprobante=Comprobante( tipoComprobante="03", serieNumero="B001-45", cliente=Cliente( nombre="Juan Pérez", numeroDocumentoIdentidad="46779327", tipoDocumentoIdentidad="1", ), impuestos=ComprobanteImpuestos(igv=Decimal("27.00")), valorVenta=ComprobanteValorVenta(importeTotal=Decimal("177.00")), ), ), ],)
xml = render_summary_documents(summary)errors = SunatValidator().validate_schema( xml, "sunat_schemas/xsd_2.1/2.0/maindoc/UBLPE-SummaryDocuments-1.0.xsd",)assert errors == []print(xml)import { createSummaryDocuments } from "@openubl/sdk";import { zSummaryDocuments } from "@openubl/sdk/zod.gen";
const summary = zSummaryDocuments.parse({numero: 1,fechaEmisionComprobantes: "2025-06-10",proveedor: { ruc: "20100100100", razonSocial: "Mi Empresa S.A.C.",},comprobantes: [ { tipoOperacion: "1", comprobante: { tipoComprobante: "03", serieNumero: "B001-45", cliente: { nombre: "Juan Pérez", numeroDocumentoIdentidad: "46779327", tipoDocumentoIdentidad: "1", }, impuestos: { igv: "27.00" }, valorVenta: { importeTotal: "177.00" }, }, },],});
const { data, error } = await createSummaryDocuments({query: { validate: true },body: summary,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST "http://localhost:8000/api/v1/summary-documents/create?validate=true" \-H "Content-Type: application/json" \-d '{ "numero": 1, "fechaEmisionComprobantes": "2025-06-10", "proveedor": { "ruc": "20100100100", "razonSocial": "Mi Empresa S.A.C." }, "comprobantes": [{ "tipoOperacion": "1", "comprobante": { "tipoComprobante": "03", "serieNumero": "B001-45", "cliente": { "nombre": "Juan Pérez", "numeroDocumentoIdentidad": "46779327", "tipoDocumentoIdentidad": "1" }, "impuestos": { "igv": "27.00" }, "valorVenta": { "importeTotal": "177.00" } } }]}'Ejemplo con validación del esquema
Sección titulada «Ejemplo con validación del esquema»openUBL expone validate_schema para validar el XML generado contra el XSD de SUNAT:
from openubl.validator import SunatValidator
errors = SunatValidator().validate_schema( xml, "sunat_schemas/xsd_2.1/2.0/maindoc/UBLPE-SummaryDocuments-1.0.xsd",)print(errors) # [] si es válidoimport { createSummaryDocuments } from "@openubl/sdk";import { zSummaryDocuments } from "@openubl/sdk/zod.gen";
const summary = zSummaryDocuments.parse({numero: 1,fechaEmisionComprobantes: "2025-06-10",proveedor: { ruc: "20100100100", razonSocial: "Mi Empresa S.A.C." },comprobantes: [{ tipoOperacion: "1", comprobante: { tipoComprobante: "03", serieNumero: "B001-45", cliente: { nombre: "Juan Pérez", numeroDocumentoIdentidad: "46779327", tipoDocumentoIdentidad: "1" }, impuestos: { igv: "27.00" }, valorVenta: { importeTotal: "177.00" }, },}],});
const { data, error } = await createSummaryDocuments({query: { validate: true },body: summary,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST "http://localhost:8000/api/v1/summary-documents/create?validate=true" \-H "Content-Type: application/json" \-d '{ "numero": 1, "fechaEmisionComprobantes": "2025-06-10", "proveedor": { "ruc": "20100100100", "razonSocial": "Mi Empresa S.A.C." }, "comprobantes": [{ "tipoOperacion": "1", "comprobante": { "tipoComprobante": "03", "serieNumero": "B001-45", "cliente": { "nombre": "Juan Pérez", "numeroDocumentoIdentidad": "46779327", "tipoDocumentoIdentidad": "1" }, "impuestos": { "igv": "27.00" }, "valorVenta": { "importeTotal": "177.00" } } }]}'Endpoint
Sección titulada «Endpoint»from openubl.models import ( SummaryDocuments, SummaryDocumentsItem, Comprobante, ComprobanteImpuestos, ComprobanteValorVenta, Proveedor, Cliente,)from openubl.renderer import render_summary_documentsfrom decimal import Decimalfrom datetime import date
summary = SummaryDocuments( numero=1, fechaEmisionComprobantes=date(2025, 6, 10), proveedor=Proveedor( ruc="20100100100", razonSocial="Mi Empresa S.A.C.", ), comprobantes=[ SummaryDocumentsItem( tipoOperacion="1", comprobante=Comprobante( tipoComprobante="03", serieNumero="B001-45", cliente=Cliente( nombre="Juan Pérez", numeroDocumentoIdentidad="46779327", tipoDocumentoIdentidad="1", ), impuestos=ComprobanteImpuestos(igv=Decimal("27.00")), valorVenta=ComprobanteValorVenta(importeTotal=Decimal("177.00")), ), ), ],)
xml = render_summary_documents(summary)print(xml)import { createSummaryDocuments } from "@openubl/sdk";import { zSummaryDocuments } from "@openubl/sdk/zod.gen";
const summary = zSummaryDocuments.parse({numero: 1,fechaEmisionComprobantes: "2025-06-10",proveedor: { ruc: "20100100100", razonSocial: "Mi Empresa S.A.C.",},comprobantes: [ { tipoOperacion: "1", comprobante: { tipoComprobante: "03", serieNumero: "B001-45", cliente: { nombre: "Juan Pérez", numeroDocumentoIdentidad: "46779327", tipoDocumentoIdentidad: "1", }, impuestos: { igv: "27.00" }, valorVenta: { importeTotal: "177.00" }, }, },],});
const { data, error } = await createSummaryDocuments({body: summary,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST "http://localhost:8000/api/v1/summary-documents/create?validate=true" \-H "Content-Type: application/json" \-d '{ "numero": 1, "fechaEmisionComprobantes": "2025-06-10", "proveedor": { "ruc": "20100100100", "razonSocial": "Mi Empresa S.A.C." }, "comprobantes": [{ "tipoOperacion": "1", "comprobante": { "tipoComprobante": "03", "serieNumero": "B001-45", "cliente": { "nombre": "Juan Pérez", "numeroDocumentoIdentidad": "46779327", "tipoDocumentoIdentidad": "1" }, "impuestos": { "igv": "27.00" }, "valorVenta": { "importeTotal": "177.00" } } }]}'Casos especiales
Sección titulada «Casos especiales»Modificación y anulación
Sección titulada «Modificación y anulación»Además de adicionar (tipoOperacion: "1"), puedes modificar ("2") o anular ("3") boletas previamente comunicadas en un resumen diario.
from openubl.models import ( SummaryDocuments, SummaryDocumentsItem, Comprobante, ComprobanteImpuestos, ComprobanteValorVenta, Proveedor, Cliente,)from openubl.renderer import render_summary_documentsfrom openubl.validator import SunatValidatorfrom decimal import Decimalfrom datetime import date
cliente = Cliente( nombre="Juan Pérez", numeroDocumentoIdentidad="46779327", tipoDocumentoIdentidad="1",)
summary = SummaryDocuments( numero=2, fechaEmisionComprobantes=date(2025, 6, 10), proveedor=Proveedor(ruc="20100100100", razonSocial="Mi Empresa S.A.C."), comprobantes=[ SummaryDocumentsItem( tipoOperacion="2", # Modificar comprobante=Comprobante( tipoComprobante="03", serieNumero="B001-45", cliente=cliente, impuestos=ComprobanteImpuestos(igv=Decimal("28.00")), valorVenta=ComprobanteValorVenta(importeTotal=Decimal("178.00")), ), ), SummaryDocumentsItem( tipoOperacion="3", # Anular comprobante=Comprobante( tipoComprobante="03", serieNumero="B001-46", cliente=cliente, impuestos=ComprobanteImpuestos(igv=Decimal("0.00")), valorVenta=ComprobanteValorVenta(importeTotal=Decimal("0.00")), ), ), ],)
xml = render_summary_documents(summary)errors = SunatValidator().validate_schema( xml, "sunat_schemas/xsd_2.1/2.0/maindoc/UBLPE-SummaryDocuments-1.0.xsd",)assert errors == [], errorsprint(xml)import { createSummaryDocuments } from "@openubl/sdk";import { zSummaryDocuments } from "@openubl/sdk/zod.gen";
const cliente = { nombre: "Juan Pérez", numeroDocumentoIdentidad: "46779327", tipoDocumentoIdentidad: "1",};
const summary = zSummaryDocuments.parse({ numero: 2, fechaEmisionComprobantes: "2025-06-10", proveedor: { ruc: "20100100100", razonSocial: "Mi Empresa S.A.C." }, comprobantes: [ { tipoOperacion: "2", comprobante: { tipoComprobante: "03", serieNumero: "B001-45", cliente, impuestos: { igv: "28.00" }, valorVenta: { importeTotal: "178.00" }, }, }, { tipoOperacion: "3", comprobante: { tipoComprobante: "03", serieNumero: "B001-46", cliente, impuestos: { igv: "0.00" }, valorVenta: { importeTotal: "0.00" }, }, }, ],});
const { data, error } = await createSummaryDocuments({ body: summary,});
if (error) { throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST "http://localhost:8000/api/v1/summary-documents/create" \ -H "Content-Type: application/json" \ -d '{ "numero": 2, "fechaEmisionComprobantes": "2025-06-10", "proveedor": { "ruc": "20100100100", "razonSocial": "Mi Empresa S.A.C." }, "comprobantes": [ { "tipoOperacion": "2", "comprobante": { "tipoComprobante": "03", "serieNumero": "B001-45", "cliente": { "nombre": "Juan Pérez", "numeroDocumentoIdentidad": "46779327", "tipoDocumentoIdentidad": "1" }, "impuestos": { "igv": "28.00" }, "valorVenta": { "importeTotal": "178.00" } } }, { "tipoOperacion": "3", "comprobante": { "tipoComprobante": "03", "serieNumero": "B001-46", "cliente": { "nombre": "Juan Pérez", "numeroDocumentoIdentidad": "46779327", "tipoDocumentoIdentidad": "1" }, "impuestos": { "igv": "0.00" }, "valorVenta": { "importeTotal": "0.00" } } } ] }'Respuesta esperada
Sección titulada «Respuesta esperada»{ "xml": "<?xml version='1.0' encoding='UTF-8'?\u003e...", "document_type": "RC", "document_id": "20100100100-RC-20250610-1"}Si validate=true y el cuerpo no cumple las reglas, la API devuelve un error 422 con el detalle de la validación.
`,