Validar email en el registro
Verifica si una dirección de email es real y entregable durante el registro — con la API de validación de email de Veille, incluyendo verificación de sintaxis, DNS y buzón.
Descripción general
Este tutorial muestra cómo realizar una validación completa de email antes de aceptar un registro: comprobación de sintaxis, búsqueda de registros DNS/MX y alcanzabilidad SMTP. La API devuelve un risk_score (0 = limpio, 100 = alto riesgo) que puedes usar para redirigir usuarios a pasos de verificación adicionales.
Prerrequisitos
- Una clave de API de Veille — consigue una en app.veille.io
- Instala las dependencias para tu lenguaje:
pip install requestsSin dependencias adicionales — usa la API nativa fetch (Node 18+).
Extensión curl habilitada (activa por defecto).
Sin dependencias adicionales — usa net/http (Go 1.18+).
Sin dependencias adicionales — usa java.net.http (Java 11+).
Sin dependencias adicionales — usa System.Net.Http (.NET 6+).
# Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde_json = "1"Pasos
Valida la dirección de email
Llama a GET /v1/email con el parámetro email.
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://api.veille.io/v1/email",
headers={"x-api-key": API_KEY},
params={"email": "alice@example.com"},
)
result = response.json()
print(result)const API_KEY = "YOUR_API_KEY";
const params = new URLSearchParams({ email: "alice@example.com" });
const response = await fetch(`https://api.veille.io/v1/email?${params}`, {
headers: { "x-api-key": API_KEY },
});
const result = await response.json();
console.log(result);<?php
$apiKey = "YOUR_API_KEY";
$params = http_build_query(["email" => "alice@example.com"]);
$ch = curl_init("https://api.veille.io/v1/email?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($result);package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
params := url.Values{"email": {"alice@example.com"}}
req, _ := http.NewRequest("GET", "https://api.veille.io/v1/email?"+params.Encode(), nil)
req.Header.Set("x-api-key", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result map[string]any
json.Unmarshal(body, &result)
fmt.Println(result)
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
var client = HttpClient.newHttpClient();
var email = URLEncoder.encode("alice@example.com", StandardCharsets.UTF_8);
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.veille.io/v1/email?email=" + email))
.header("x-api-key", "YOUR_API_KEY")
.GET().build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());using System.Net.Http;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");
var email = Uri.EscapeDataString("alice@example.com");
var body = await client.GetStringAsync($"https://api.veille.io/v1/email?email={email}");
Console.WriteLine(body);#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let result = reqwest::Client::new()
.get("https://api.veille.io/v1/email")
.header("x-api-key", "YOUR_API_KEY")
.query(&[("email", "alice@example.com")])
.send().await?.json::<serde_json::Value>().await?;
println!("{:#?}", result);
Ok(())
}Interpreta el resultado
Campos clave: is_valid, is_deliverable, is_disposable, is_role_account, risk_score, did_you_mean (sugerencia de error tipográfico).
print(f"Válido : {result['is_valid']}")
print(f"Entregable : {result['is_deliverable']}")
print(f"Desechable : {result['is_disposable']}")
print(f"Cuenta rol : {result['is_role_account']}")
print(f"Puntuación : {result['risk_score']}/100")
if result.get("did_you_mean"):
print(f"¿Quisiste decir: {result['did_you_mean']}?")console.log(`Válido : ${result.is_valid}`);
console.log(`Entregable : ${result.is_deliverable}`);
console.log(`Desechable : ${result.is_disposable}`);
console.log(`Cuenta rol : ${result.is_role_account}`);
console.log(`Puntuación : ${result.risk_score}/100`);
if (result.did_you_mean) console.log(`¿Quisiste decir: ${result.did_you_mean}?`);echo "Válido : " . ($result["is_valid"] ? "true" : "false") . "\n";
echo "Entregable : " . ($result["is_deliverable"] ? "true" : "false") . "\n";
echo "Desechable : " . ($result["is_disposable"] ? "true" : "false") . "\n";
echo "Puntuación : {$result['risk_score']}/100\n";
if (!empty($result["did_you_mean"])) echo "¿Quisiste decir: {$result['did_you_mean']}?\n";fmt.Printf("Válido : %v\nEntregable : %v\nDesechable : %v\nPuntuación : %v/100\n",
result["is_valid"], result["is_deliverable"], result["is_disposable"], result["risk_score"])
if typo, ok := result["did_you_mean"].(string); ok && typo != "" {
fmt.Println("¿Quisiste decir:", typo+"?")
}import org.json.*;
var r = new JSONObject(response.body());
System.out.printf("Válido : %b%nEntregable : %b%nDesechable : %b%nPuntuación : %d/100%n",
r.getBoolean("is_valid"), r.getBoolean("is_deliverable"),
r.getBoolean("is_disposable"), r.getInt("risk_score"));
if (r.has("did_you_mean")) System.out.println("¿Quisiste decir: " + r.getString("did_you_mean") + "?");using System.Text.Json;
var r = JsonDocument.Parse(body).RootElement;
Console.WriteLine($"Válido : {r.GetProperty("is_valid").GetBoolean()}");
Console.WriteLine($"Entregable : {r.GetProperty("is_deliverable").GetBoolean()}");
Console.WriteLine($"Desechable : {r.GetProperty("is_disposable").GetBoolean()}");
Console.WriteLine($"Puntuación : {r.GetProperty("risk_score").GetInt32()}/100");
if (r.TryGetProperty("did_you_mean", out var typo) && typo.GetString() is { } t and not "")
Console.WriteLine($"¿Quisiste decir: {t}?");println!("Válido : {}", result["is_valid"]);
println!("Entregable : {}", result["is_deliverable"]);
println!("Desechable : {}", result["is_disposable"]);
println!("Puntuación : {}/100", result["risk_score"]);
if let Some(typo) = result["did_you_mean"].as_str() {
if !typo.is_empty() { println!("¿Quisiste decir: {}?", typo); }
}Flujo de registro basado en riesgo
Usa risk_score para redirigir usuarios: bloquea direcciones de alto riesgo, sugiere correcciones tipográficas y aplica verificaciones adicionales a cuentas de rol.
import requests
API_KEY = "YOUR_API_KEY"
def validate_email(email: str) -> dict:
r = requests.get("https://api.veille.io/v1/email",
headers={"x-api-key": API_KEY}, params={"email": email})
return r.json()
def register(email: str) -> dict:
v = validate_email(email)
if not v.get("is_valid"):
return {"ok": False, "error": "Esta dirección de email no es válida."}
if v.get("is_disposable"):
return {"ok": False, "error": "No se aceptan emails temporales."}
if v.get("did_you_mean"):
return {"ok": False, "suggestion": f"¿Quisiste decir {v['did_you_mean']}?"}
if v.get("risk_score", 0) >= 70:
return {"ok": False, "error": "Puntuación de riesgo alta. Por favor usa otra dirección."}
if v.get("is_role_account"):
return {"ok": True, "flag": "role_account", "message": "Por favor confirma tu email."}
return {"ok": True, "message": "¡Registro exitoso!"}
for test_email in ["alice@mailinator.com", "info@company.com", "alice@gmial.com", "alice@stripe.com"]:
print(f"{test_email}: {register(test_email)}")const API_KEY = "YOUR_API_KEY";
async function validateEmail(email: string) {
const params = new URLSearchParams({ email });
const res = await fetch(`https://api.veille.io/v1/email?${params}`, {
headers: { "x-api-key": API_KEY },
});
return res.json();
}
async function register(email: string) {
const v = await validateEmail(email);
if (!v.is_valid) return { ok: false, error: "Email inválido." };
if (v.is_disposable) return { ok: false, error: "Emails temporales no aceptados." };
if (v.did_you_mean) return { ok: false, suggestion: `¿Quisiste decir ${v.did_you_mean}?` };
if (v.risk_score >= 70) return { ok: false, error: "Puntuación de riesgo alta." };
if (v.is_role_account) return { ok: true, flag: "role_account", message: "Confirma tu email." };
return { ok: true, message: "¡Registro exitoso!" };
}
for (const email of ["alice@mailinator.com", "info@company.com", "alice@gmial.com", "alice@stripe.com"]) {
console.log(email, await register(email));
}<?php
function validateEmail(string $apiKey, string $email): array {
$params = http_build_query(["email" => $email]);
$ch = curl_init("https://api.veille.io/v1/email?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
function register(string $apiKey, string $email): array {
$v = validateEmail($apiKey, $email);
if (!($v["is_valid"] ?? false)) return ["ok" => false, "error" => "Email inválido."];
if ($v["is_disposable"] ?? false) return ["ok" => false, "error" => "Emails temporales no aceptados."];
if (!empty($v["did_you_mean"])) return ["ok" => false, "suggestion" => "¿Quisiste decir {$v['did_you_mean']}?"];
if (($v["risk_score"] ?? 0) >= 70) return ["ok" => false, "error" => "Puntuación de riesgo alta."];
if ($v["is_role_account"] ?? false) return ["ok" => true, "flag" => "role_account"];
return ["ok" => true, "message" => "¡Registro exitoso!"];
}
foreach (["alice@mailinator.com", "info@company.com", "alice@gmial.com"] as $email) {
print_r(["email" => $email, "result" => register("YOUR_API_KEY", $email)]);
}package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
const APIKey = "YOUR_API_KEY"
func validate(email string) map[string]any {
params := url.Values{"email": {email}}
req, _ := http.NewRequest("GET", "https://api.veille.io/v1/email?"+params.Encode(), nil)
req.Header.Set("x-api-key", APIKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var v map[string]any
json.Unmarshal(body, &v)
return v
}
func register(email string) string {
v := validate(email)
if !(v["is_valid"].(bool)) { return "❌ Email inválido." }
if v["is_disposable"].(bool) { return "❌ Email temporal no aceptado." }
if typo, ok := v["did_you_mean"].(string); ok && typo != "" {
return "⚠️ ¿Quisiste decir " + typo + "?"
}
if v["risk_score"].(float64) >= 70 { return "❌ Puntuación de riesgo alta." }
return "✅ ¡Registro exitoso!"
}
func main() {
for _, email := range []string{"alice@mailinator.com", "info@company.com", "alice@stripe.com"} {
fmt.Printf("%s: %s\n", email, register(email))
}
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import org.json.*;
public class Main {
static HttpClient client = HttpClient.newHttpClient();
static String API_KEY = "YOUR_API_KEY";
static JSONObject validate(String email) throws Exception {
var encoded = URLEncoder.encode(email, StandardCharsets.UTF_8);
var req = HttpRequest.newBuilder()
.uri(URI.create("https://api.veille.io/v1/email?email=" + encoded))
.header("x-api-key", API_KEY).GET().build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
return new JSONObject(resp.body());
}
static String register(String email) throws Exception {
var v = validate(email);
if (!v.getBoolean("is_valid")) return "❌ Email inválido.";
if (v.getBoolean("is_disposable")) return "❌ Email temporal no aceptado.";
if (v.has("did_you_mean")) return "⚠️ ¿Quisiste decir " + v.getString("did_you_mean") + "?";
if (v.getInt("risk_score") >= 70) return "❌ Puntuación de riesgo alta.";
return "✅ ¡Registro exitoso!";
}
public static void main(String[] args) throws Exception {
for (var email : new String[]{"alice@mailinator.com", "info@company.com", "alice@stripe.com"}) {
System.out.printf("%s: %s%n", email, register(email));
}
}
}using System.Net.Http;
using System.Text.Json;
var apiKey = "YOUR_API_KEY";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", apiKey);
async Task<JsonElement> Validate(string email)
{
var encoded = Uri.EscapeDataString(email);
var body = await client.GetStringAsync($"https://api.veille.io/v1/email?email={encoded}");
return JsonDocument.Parse(body).RootElement;
}
async Task<string> Register(string email)
{
var v = await Validate(email);
if (!v.GetProperty("is_valid").GetBoolean()) return "❌ Email inválido.";
if (v.GetProperty("is_disposable").GetBoolean()) return "❌ Email temporal no aceptado.";
if (v.TryGetProperty("did_you_mean", out var t) && t.GetString() is { Length: > 0 } typo)
return $"⚠️ ¿Quisiste decir {typo}?";
if (v.GetProperty("risk_score").GetInt32() >= 70) return "❌ Puntuación de riesgo alta.";
return "✅ ¡Registro exitoso!";
}
foreach (var email in new[] { "alice@mailinator.com", "info@company.com", "alice@stripe.com" })
Console.WriteLine($"{email}: {await Register(email)}");use reqwest::Client;
use serde_json::Value;
const API_KEY: &str = "YOUR_API_KEY";
async fn validate(client: &Client, email: &str) -> Value {
client.get("https://api.veille.io/v1/email")
.header("x-api-key", API_KEY)
.query(&[("email", email)])
.send().await.unwrap().json::<Value>().await.unwrap()
}
async fn register(client: &Client, email: &str) -> &'static str {
let v = validate(client, email).await;
if !v["is_valid"].as_bool().unwrap_or(false) { return "❌ Email inválido."; }
if v["is_disposable"].as_bool().unwrap_or(false) { return "❌ Email temporal no aceptado."; }
if v["risk_score"].as_i64().unwrap_or(0) >= 70 { return "❌ Puntuación de riesgo alta."; }
"✅ ¡Registro exitoso!"
}
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
for email in ["alice@mailinator.com", "info@company.com", "alice@stripe.com"] {
println!("{}: {}", email, register(&client, email).await);
}
Ok(())
}Las cuentas de rol (admin@, info@, support@) a menudo son monitoreadas por múltiples personas — o por nadie. Márcalas para revisión manual en lugar de bloquearlas para no perder registros B2B legítimos.
Detectar dominios desechables
Bloquea en tiempo real los registros con emails temporales verificando si un dominio pertenece a un proveedor de correo desechable usando la API de Veille.
Validar números de IVA de la UE
Verifica números de IVA europeos en el checkout para habilitar exenciones fiscales B2B y prevenir fraude usando la API de validación de IVA de Veille.