Errores
Toda respuesta de error tiene la misma forma JSON, idéntica a la de Resend:
{ "statusCode": 422, "name": "validation_error", "message": "`from`: Invalid email address"}Bifurca según name, que es estable. message es para personas y puede cambiar. En el SDK de Node, los errores llegan como { data: null, error } con los mismos tres campos; los fallos de red usan name: "application_error" y statusCode: null.
import { SpacePost } from "@spacepost/node";
const spacepost = new SpacePost();
const { data, error } = await spacepost.emails.send({ from: "Acme <hello@acme.com>", to: "user@example.com", subject: "Hello", html: "<p>Hello</p>",});
if (error) { switch (error.name) { case "rate_limit_exceeded": // wait about a second, then retry with the same idempotency key break; case "daily_quota_exceeded": case "monthly_quota_exceeded": // alert someone: you hit a limit break; case "validation_error": case "invalid_from_address": // a bug in your request: do not retry throw new Error(`${error.name}: ${error.message}`); default: console.error(error.statusCode, error.name, error.message); }} else { console.log(data.id);}Tabla de errores
Sección titulada «Tabla de errores»| Estado | name |
Significado y solución |
|---|---|---|
| 400 | invalid_idempotency_key |
El encabezado Idempotency-Key no tiene entre 1 y 256 caracteres. |
| 401 | missing_api_key |
Falta el encabezado Authorization: Bearer sp_live_.... |
| 401 | restricted_api_key |
La clave no puede hacer esto: una clave sending_access usada en un endpoint que no es de envío, o una clave restringida a un dominio que envía desde otro dominio. |
| 403 | invalid_api_key |
La clave es desconocida, fue revocada o no es una clave de SpacePost (por ejemplo, una clave re_ de Resend). |
| 403 | invalid_from_address |
El dominio de from no es un dominio verificado de tu equipo. |
| 403 | sending_paused |
Tu equipo está pausado, normalmente tras tasas altas de rebotes o quejas, o (cuando pasas tenant_id o envías desde un dominio propiedad de un tenant) ese tenant está pausado. Consulta Pausa automática. |
| 403 | validation_error |
Una petición válida pero no permitida: usar test.spacepost.dev para escribir a destinatarios que no sean tu equipo ni direcciones de prueba, o superar el límite de dominios de tu plan. |
| 403 | invalid_access |
Sesión del panel sin acceso al equipo solicitado, o POST /tenants/{ref}/unpause sobre un tenant que se pausó por su tasa de rebotes o quejas desde un equipo que no es trusted. Contacta con soporte. |
| 404 | not_found |
El recurso no existe (o pertenece a otro equipo), o el endpoint no existe. |
| 405 | method_not_allowed |
El método HTTP no es compatible con esta ruta. |
| 409 | concurrent_idempotent_requests |
La misma clave de idempotencia aún se está procesando. Reintenta en breve. |
| 409 | invalid_idempotent_request |
La clave de idempotencia ya se usó con un cuerpo de petición distinto. |
| 422 | validation_error |
Falta un campo o no es válido. El mensaje lo indica. También: “Only scheduled emails can be canceled”, “Domain already registered”, JSON no válido, un tenant_id que entra en conflicto con el tenant del dominio, un external_id de tenant duplicado, eliminar un tenant que aún tiene dominios. |
| 422 | invalid_parameter |
Un parámetro de consulta o de ruta no es válido. |
| 429 | rate_limit_exceeded |
Se superó tu límite de peticiones por segundo. Espera los segundos indicados en retry-after. |
| 429 | daily_quota_exceeded |
Se alcanzó el límite diario de envío (el sandbox de cuenta nueva, tu tope por nivel de confianza o el daily_limit de un tenant). |
| 429 | monthly_quota_exceeded |
Se alcanzó el límite mensual del plan Free. Mejora tu plan o espera. |
| 451 | security_error |
El correo fue bloqueado por el filtrado de contenido (archivo adjunto ejecutable, indicadores de phishing o spam). Cambia el contenido; no reintentes tal cual. |
| 500 | application_error |
Error inesperado de la API. Reintenta con espera creciente. |
| 500 | internal_server_error |
“An unexpected error occurred, please try again later”. Reintenta con espera creciente; contacta con soporte si persiste. |
Reintentos
Sección titulada «Reintentos»| ¿Reintentar? | Errores |
|---|---|
Sí, tras los segundos de retry-after |
rate_limit_exceeded |
Sí, con espera exponencial y la misma Idempotency-Key |
500, errores de red, concurrent_idempotent_requests |
| No, corrige la petición | 400, 401, 403, 404, 422 |
| No, espera a que se reinicie el límite o mejora tu plan | daily_quota_exceeded, monthly_quota_exceeded |
| No, consulta con soporte (o reanuda un tenant que pausaste tú mismo) | sending_paused, security_error |
Webhooks y fallos asíncronos
Sección titulada «Webhooks y fallos asíncronos»Los errores anteriores se devuelven cuando haces una petición. Los problemas que ocurren después de aceptarse un correo (rebotes, rechazos) llegan como eventos de webhook y en el last_event del correo.
Por SMTP, las mismas condiciones se devuelven como códigos de respuesta SMTP: errores de cuota 452, límite de tasa 421, remitente no válido 553, otros rechazos 550, fallos temporales 451.