Quién envía a SUNAT
Elige si el comprobante sale solo al firmarlo o lo envía la empresa cuando quiera.
Autenticación: token Bearer de cuenta (empresas:manage).
Consideraciones
- Por defecto es
automatic: firmar encola el envío y no hay que hacer nada más. - En
manual, POST /v1/cpe respondeestado: "por_enviar"y el comprobante queda firmado esperando. Se manda conPOST /v1/cpe/{external_id}/enviar. - Manual es decidir CUÁNDO, no SI. Pasadas 12 horas el comprobante se envía igual: SUNAT tiene plazos y un comprobante firmado que nunca se informa es un incumplimiento del emisor.
- La firma ya se consumió al emitir: el modo de envío no cambia lo que se cobra ni cuándo.
Para qué sirve
Por defecto nosotros llevamos el envío: firmas y el comprobante sale hacia SUNAT sin que tengas que hacer nada. Es lo que quiere la mayoría.
El modo manual es para quien necesita revisar antes de que salga — o
elegir el momento, por ejemplo agrupando los envíos al cierre del día. El
comprobante se firma igual, queda en estado Por enviar, y sale cuando tú lo
mandes:
curl -X POST https://api.xmlperu.dev/v1/cpe/$EXTERNAL_ID/enviar \
-H "Authorization: Bearer $TOKEN_EMPRESA"
También puedes mandarlo desde el panel, en el listado de comprobantes.
El plazo
Pasadas 12 horas en «Por enviar», el comprobante se envía solo.
No es quitarte el control: es el suelo por debajo del cual no te dejamos caer. Un comprobante firmado y nunca informado es un incumplimiento tuyo ante SUNAT, y llevaría nuestra firma dentro. El modo manual decide cuándo sale, dentro del plazo, no si sale.
Lo que no cambia
La firma se consume al emitir, no al enviar: cambiar el modo no altera lo que se
cobra. Y el resultado se consulta igual, con
GET /v1/cpe/{external_id}.
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 |
|---|---|---|
| ruc* | string | RUC de 11 dígitos de la empresa. |
Body
| Name | Type | Description |
|---|---|---|
| mode* | string | automatic (por defecto) · manual. |
Ejemplo de solicitud
curl -X PATCH https://api.xmlperu.dev/v1/companies/20123456789/sending \
-H "Authorization: Bearer $TOKEN_CUENTA" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"mode": "manual"
}'<?php
$token_cuenta = 'pega-aqui-tu-token';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xmlperu.dev/v1/companies/20123456789/sending');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token_cuenta,
'Accept: application/json',
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"mode": "manual"
}
JSON);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);const TOKEN_CUENTA = 'pega-aqui-tu-token';
const res = await fetch('https://api.xmlperu.dev/v1/companies/20123456789/sending', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${TOKEN_CUENTA}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"mode": "manual"
}),
});
const data = await res.json();import requests
TOKEN_CUENTA = "pega-aqui-tu-token"
headers = {
"Authorization": f"Bearer {TOKEN_CUENTA}",
"Accept": "application/json",
}
payload = {
"mode": "manual"
}
res = requests.patch("https://api.xmlperu.dev/v1/companies/20123456789/sending", json=payload, headers=headers)
data = res.json()Respuesta
{
"success": true,
"message": "Modo de envío actualizado.",
"data": {
"company": {
"ruc": "20123456789",
"business_name": "MI EMPRESA SAC",
"plan_type": "01",
"environment": "02",
"environment_name": "production",
"sending": "manual",
"is_active": true
}
}
}{
"success": false,
"message": "Datos inválidos",
"errors": { "mode": ["El campo mode seleccionado es inválido."] }
}