Errores y límites de tasa
Referencia completa de códigos de error, mapeo HTTP, políticas de rate limit y estrategias de reintento.
Códigos de estado HTTP
La API REST moderna usa códigos HTTP estándar. El cuerpo de respuesta incluye un objeto de error estructurado.
| Código | Estado | Significado |
|---|---|---|
| 400 | Bad Request | Falló la validación (parámetros faltantes o inválidos) |
| 401 | Unauthorized | Autenticación requerida o clave API inválida |
| 402 | Payment Required | Saldo insuficiente en cartera para completar la acción |
| 403 | Forbidden | Autenticado pero no autorizado para este recurso |
| 404 | Not Found | Recurso no encontrado (ej. ID de activación inexistente) |
| 409 | Conflict | Conflicto con el estado actual (ej. activación ya completada) |
| 422 | Unprocessable Entity | Solicitud bien formada pero semánticamente inválida |
| 429 | Too Many Requests | Rate limit excedido — ver cabecera Retry-After |
| 500 | Internal Server Error | Error inesperado del servidor — reintentar con backoff exponencial |
| 503 | Service Unavailable | Proveedor upstream no disponible — reintentar luego |
Forma de respuesta de error (JSON)
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 27937
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-05-10T00:00:00.000Z
{
"error": "rate_limit_exceeded",
"message": "Daily API limit reached. Contact support for higher tier.",
"retryAfter": 27937,
"limit": 10000,
"usage": 10000
}Códigos de texto SMS-Activate
El endpoint compatible con SMS-Activate devuelve códigos en texto plano. Cada código se mapea a un estado HTTP.
| Código texto | HTTP | Significado |
|---|---|---|
| BAD_KEY | 401 | Clave API inválida o ausente |
| BAD_ACTION | 400 | Parámetro action ausente o malformado |
| BAD_SERVICE | 400 | Código de servicio no reconocido |
| BAD_COUNTRY | 400 | Parámetro country no reconocido |
| BAD_STATUS | 400 | Valor de status inválido para setStatus |
| WRONG_ACTION | 400 | Nombre de acción no soportado |
| NO_BALANCE | 402 | Saldo insuficiente en cartera |
| NO_NUMBERS | 404 | Sin números disponibles para esta combinación |
| NO_ACTIVATION | 404 | ID de activación no encontrado o no tuyo |
| RATE_LIMITED | 429 | Rate limit excedido — desacelera o espera el reset |
| ERROR_SQL | 500 | Error interno del servidor — reintentar luego |
Rate Limits
Throttle por clave API. Múltiples servidores con la misma clave comparten un único bucket.
Límites de ráfaga
Tres niveles concurrentes protegen de ráfagas y abuso sostenido. Llegar a cualquiera devuelve 429.
Cuota diaria
Por defecto 10,000 solicitudes por clave API por día. Se reinicia a medianoche UTC.
- Los endpoints públicos de catálogo (services, countries) están exentos de la cuota diaria
- El contador incrementa en cada solicitud autenticada, sin importar el estado de respuesta
- Plan Pro con límites más altos disponible — contacta con soporte
Cabeceras de respuesta
Cada respuesta autenticada incluye cabeceras de rate limit para auto-throttle proactivo del cliente.
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9543
X-RateLimit-Reset: 2026-05-10T00:00:00.000Z
Retry-After: 27937Estrategia de reintento
Cómo manejar fallos transitorios sin saturar la API ni perder datos.
Sí
- • Respeta la cabecera Retry-After en respuestas 429
- • Usa backoff exponencial para errores 5xx (1s, 2s, 4s, 8s)
- • Reintenta hasta 5 veces, luego muestra el error al usuario
No
- • No reintentes 4xx excepto 429 — son deterministas
- • No martillees la API tras 429 — espera el periodo Retry-After completo
- • No reintentes POST /activations sin verificar idempotencia
Patrón de reintento recomendado
# Pseudocode — exponential backoff with Retry-After
attempt = 0
while attempt < 5:
response = call_api()
if response.status == 200:
break # success
if response.status == 429:
wait = response.headers.get('Retry-After', 2 ** attempt)
sleep(wait)
attempt += 1
continue
if response.status >= 500:
sleep(2 ** attempt) # exponential
attempt += 1
continue
raise APIError(response) # 4xx other than 429Idempotencia
Algunas operaciones cobran de tu cartera — reintentar ingenuamente puede causar cargos dobles.
POST /activations no es idempotente
Si reintentas un POST /activations exitoso, crearás una segunda activación y se te cobrará dos veces. Ante cualquier timeout o respuesta poco clara, lista activaciones con GET /activations para verificar estado antes de reintentar.
¿Necesitas más detalles?
La referencia API interactiva muestra respuestas de error para cada endpoint.
