Reenviar a SUNAT
Vuelve a encolar el envío de un comprobante firmado que no llegó a resolverse.
Autenticación: token Bearer de empresa (cpe:sign).
Consideraciones
- Responde
202apenas encola: no devuelve el CDR. El resultado se consulta con GET /v1/cpe/{external_id}. - Casi nunca hace falta. POST /v1/cpe ya firma y manda en un solo paso, y los fallos de red se reintentan solos.
- Es idempotente: llamarlo repetido no envía el comprobante dos veces.
- Si SUNAT ya respondió (aceptado, observado o rechazado) devuelve
409: no hay nada que enviar. - Sirve para comprobantes y también para resúmenes (RC/RA/RR) y guías (09/31).
Cuándo usar este endpoint
Casi nunca. POST /v1/cpe ya firma y manda el comprobante, y los fallos de red se reintentan solos
los fallos de red con esperas crecientes.
Queda para el caso raro: un comprobante firmado que se quedó sin resolver. Por ejemplo, un envío que agotó sus reintentos, o uno que nunca llegó a encolarse.
Antes de usarlo, consulta el comprobante. Si resolved es true, no hay nada que
hacer; si es false, lo más probable es que siga en camino y solo haya que
esperar.
Qué pasa si SUNAT falla
La cola reintenta los fallos de conexión con esperas crecientes (10 s, 30 s, 2 min, 10 min). Un rechazo de SUNAT no se reintenta: es una respuesta, no un fallo, y el comprobante queda rechazado.
El caso delicado es el timeout. Ahí la petición sí salió, y SUNAT pudo haberla registrado; reenviar arriesga duplicar el comprobante. Por eso el envío no se reintenta: el comprobante queda en Pendiente y un proceso periódico consulta su estado hasta resolverlo. Tú no tienes que hacer nada — solo no reenviarlo a ciegas por tu cuenta.
Headers
| Name | Type | Description |
|---|---|---|
| Accept | string | application/json |
| Content-Type | string | application/json |
| Authorization | string | Bearer <token>. Genéralo desde tu panel, en Tokens de API. |
Parámetros de URL
| Name | Type | Description |
|---|---|---|
| external_id* | string | Identificador del comprobante devuelto al emitir. |
Ejemplo de solicitud
curl -X POST https://api.xmlperu.dev/v1/cpe/9c2f1b7e-0000-0000-0000-000000000000/resend \
-H "Authorization: Bearer $TOKEN_EMPRESA" \
-H "Accept: application/json"<?php
$token_empresa = 'pega-aqui-tu-token';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xmlperu.dev/v1/cpe/9c2f1b7e-0000-0000-0000-000000000000/resend');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token_empresa,
'Accept: application/json',
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);const TOKEN_EMPRESA = 'pega-aqui-tu-token';
const res = await fetch('https://api.xmlperu.dev/v1/cpe/9c2f1b7e-0000-0000-0000-000000000000/resend', {
method: 'POST',
headers: {
Authorization: `Bearer ${TOKEN_EMPRESA}`,
Accept: 'application/json',
},
});
const data = await res.json();import requests
TOKEN_EMPRESA = "pega-aqui-tu-token"
headers = {
"Authorization": f"Bearer {TOKEN_EMPRESA}",
"Accept": "application/json",
}
res = requests.post("https://api.xmlperu.dev/v1/cpe/9c2f1b7e-0000-0000-0000-000000000000/resend", headers=headers)
data = res.json()Respuesta
{
"success": true,
"status": "queued",
"message": "El envío quedó encolado. Consulta el estado del comprobante para conocer el resultado.",
"external_id": "9c2f1b7e-…"
}{
"success": false,
"message": "El comprobante ya tiene respuesta de SUNAT. Consulta su estado con GET /v1/cpe/{external_id}."
}{
"success": false,
"message": "El comprobante no existe."
}{
"success": false,
"message": "El comprobante no pertenece a esta empresa."
}