Migrar desde Emailable
Esta guía explica cómo sustituir las llamadas de verificación de Emailable por
Mailbeam. La mayoría de las migraciones llevan entre 30 y 60 minutos: el trabajo
es cambiar una petición y traducir la cadena state de Emailable al booleano más
puntuación de Mailbeam.
Por qué se cambia la gente
- Residencia del dato en la UE: Emailable trata los datos en infraestructura estadounidense, así que una empresa europea necesita cláusulas contractuales tipo; Mailbeam trata en Fráncfort con un DPA en todos los planes
- Hecho para formularios: la latencia de Emailable para una dirección ronda los 250 ms, lento para validar mientras alguien todavía escribe
- Catch-all graduado: Emailable devuelve los dominios accept-all como
riskyounknownsin nada con lo que fijar un umbral; Mailbeam añade una puntuación de 0 a 100 y unreason - Precios que se pueden aislar: los paquetes de créditos más los complementos de entregabilidad con precio aparte hacen difícil leer cuánto cuesta la verificación en sí
- Modo de pruebas: un modo determinista para CI, en vez de llamar a producción
Una cosa juega de verdad a favor de Emailable: ofrece pruebas de colocación en bandeja con direcciones semilla y monitorización continua de entregabilidad, algo que Mailbeam deliberadamente no hace. Los equipos que necesitan eso suelen quedarse con Emailable para la entregabilidad y mover solo la verificación.
Equivalencia de endpoints
| Emailable | Mailbeam | Notas |
|---|---|---|
GET /v1/verify?email=&api_key= | POST /v1/verify | Verificación de un email |
POST /v1/batch | POST /v1/verify/batch | Hasta 500 000 direcciones por trabajo |
GET /v1/batch?id= | GET /v1/jobs/{id} | Estado del lote |
Autenticación
Emailable pasa la clave de API como parámetro en la URL, lo que significa que acaba en los logs de acceso, en el historial del navegador y en las trazas de los proxies. Mailbeam toma un token Bearer en la cabecera, así que la credencial se queda fuera de la URL.
Emailable (antes):
curl "https://api.emailable.com/v1/verify?email=user@example.com&api_key=YOUR_KEY"Mailbeam (ahora):
curl -X POST https://api.mailbeam.dev/v1/verify \
-H "Authorization: Bearer $MAILBEAM_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'Equivalencia de respuestas
Emailable informa con una única cadena state. Mailbeam reparte la misma
información en un booleano sobre el que ramificar y una puntuación con la que
fijar umbrales.
| Campo de Emailable | Equivalente en Mailbeam |
|---|---|
state: "deliverable" | valid: true, score >= 70 |
state: "undeliverable" | valid: false |
state: "risky" | valid: true, score 30-69 |
state: "unknown" | status: "unknown" |
reason | reason (código legible por máquina) |
disposable | disposable |
role | role |
accept_all | catchAll más un score graduado |
Migrar la llamada
Emailable (antes):
const res = await fetch(
`https://api.emailable.com/v1/verify?email=${email}&api_key=${apiKey}`
);
const { state } = await res.json();
if (state !== "deliverable") return 422;Mailbeam (ahora):
// No hay SDK que instalar: mira /docs/quickstart para este envoltorio de 12 líneas.
import { verifyEmail } from "./lib/mailbeam.js";
const { valid, score, reason } = await verifyEmail(email);
if (!valid || score < 60) return 422;Fíjate en lo que hacía la rama antigua: state !== "deliverable" rechaza
risky y unknown junto con los fallos de verdad. Si tu embudo de registro
estaba descartando en silencio direcciones corporativas accept-all, ahí es donde
ocurría.
Lo primero que revisar: risky y unknown
Emailable mete dos situaciones distintas en cadenas que tienes que interpretar.
Un dominio accept-all y un servidor que se negó a responder llegan los dos como
algo distinto de deliverable, y la mayoría de las integraciones rechazan
ambos. Mailbeam los separa, así que puedes decidir una vez y para cada caso:
const { valid, status, catchAll, score, reason } = await verifyEmail(email);
if (status === "unknown") {
// El servidor no quiso responder: greylisting, tiempo agotado, rechazo temporal.
// Esto no es prueba de que el buzón sea malo. Acepta y reverifica más tarde.
return acceptPendingReverification();
}
if (catchAll) {
return score >= 70 ? accept() : challenge({ reason });
}
return valid ? accept() : reject({ reason });