Enviar un correo en una demo es fácil. Enviar cien mil al mes en producción implica prepararse para los momentos en que algo falla: una clave revocada, una tarjeta caducada, un mes que se acaba antes de lo previsto, un servidor de correo que tiene un mal día.
Esta guía explica cada respuesta que devuelve el endpoint de envío de Inbixio, qué debe hacer tu código ante cada una y cómo vigilar la entrega una vez en producción.
Dos fases: aceptado y, después, entregado
Una llamada a POST /api/send-email/ se produce en dos fases:
- La solicitud a la API. Inbixio comprueba tu clave, sus permisos, tu suscripción, tu uso mensual y el cuerpo de la solicitud. Si todo está en orden, devuelve
200y pone el mensaje en cola. - La entrega. Un momento después, Inbixio se conecta a tu servidor SMTP y le entrega el mensaje. Cada mensaje se registra como enviado o fallido, y esos resultados alimentan las cifras de tu panel.
Así que un 200 significa «aceptado para su entrega», no «en la bandeja de entrada». Los problemas de la fase 1 vuelven como errores HTTP que tu código puede gestionar. Los de la fase 2, como una contraseña SMTP incorrecta, aparecen en la tasa de entregas fallidas del panel. Inbixio hace un único intento de entrega por mensaje; no reintenta una entrega fallida.
Cada respuesta y qué hacer
| Estado | Cuerpo | Significado | Qué debe hacer tu código |
|---|---|---|---|
200 |
{"message": "Email queued successfully."} |
Aceptado | Nada más |
400 |
{"error": "to_email, subject, and message are required."} |
Falta un campo o está vacío | Corregir la solicitud; no reintentar |
400 |
{"error": "to_email must be a single valid email address."} |
No es exactamente una dirección válida | Corregir la solicitud; no reintentar |
400 |
{"error": "subject must be a single line of at most 500 characters."} |
Asunto demasiado largo o con un salto de línea | Corregir la solicitud; no reintentar |
400 |
{"error": "message must be text of at most 1,000,000 characters."} |
Cuerpo demasiado grande | Corregir la solicitud; no reintentar |
400 |
{"error": "No SMTP configuration found. Please add an email server first."} |
No hay ningún servidor conectado | Añadir un servidor en el panel |
401 |
{"detail": "API key missing"} |
Falta la cabecera X-API-Key |
Corregir la configuración; no reintentar |
401 |
{"detail": "Invalid API key"} |
Clave incorrecta, renovada o eliminada | Actualizar la clave; avisar a tu equipo |
401 |
{"detail": "API key access not allowed"} |
La clave se ha desactivado | Usar otra clave; avisar a tu equipo |
402 |
{"error": "An active subscription is required to send emails."} |
Suscripción inactiva | Resolver la facturación; avisar a tu equipo |
403 |
{"error": "This API key does not have send permission."} |
La clave no tiene Send | Activar Send o usar otra clave |
429 |
{"error": "Monthly email limit reached for your plan.", "limit": 25000, "sent": 25000} |
Límite del plan alcanzado | Mejorar el plan o retener el correo hasta el mes siguiente; no reintentar |
429 |
{"detail": "Request was throttled. Expected available in 12 seconds."} |
Demasiadas solicitudes con esta clave en poco tiempo (límite de frecuencia) | Esperar lo que indique la cabecera Retry-After y reintentar |
503 |
{"error": "Too many emails are waiting to be sent. Please retry in a few seconds."} |
Saturación temporal | Esperar lo que indique la cabecera Retry-After y reintentar |
5xx / tiempo de espera agotado |
— | Problema temporal | Reintentar con espera progresiva |
Los mensajes de error llegan en error en la mayoría de las respuestas y en detail en los errores de autenticación, así que lee ambos:
const body = await res.json().catch(() => ({}));
const reason = body.error ?? body.detail ?? res.statusText;
Reintenta solo lo que puede funcionar más tarde
Reintentar un 401 cien veces no hará que la clave sea válida; solo llenará tus registros. Divide los errores en dos grupos:
- Reintentar: errores de red, tiempos de espera agotados, respuestas
5xxy el429por límite de frecuencia (el que trae un mensaje endetail). Espera lo que indique la cabeceraRetry-After; si no la hay, usa una espera exponencial con variación aleatoria (jitter) y abandona tras unos pocos intentos. - No reintentar:
400,401,402,403y el429por límite mensual (el que traelimitysent). Requieren a una persona o una solicitud distinta. Regístralos de forma bien visible y genera alertas para401,402y el429por límite mensual, porque detienen todo tu correo.
// 5xx and the short-term rate limit can succeed later; the monthly limit (body has `limit`) can't.
const retryable = (status, body) => status >= 500 || (status === 429 && body.limit === undefined);
export async function sendWithRetry(payload, attempts = 4) {
for (let i = 0; i < attempts; i++) {
let res;
try {
res = await fetch('https://backend.inbixio.com/api/send-email/', {
method: 'POST',
headers: { 'X-API-Key': process.env.INBIXIO_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(15_000),
});
} catch (err) {
if (i === attempts - 1) throw err; // network error or timeout: retry
}
if (res?.ok) return res.json();
if (res) {
const body = await res.json().catch(() => ({}));
if (!retryable(res.status, body)) {
throw new Error(`Inbixio ${res.status}: ${body.error ?? body.detail ?? res.statusText}`);
}
}
const retryAfter = Number(res?.headers.get('Retry-After')) * 1000;
const delay = retryAfter || Math.min(30_000, 1000 * 2 ** i) * (0.5 + Math.random()); // 0.5s–30s with jitter
await new Promise((r) => setTimeout(r, delay));
}
throw new Error('Inbixio: gave up after retries');
}
Sobre los duplicados: si una solicitud agota el tiempo de espera, puede que se haya aceptado igualmente. Reintentarla podría enviar el mismo correo dos veces. Para recibos y notificaciones eso suele ser aceptable; para cualquier caso en que un duplicado confundiría a los usuarios, registra lo que has enviado en tu propia base de datos y compruébalo antes de reintentar.
Límites mensuales
Cada plan incluye un número de correos al mes: 25.000 en Starter y 150.000 en Growth. Inbixio cuenta los correos enviados correctamente en el mes natural en curso. Cuando alcanzas el límite, los envíos devuelven 429 con tu limit y el recuento actual de sent, hasta que empieza el mes siguiente o mejoras tu plan.
No esperes al 429:
- La página API Keys (claves de API) muestra una tarjeta Usage Limit (límite de uso) con los correos enviados este mes frente al límite de tu plan.
- Ponte un recordatorio para revisarla cuando llegues a alrededor del 80 % de tu límite, y planifica la mejora de plan antes de un gran lanzamiento o una importación.
- Para un cálculo de volumen paso a paso, consulta cómo elegir un plan de API de correo.
Fallos de entrega (fase 2)
Cuando la API aceptó un mensaje pero tu servidor SMTP lo rechazó, cuenta como una entrega fallida. El panel muestra la tasa de Failed Deliveries (entregas fallidas) de los últimos 7 días en lugar de una lista de mensajes individuales, así que vigila la tasa y revisa la configuración de tu servidor cuando suba. Las causas habituales:
- Fallo de autenticación: la contraseña del buzón ha cambiado o el proveedor exige ahora una contraseña de aplicación.
- Problemas de conexión: el host o el puerto de la configuración del servidor son incorrectos.
- Límites del proveedor: tu proveedor de correo ha limitado el envío diario del buzón.
- Destinatario rechazado: tu servidor rechazó la dirección durante el envío. Los rebotes que llegan más tarde en forma de correo van al buzón remitente, no a Inbixio, así que revisa también esa bandeja de entrada.
La solución casi siempre está en Email Servers (servidores de correo) o en tu proveedor de correo. La configuración SMTP explicada cubre los casos más comunes.
Qué vigilar en producción
Tu panel de Inbixio te ofrece lo esencial:
- Email Sent (correos enviados) y la tasa de Failed Deliveries de los últimos 7 días, cada uno con la variación respecto a los 7 días anteriores.
- Avg Latency (latencia media): cuánto tarda tu servidor SMTP en aceptar el correo. Un salto repentino suele preceder a los fallos.
- Gráficos de volumen de la API y de correos a lo largo del año, para detectar tendencias y picos estacionales.
- Logs (registros) de cada llamada a la API: ID de evento, endpoint, método, código de estado, tiempo de respuesta y marca de tiempo.
Por tu parte, contabiliza las respuestas distintas de 200 por código de estado y genera una alerta cuando aparezcan 401, 402 o el 429 por límite mensual. Significan que todo el correo se ha detenido, y tus usuarios lo notarán antes que tus registros.
Lista de comprobación
- Trata
200como «en cola»; comprueba los resultados de entrega en el panel - Lee tanto
errorcomodetailen las respuestas de error - Reintenta solo errores de red, tiempos de espera agotados,
5xx,503y el429por límite de frecuencia, respetandoRetry-After - Genera alertas para
401,402y el429por límite mensual - Vigila la tarjeta Usage Limit antes de lanzamientos e importaciones
- Vigila la tasa de Failed Deliveries y corrige la configuración SMTP sin demora
Envíalo con Inbixio
Conecta tu propio servidor SMTP, crea una clave de API con permisos limitados y envía desde cualquier lenguaje con una sola solicitud HTTPS.