API de verificación de correo electrónico: intégrala en 10 minutos (con ejemplos de código)

API de verificación de correo electrónico: intégrala en 10 minutos (con ejemplos de código)

Has decidido añadir la verificación de correo electrónico a tu aplicación. Buena decisión: es el cambio con mayor impacto que puedes hacer para mejorar la calidad de los registros, reducir los rebotes y prevenir el fraude.

Esta guía te ofrece código listo para producción para integrar la verificación de correo electrónico en cualquier stack. Python, JavaScript, PHP, cURL: elige tu lenguaje y copia el código.


Por qué importa la verificación del lado del servidor

Antes de escribir código, dejemos algo claro: la validación de correo electrónico en el lado del cliente no es suficiente.

// Esto NO es verificación: solo comprueba la sintaxis
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
// "thisdoesnotexist8472@gmail.com" → true (la sintaxis es correcta, pero el buzón no existe)

Las expresiones regulares del cliente detectan errores de formato. No te dicen si el buzón realmente existe. Para eso necesitas verificación a nivel SMTP, lo que requiere una llamada a la API desde el servidor.


Cómo obtener tu clave de API

Primero, regístrate en email-validaton.com y copia tu clave de API desde el panel de control. Las cuentas gratuitas incluyen 100 verificaciones al mes.

Mantén tu clave de API en secreto: nunca debe aparecer en JavaScript del lado del cliente. Llama siempre a la API de verificación desde tu backend.


Verificación de un solo correo electrónico

Python

import requests
from typing import Opcional

def verify_email(email: str, api_key: str) -> dict:
    """Verifica una sola dirección de correo electrónico."""
    resp = requests.get(
        "https://email-validaton.com/api/v1/verify",
        params={"email": email},
        headers={"Authorization": f"Bearer {api_key}"},
        timeout=15,
    )
    resp.raise_for_status()
    return resp.json()

# Usage
result = verify_email("user@example.com", "YOUR_API_KEY")
print(f"Estado: {result['status']}")
print(f"Puntuación: {result['score']}/10")
print(f"Confianza: {result.get('confidence', 'N/D')}")

if result["status"] == "valid":
    # Proceder con la creación de la cuenta
    create_user(email)
elif result["status"] a ("invalid", "disposable"):
    # Rechazar o marcar
    raise ValueError(f"Correo electrónico no válido: {result['reason']}")

JavaScript (Node.js)

async function verifyEmail(email, apiKey) {
  const url = new URL("https://email-validaton.com/api/v1/verify");
  url.searchParams.set("email", email);

  const resp = await fetch(url, {
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  if (!resp.ok) throw new Error(`Error de API: ${resp.status}`);
  return resp.json();
}

// Uso
const result = await verifyEmail("user@example.com", process.env.EV_API_KEY);
console.log(`Estado: ${result.status}, Puntuación: ${result.score}/10`);

if (result.status === "valid") {
  await db.users.insert({ email, verified: true });
} else {
  throw new Error(result.reason || "La verificación del correo electrónico falló");
}

PHP

function verify_email(string $email, string $api_key): array {
    $url = "https://email-validaton.com/api/v1/verify?email=" . urlencode($email);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["Authorization: Bearer $api_key"],
        CURLOPT_TIMEOUT => 15,
    ]);

    $body = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code !== 200) {
        throw new RuntimeException("API returned $http_code");
    }

    return json_decode($body, true);
}

// Uso
$result = verify_email("user@example.com", getenv("EV_API_KEY"));
echo "Estado: {$result['status']}, Puntuación: {$result['score']}/10\n";

cURL (CLI / Scripts de shell)

#!/bin/bash
API_KEY="your_api_key"
EMAIL="user@example.com"

curl -s -H "Authorization: Bearer $API_KEY" \
  "https://email-validaton.com/api/v1/verify?email=$EMAIL" | python3 -m json.tool

Comprender la respuesta

Cada verificación devuelve una estructura JSON coherente:

{
  "email": "user@gmail.com",
  "status": "valid",
  "score": 9,
  "confidence": "high",
  "reason": "El buzón existe y acepta correo",
  "mx_server": "gmail-smtp-in.l.google.com",
  "duration_ms": 287,
  "disposable": false,
  "role_account": false,
  "free_provider": true
}

Explicación de los campos clave

Campo Valores Significado
status valid, invalid, catch_all, unknown, risky, disposable, over_quota, error El resultado de la verificación
score 0–10 Puntuación de calidad compuesta. 8+ = excelente, 5-7 = moderada, <5 = arriesgada
confidence high, medium, low Lo fiable que es el resultado
reason Cadena de texto legible para personas Motivo por el que se asignó el estado
disposable booleano Dirección de correo electrónico temporal
role_account booleano info@, support@, admin@, etc.
free_provider booleano Gmail, Yahoo, Outlook, etc.

Patrones de integración

Patrón 1: validación del formulario de registro (el más común)

