Estructura del XML UBL (antes de firmar)
/emision/firmar recibe un XML UBL 2.1 sin firmar — tú lo generas con los datos del comprobante, nosotros solo lo firmamos y lo enviamos a SUNAT. Esta página describe exactamente qué estructura debe tener ese XML según el Manual del Programador SUNAT (RS-097-2012), para que no tengas que ir a buscarlo en otro lado.
1. Configuración de la API
Entornos
A diferencia de otros proveedores, no usamos subdominios distintos para pruebas y producción — todo pasa por la misma URL base. El ambiente es un atributo de tu cuenta (lo configuramos al activar el servicio) y se refleja en el campo ambiente de cada respuesta.
| Ambiente | URL base | Descripción |
|---|---|---|
| Beta | https://mblapirest.com/api | Pruebas y simulaciones — no se envía nada real a SUNAT. |
| Producción | https://mblapirest.com/api | Los comprobantes se envían de verdad; SUNAT los acepta o rechaza en definitiva. |
Endpoints de este flujo (XML propio)
| Método | Path | Descripción |
|---|---|---|
| POST | /v1/emision/firmar | Firma el XML sin firmar (esta página) y arma el ZIP para SUNAT. |
| POST | /v1/emision/enviar | Envía el ZIP ya firmado a SUNAT (sendBill). |
Para el catálogo completo de endpoints (armar+firmar+enviar en un solo paso, consultas, historial), ver Emisión de comprobantes.
Encabezados HTTP
| Nombre | Valor |
|---|---|
X-Api-Key | Tu token de cuenta con el servicio "Emisión de Comprobantes" habilitado — distinto al Authorization: Bearer que usa el resto de la API (ver Autenticación). |
Content-Type | application/json |
2. Elemento raíz según el tipo de documento
El nombre del elemento raíz del XML cambia según id_tipodoc_electronico:
| id_tipodoc_electronico | Documento | Elemento raíz UBL |
|---|---|---|
01 | Factura | <Invoice> |
03 | Boleta | <Invoice> |
07 | Nota de Crédito | <CreditNote> |
08 | Nota de Débito | <DebitNote> |
09 | Guía de Remisión Remitente | <DespatchAdvice> |
31 | Guía de Remisión Transportista | <DespatchAdvice> |
3. Namespaces obligatorios
El elemento raíz debe declarar estos namespaces (usando Invoice como ejemplo, el patrón es igual para los demás):
<Invoice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2">
4. El nodo vacío para la firma (obligatorio, aunque tú no firmes nada)
Justo después de abrir el elemento raíz, debe existir este nodo — vacío, nosotros lo llenamos al firmar. Si falta, /emision/firmar devuelve error ("No se encontró el nodo ExtensionContent vacío para insertar la firma"):
<ext:UBLExtensions>
<ext:UBLExtension>
<ext:ExtensionContent></ext:ExtensionContent>
</ext:UBLExtension>
</ext:UBLExtensions>
Nosotros insertamos ahí el <ds:Signature Id="SignSUNAT"> completo (RSA-SHA1, canonicalización C14N) al llamar /emision/firmar. No necesitas construir la firma tú mismo — solo dejar el espacio.
5. Campos mínimos obligatorios (cabecera)
| Campo | Elemento | Notas |
|---|---|---|
| Versión UBL | cbc:UBLVersionID | Siempre 2.1 |
| Versión del documento | cbc:CustomizationID | 2.0 para Factura/Boleta/NC/ND |
| Serie y número | cbc:ID | Formato F001-123 (Factura), B001-123 (Boleta) |
| Fecha de emisión | cbc:IssueDate | Formato YYYY-MM-DD |
| Tipo de documento | cbc:InvoiceTypeCode | Catálogo 01 de SUNAT (01=Factura, 03=Boleta) |
| Moneda | cbc:DocumentCurrencyCode | PEN o USD |
| Firma (referencia) | cac:Signature | Referencia al nodo firmado, con datos del emisor |
| Emisor | cac:AccountingSupplierParty | RUC, razón social, dirección fiscal |
| Cliente | cac:AccountingCustomerParty | Tipo/número de documento, nombre |
| Totales | cac:LegalMonetaryTotal | Subtotal, IGV, total a pagar |
| Detalle | cac:InvoiceLine (o CreditNoteLine/DebitNoteLine) | Uno por cada ítem/producto |
6. Ejemplo completo — Factura simple (una línea, sin descuentos)
XML mínimo válido para una factura de S/ 118.00 (S/ 100.00 + IGV 18%), un solo ítem. Reemplaza los datos reales y conviértelo a base64 para xml_sin_firmar.
<?xml version="1.0" encoding="UTF-8"?>
<Invoice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
<ext:UBLExtensions>
<ext:UBLExtension>
<ext:ExtensionContent></ext:ExtensionContent>
</ext:UBLExtension>
</ext:UBLExtensions>
<cbc:UBLVersionID>2.1</cbc:UBLVersionID>
<cbc:CustomizationID>2.0</cbc:CustomizationID>
<cbc:ID>F001-123</cbc:ID>
<cbc:IssueDate>2026-07-27</cbc:IssueDate>
<cbc:InvoiceTypeCode listID="0101">01</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>PEN</cbc:DocumentCurrencyCode>
<cac:Signature>
<cbc:ID>IDSignSUNAT</cbc:ID>
<cac:SignatoryParty>
<cac:PartyIdentification><cbc:ID>20611187620</cbc:ID></cac:PartyIdentification>
<cac:PartyName><cbc:Name><![CDATA[667 E&J GROUP S.A.C.]]></cbc:Name></cac:PartyName>
</cac:SignatoryParty>
<cac:DigitalSignatureAttachment>
<cac:ExternalReference><cbc:URI>#SignSUNAT</cbc:URI></cac:ExternalReference>
</cac:DigitalSignatureAttachment>
</cac:Signature>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification><cbc:ID schemeID="6">20611187620</cbc:ID></cac:PartyIdentification>
<cac:PartyLegalEntity>
<cbc:RegistrationName><![CDATA[667 E&J GROUP S.A.C.]]></cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cac:PartyIdentification><cbc:ID schemeID="6">20123456789</cbc:ID></cac:PartyIdentification>
<cac:PartyLegalEntity>
<cbc:RegistrationName><![CDATA[CLIENTE DE PRUEBA S.A.C.]]></cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="PEN">18.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="PEN">100.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="PEN">18.00</cbc:TaxAmount>
<cac:TaxCategory>
<cac:TaxScheme><cbc:ID>1000</cbc:ID><cbc:Name>IGV</cbc:Name><cbc:TaxTypeCode>VAT</cbc:TaxTypeCode></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="PEN">100.00</cbc:LineExtensionAmount>
<cbc:TaxInclusiveAmount currencyID="PEN">118.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="PEN">118.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="NIU">1</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="PEN">100.00</cbc:LineExtensionAmount>
<cac:PricingReference>
<cac:AlternativeConditionPrice>
<cbc:PriceAmount currencyID="PEN">118.00</cbc:PriceAmount>
<cbc:PriceTypeCode>01</cbc:PriceTypeCode>
</cac:AlternativeConditionPrice>
</cac:PricingReference>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="PEN">18.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="PEN">100.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="PEN">18.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:Percent>18</cbc:Percent>
<cbc:TaxExemptionReasonCode>10</cbc:TaxExemptionReasonCode>
<cac:TaxScheme><cbc:ID>1000</cbc:ID><cbc:Name>IGV</cbc:Name><cbc:TaxTypeCode>VAT</cbc:TaxTypeCode></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Description><![CDATA[Producto o servicio de ejemplo]]></cbc:Description>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="PEN">100.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>
7. Diferencias para Boleta, Notas y Guías
| Documento | Diferencia principal respecto a la Factura |
|---|---|
| Boleta (03) | Mismo elemento <Invoice>, InvoiceTypeCode = 03, cliente normalmente con DNI (schemeID="1") en vez de RUC. |
| Nota de Crédito (07) | Elemento raíz <CreditNote>, agrega cac:DiscrepancyResponse (motivo) y cac:BillingReference (comprobante que se está afectando). |
| Nota de Débito (08) | Elemento raíz <DebitNote>, misma lógica que la Nota de Crédito. |
| Guía de Remisión Remitente (09) | Elemento raíz <DespatchAdvice>, estructura distinta: no lleva montos/IGV, sí cac:DespatchSupplierParty, cac:DeliveryCustomerParty, cac:Shipment (origen/destino/transportista). |
| Guía de Remisión Transportista (31) | Mismo elemento <DespatchAdvice> que la Remitente, pero DespatchAdviceTypeCode = 31, el emisor (cac:DespatchSupplierParty) es la empresa de transporte, y agrega cac:OriginatorCustomerParty (dueño de la carga) + conductor(es)/vehículo(s) propios en cac:ShipmentStage. |
8. ¿No quieres armar el XML tú mismo?
No hace falta — /emision/emitir-simple, /emision/emitir-guia-simple y /emision/emitir-guia-transportista-simple arman este XML por ti a partir de datos simples en JSON (armamos, firmamos y enviamos en un solo paso). Esta guía te sirve solo si necesitas el control total: mezclar más de una afectación de IGV en el mismo comprobante, o generar el XML desde tu propio sistema. Ver Emisión de comprobantes para todas las variantes ya resueltas.
Referencia oficial
Esta estructura sigue el Manual del Programador SUNAT — Resolución de Superintendencia N.° 097-2012/SUNAT y sus anexos, la fuente oficial y definitiva ante cualquier duda o cambio normativo.
Última actualización: 03/09/2026