Códigos de Error

Referencia completa de los errores que puede retornar la API y cómo manejarlos.

Formato de Respuesta de Error

Todos los errores siguen el mismo formato JSON:

{
"detail": "Mensaje descriptivo en español",
"error_code": "categoria.error_especifico"
}

El campo error_code usa el formato categoria.error para facilitar el manejo programático de errores.

Códigos HTTP

400

Bad Request

La petición tiene un formato inválido o faltan parámetros requeridos.

Posibles causas:

  • Formato de document_id incorrecto
  • JSON malformado en el body
  • Parámetros faltantes o inválidos
401

Unauthorized

No se proporcionó API Key o la key es inválida.

Posibles causas:

  • Header Authorization faltante
  • API Key expirada o revocada
  • Formato incorrecto del Bearer token
403

Forbidden

API Key válida pero sin permisos para el recurso.

Posibles causas:

  • API Key sin Clave SOL configurada (para Receptor)
  • Plan sin acceso a PDF
  • Cuota mensual agotada
  • Trial expirado
404

Not Found

El recurso solicitado no existe.

Posibles causas:

  • Comprobante no existe en SUNAT
  • Endpoint incorrecto
  • El documento aún no está disponible (esperar 24-72 horas)
429

Too Many Requests

Se ha excedido el límite de peticiones.

Posibles causas:

  • Demasiadas peticiones por minuto
  • Cuota mensual agotada
500

Internal Server Error

Error interno del servidor.

Posibles causas:

  • Error inesperado en el servidor
  • Problema temporal - reintentar
502

Bad Gateway

Error de comunicación con SUNAT.

Posibles causas:

  • Credenciales SUNAT incorrectas
  • SUNAT rechazó la autenticación
503

Service Unavailable

SUNAT no está disponible temporalmente. Incluye header Retry-After.

Posibles causas:

  • SUNAT no responde
  • Problema de red con SUNAT
  • Mantenimiento de SUNAT

Códigos de Error por Categoría

El campo error_code identifica el tipo específico de error:

auth.*

Autenticación

Errores relacionados con la API Key y permisos

CódigoHTTPMensajeAcción
auth.invalid_api_key401API Key inválida o no proporcionadaVerificar API Key en el dashboard
auth.api_key_required401Este endpoint requiere autenticación con API KeyUsar API Key (sk_live_xxx) en vez de session token
auth.trial_expired403Tu período de prueba ha terminadoSuscribirse a un plan o comprar una bolsa
auth.max_rucs_exceeded403Has alcanzado el límite de RUCs para tu planActualizar a un plan superior
auth.feature_not_allowed403Función no disponible en tu plan actualActualizar plan para acceder a esta función
validation.*

Validación

Errores en el formato de los datos enviados

CódigoHTTPMensajeAcción
validation.bad_request400Solicitud inválidaRevisar formato del request
validation.invalid_ruc400RUC debe ser exactamente 11 dígitos numéricosValidar RUC antes de enviar
validation.invalid_document_id400Formato de documento inválidoUsar formato: {RUC}-{TipoDoc}-{Serie}-{Numero}
sunat.*

SUNAT

Errores relacionados con la comunicación con SUNAT

CódigoHTTPMensajeAcción
sunat.auth_failed502No se pudo validar las credenciales SUNATVerificar RUC/Usuario/Clave SOL en el dashboard
sunat.request_failed503No se pudo obtener el documento de SUNATReintentar usando el header Retry-After
sunat.credentials_not_configured400API Key sin credenciales SUNAT configuradasConfigurar Clave SOL en la API Key (solo Receptor)
rate_limit.*

Rate Limiting

Límites de peticiones excedidos

CódigoHTTPMensajeAcción
rate_limit.exceeded429Límite de peticiones excedidoEsperar según header Retry-After
server.*

Servidor

Errores internos del servidor

CódigoHTTPMensajeAcción
server.service_unavailable503Servicio no disponible temporalmenteReintentar usando el header Retry-After
server.internal_error500Error interno del servidorContactar soporte si persiste

Manejo de Errores Recomendado

async function downloadXML(documentId: string) {
try {
const response = await fetch(
`https://api.integracpe.com/api/v1/sunat/receptor/xml/${documentId}`,
{
headers: {
'Authorization': 'Bearer sk_live_tu_api_key'
}
}
);
if (!response.ok) {
const error = await response.json();
const [category] = error.error_code.split('.');
switch (category) {
case 'auth':
if (error.error_code === 'auth.trial_expired') {
console.log('Trial expirado. Suscríbete a un plan.');
// Redirigir a página de planes
} else {
console.log('Error de autenticación:', error.detail);
}
break;
case 'sunat':
if (error.error_code === 'sunat.request_failed') {
const retryAfter = response.headers.get('Retry-After');
console.log(`SUNAT no disponible. Reintentar en ${retryAfter}s`);
// Implementar retry con backoff
}
break;
case 'rate_limit':
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limit. Esperar ${retryAfter}s`);
break;
case 'validation':
console.log('Error de validación:', error.detail);
// Mostrar error al usuario
break;
default:
console.log('Error:', error.detail);
}
throw new Error(error.detail);
}
return await response.json();
} catch (error) {
console.error('Error de conexión:', error);
throw error;
}
}

Política de Reintentos

Reintentar

  • 429 - Rate limit (usar Retry-After)
  • 500 - Error interno (esperar 5s)
  • 502 - Bad Gateway (esperar 30s)
  • 503 - SUNAT no disponible (usar Retry-After)

No Reintentar

  • 400 - Request inválido
  • 401 - API Key inválida
  • 403 - Sin permisos / Trial expirado
  • 404 - No encontrado

Rate Limiting

La API incluye headers informativos sobre tu uso actual:

HeaderDescripción
X-RateLimit-LimitPeticiones permitidas por minuto
X-RateLimit-RemainingPeticiones restantes en el período actual
X-RateLimit-Limit-TypeTipo de límite: per-minute o per-month
Retry-AfterSegundos a esperar antes de reintentar (en 429 y 503)

Logging

Guarda el error_code completo en tus logs para facilitar el debugging. Es más útil que solo el código HTTP.

Soporte

Si encuentras un error que no puedes resolver, contacta a soporte@integracpe.com incluyendo el request ID (header X-Request-ID).