Guías por comprobante
Comprobante de retención electrónico por API
JSON mínimo para emitir el comprobante de retención (20) por API cuando eres agente de retención del IGV: proveedor, facturas pagadas e importes retenidos.
Actualizado el
El comprobante de retención (tipo 20) lo emite el agente de retención designado por SUNAT cuando paga facturas a
sus proveedores y retiene un porcentaje del IGV. Casi ninguna MYPE lo es: si SUNAT no te lo comunicó, no lo necesitas.
- Endpoint:
POST /retenciones· alcancecomprobantes.emitir· desde el Plan PRO. - En la empresa: Configuración › Empresa › Datos y facturación SUNAT › «Soy agente de retención».
- Usa el mismo JSON de la API antigua (
/api/retentions); el local va enestablecimiento(código SUNAT) o sale de tu clave.
JSON mínimo
Pagas una factura de S/ 1.000 a un proveedor y retienes el 3 % (S/ 30):
{
"serie_documento": "R001",
"numero_documento": "#",
"fecha_de_emision": "2026-11-04",
"hora_de_emision": "11:00:00",
"codigo_tipo_documento": "20",
"datos_del_proveedor": {
"codigo_tipo_documento_identidad": "6",
"numero_documento": "20512345678",
"apellidos_y_nombres_o_razon_social": "DISTRIBUIDORA NORTE S.A.C.",
"codigo_pais": "PE",
"ubigeo": "150101",
"direccion": "Av. Industrial 450"
},
"codigo_tipo_retencion": "01",
"observaciones": "Retención del pago de la factura F001-120",
"totales": {
"total_retenido": 30,
"total_pagado": 970
},
"documentos": [{
"codigo_tipo_documento": "01",
"serie_documento": "F001",
"numero_documento": "120",
"fecha_de_emision": "2026-11-01",
"codigo_tipo_moneda": "PEN",
"total_documento": 1000,
"pagos": [{ "fecha_de_pago": "2026-11-04", "total_pago": 1000, "codigo_tipo_moneda": "PEN" }],
"fecha_de_retencion": "2026-11-04",
"total_retenido": 30,
"total_a_pagar": 970,
"total_pagado": 970
}]
}
curl -X POST https://pruebas.sistemafacturacionperu.com/api/v1/retenciones \
-H "Authorization: Bearer $SFP_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: retencion-$(uuidgen)" \
-d @retencion.json
<?php
$ch = curl_init('https://pruebas.sistemafacturacionperu.com/api/v1/retenciones');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_TIMEOUT => 90,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SFP_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => file_get_contents('retencion.json'),
]);
$retencion = json_decode(curl_exec($ch), true)['data'];
const res = await fetch('https://pruebas.sistemafacturacionperu.com/api/v1/retenciones', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SFP_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': randomUUID(),
},
body: await readFile('retencion.json', 'utf8'),
});
const { data: retencion } = await res.json();
r = requests.post(
"https://pruebas.sistemafacturacionperu.com/api/v1/retenciones",
json=json.load(open("retencion.json", encoding="utf-8")),
headers={"Authorization": f"Bearer {os.environ['SFP_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
timeout=90,
)
retencion = r.json()["data"]
Respuesta (201):
{
"success": true,
"data": {
"id": 33,
"tipo": "20",
"numero_completo": "R001-33",
"fecha_emision": "2026-11-04",
"estado": { "codigo": "05", "clave": "aceptado", "descripcion": "Aceptado" },
"sunat": { "codigo": "0", "descripcion": "El Comprobante numero R001-33, ha sido aceptado", "notas": [] },
"enlaces_publicos": { "pdf": "…", "xml": "…", "cdr": "…" }
}
}
Notas
codigo_tipo_retencion01es la tasa de 3 % del régimen de retenciones del IGV.- El proveedor (
datos_del_proveedor) se crea o actualiza en tus proveedores con esos datos. - Cada línea de
documentoses un comprobante del proveedor que estás pagando. Puedes poner varios. - Si pagas en dólares, agrega en el documento
tipo_de_cambio:{"codigo_tipo_moneda_referencia": "USD", "codigo_tipo_moneda_objetivo": "PEN", "factor": 3.741, "fecha_tipo_de_cambio": "2026-11-04"}. El tipo de cambio de SUNAT del día sale deGET /consultas/tipo-cambio. - No lo confundas con el campo
retencionde una factura de venta (cuando tu cliente es agente de retención y te retiene a ti): ese va dentro dePOST /comprobantesy no se combina con una detracción (422detraccion_con_retencion, ver casos especiales).