@app.route("/register", methods=["POST"])
def register():
    email = request.form["email"]
    password = request.form["password"]

    # 1. Verificación de sintaxis (rápida, local)
    if "@" No a email o "." No a email.split("@")[-1]:
        return jsonify({"error": "Formato de correo electrónico no válido"}), 400

    # 2. Verificación SMTP (llamada a la API)
    try:
        result = verify_email(email, current_app.config["EV_API_KEY"])
    except requests.RequestException:
        # La API no está disponible: no bloquear los registros, solo marcar para revisión
        create_user(email, password, flags=["unverified"])
        return redirect(url_for("dashboard"))

    # 3. Lógica de negocio según el resultado
    if result["status"] == "valid":
        create_user(email, password, verified=True)
        return redirect(url_for("welcome"))

    if result["status"] == "disposable":
        return jsonify({
            "error": "Por favor, utiliza una dirección de correo electrónico permanente"
        }), 400

    if result["status"] == "invalid":
        return jsonify({
            "error": "Esta dirección de correo electrónico parece no existir"
        }), 400

    # Catch-all, desconocido, arriesgado: permitir pero marcar
    create_user(email, password, flags=[result["status"]])
    return redirect(url_for("welcome"))

Patrón 2: Verificación asíncrona (no bloqueante)

Para producción a gran escala, no quieres que los usuarios esperen la llamada a la API:

import threading

def verify_async(email: str, api_key: str, user_id: int):
    """Verifica el correo electrónico en segundo plano y actualiza el registro del usuario."""
    try:
        result = verify_email(email, api_key)
        db.users.update(user_id, {
            "email_status": result["status"],
            "email_score": result["score"],
            "verified_at": datetime.utcnow(),
        })
    except Excepción as e:
        logger.error(f"La verificación en segundo plano falló para {user_id}: {e}")

# En tu controlador de registro:
usuario = create_user(email, password)
threading.Thread(
    objetivo=verify_async,
    args=(email, api_key, usuario.id),
    daemon=True,
).start()

Patrón 3: Procesamiento de listas masivas

Para limpiar listas grandes mediante el endpoint de carga masiva:

import requests
import time

def bulk_verify(file_path: str, api_key: str) -> str:
    """Sube un archivo para la verificación masiva. Devuelve el ID del trabajo."""
    with open(file_path, "rb") as f:
        resp = requests.post(
            "https://email-validaton.com/api/v1/bulk",
            files={"file": f},
            headers={"Authorization": f"Bearer {api_key}"},
        )
    return resp.json()["job_id"]

def wait_for_results(job_id: str, api_key: str, poll_sec: int = 5):
    """Consulta periódicamente hasta que el trabajo masivo finalice y luego descarga los resultados."""
    while True:
        resp = requests.get(
            f"https://email-validaton.com/api/v1/bulk/status/{job_id}",
            headers={"Authorization": f"Bearer {api_key}"},
        )
        data = resp.json()
        if data["status"] a ("completed", "failed", "cancelled"):
            return data
        time.sleep(poll_sec)

# Usage
job_id = bulk_verify("my_list.csv", API_KEY)
result = wait_for_results(job_id, API_KEY)
# Descargar el archivo de resultados
download = requests.get(result["result_url"])

Gestión de errores y buenas prácticas

Gestión de tiempos de espera

La API de verificación suele responder en 200-800 ms. Configura un tiempo de espera de 10-15 segundos para gestionar con elegancia los problemas de red.

Limitación de velocidad

Las cuentas gratuitas están limitadas a 100/día. Los planes de pago van de 5.000 a 500.000/mes. La API devuelve 429 Too Many Requests when you exceed your limit.

Lógica de reintentos

En caso de fallos temporales (errores de red, 503), vuelve a intentarlo hasta 3 veces con retroceso exponencial:

import time
from requests.exceptions import RequestException

def verify_with_retry(email, api_key, max_retries=3):
    for attempt a range(max_retries):
        try:
            return verify_email(email, api_key)
        except RequestException:
            if attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)

No bloquees los registros si falla la API

Si la API de verificación no está disponible temporalmente, no bloquees el registro de usuarios. En su lugar:
1. Permite el registro y marca la cuenta como "verificación pendiente"
2. Ejecuta la verificación de forma asíncrona cuando la API se recupere
3. Notifica al usuario si su correo electrónico resulta no válido posteriormente

Bloquear los registros durante una caída de la API hace perder usuarios reales.


Conclusión

La verificación de correos electrónicos no es opcional en aplicaciones de producción. Los correos no válidos provocan rebotes, los correos desechables permiten abusos y las listas sin verificar dañan la reputación de tu remitente.

Los patrones de integración de esta guía cubren los casos de uso más habituales. Copia el código, adáptalo a tu stack y empieza a verificar cada correo electrónico que entre en tu sistema.

¿Listo para integrarlo? Obtén tu clave API gratuita: incluye 100 verificaciones.

¿Listo para limpiar tu lista de correos?

200 verificaciones gratuitas. Sin tarjeta de crédito. Validación SMTP completa en menos de 1 segundo.

🚀 Crear cuenta gratuita
MP

Milan Pasić

Milan Pasić es el fundador de N-Software y desarrollador principal de Email Validator. Lleva más de una década construyendo infraestructura de correo electrónico, herramientas de entregabilidad y sistemas de validación SMTP utilizados por miles de profesionales del marketing y desarrolladores en todo el mundo.