ChartQuery

Detetar Domínios Descartáveis

Bloqueie registos com emails temporários em tempo real, verificando se um domínio pertence a um fornecedor de email descartável usando a API Veille.

Visão geral

Os fornecedores de email descartável permitem que os utilizadores criem caixas de correio temporárias que são eliminadas após minutos ou dias. Este guia mostra como consultar o endpoint de validação de domínios Veille e usar o resultado para bloquear ou sinalizar registos no momento do cadastro.

Pré-requisitos

  • Uma chave de API Veille — obtenha uma em app.veille.io
  • Instale as dependências para o seu idioma:
pip install requests

Sem dependências adicionais — utiliza a API fetch nativa (Node 18+).

Extensão curl ativada (ativa por padrão).

Sem dependências adicionais — utiliza net/http (Go 1.18+).

Sem dependências adicionais — utiliza java.net.http (Java 11+).

Sem dependências adicionais — utiliza System.Net.Http (.NET 6+).

# Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde_json = "1"

Passos

Verificar um domínio

Chame GET /v1/domain com o parâmetro domain. A resposta indica se é descartável, gratuito ou um domínio personalizado.

import requests

API_KEY  = "YOUR_API_KEY"
response = requests.get(
    "https://api.veille.io/v1/domain",
    headers={"x-api-key": API_KEY},
    params={"domain": "mailinator.com"},
)
result = response.json()
print(result)
const API_KEY = "YOUR_API_KEY";

const params   = new URLSearchParams({ domain: "mailinator.com" });
const response = await fetch(`https://api.veille.io/v1/domain?${params}`, {
  headers: { "x-api-key": API_KEY },
});
const result = await response.json();
console.log(result);
<?php
$apiKey = "YOUR_API_KEY";
$params = http_build_query(["domain" => "mailinator.com"]);

$ch = curl_init("https://api.veille.io/v1/domain?{$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"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.veille.io/v1/domain?domain=mailinator.com", 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.http.*;

var client  = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.veille.io/v1/domain?domain=mailinator.com"))
    .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 body = await client.GetStringAsync("https://api.veille.io/v1/domain?domain=mailinator.com");
Console.WriteLine(body);
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let result = reqwest::Client::new()
        .get("https://api.veille.io/v1/domain")
        .header("x-api-key", "YOUR_API_KEY")
        .query(&[("domain", "mailinator.com")])
        .send().await?.json::<serde_json::Value>().await?;

    println!("{:#?}", result);
    Ok(())
}

Ler os campos da resposta

A resposta inclui is_disposable, is_free, is_custom, domain e provider (quando identificado).

domain        = result.get("domain")
is_disposable = result.get("is_disposable")
is_free       = result.get("is_free")
provider      = result.get("provider", "desconhecido")

if is_disposable:
    print(f"❌ {domain} é um fornecedor de email DESCARTÁVEL ({provider}). Bloqueie este registo.")
elif is_free:
    print(f"⚠️  {domain} é um fornecedor de email gratuito. Considere verificação adicional.")
else:
    print(f"✅ {domain} parece ser um domínio personalizado / empresarial. Permitir.")
const { domain, is_disposable, is_free, provider } = result;

if (is_disposable) {
  console.log(`❌ ${domain} é DESCARTÁVEL (${provider ?? "desconhecido"}). Bloqueie este registo.`);
} else if (is_free) {
  console.log(`⚠️  ${domain} é um fornecedor gratuito. Considere verificação adicional.`);
} else {
  console.log(`✅ ${domain} parece ser um domínio empresarial. Permitir.`);
}
$domain      = $result["domain"] ?? "";
$isDisposable = $result["is_disposable"] ?? false;
$isFree       = $result["is_free"] ?? false;
$provider     = $result["provider"] ?? "desconhecido";

if ($isDisposable) {
    echo "❌ {$domain} é DESCARTÁVEL ({$provider}). Bloqueie este registo.\n";
} elseif ($isFree) {
    echo "⚠️  {$domain} é gratuito. Considere verificação adicional.\n";
} else {
    echo "✅ {$domain} parece ser um domínio empresarial. Permitir.\n";
}
domain        := result["domain"].(string)
isDisposable  := result["is_disposable"].(bool)
isFree        := result["is_free"].(bool)
provider, _   := result["provider"].(string)

switch {
case isDisposable:
    fmt.Printf("❌ %s é DESCARTÁVEL (%s). Bloqueie este registo.\n", domain, provider)
case isFree:
    fmt.Printf("⚠️  %s é um fornecedor gratuito.\n", domain)
default:
    fmt.Printf("✅ %s é um domínio empresarial. Permitir.\n", domain)
}
import org.json.*;

var r            = new JSONObject(response.body());
var domain       = r.getString("domain");
var isDisposable = r.getBoolean("is_disposable");
var isFree       = r.getBoolean("is_free");
var provider     = r.optString("provider", "desconhecido");

if (isDisposable)      System.out.printf("❌ %s é DESCARTÁVEL (%s). Bloqueie.%n", domain, provider);
else if (isFree)       System.out.printf("⚠️  %s é gratuito. Verificação adicional.%n", domain);
else                   System.out.printf("✅ %s é um domínio empresarial. Permitir.%n", domain);
using System.Text.Json;

var r            = JsonDocument.Parse(body).RootElement;
var domain       = r.GetProperty("domain").GetString();
var isDisposable = r.GetProperty("is_disposable").GetBoolean();
var isFree       = r.GetProperty("is_free").GetBoolean();
var provider     = r.TryGetProperty("provider", out var p) ? p.GetString() : "desconhecido";

if (isDisposable)
    Console.WriteLine($"❌ {domain} é DESCARTÁVEL ({provider}). Bloqueie.");
else if (isFree)
    Console.WriteLine($"⚠️  {domain} é gratuito. Verificação adicional.");
else
    Console.WriteLine($"✅ {domain} é um domínio empresarial. Permitir.");
let domain       = result["domain"].as_str().unwrap_or("");
let is_disposable = result["is_disposable"].as_bool().unwrap_or(false);
let is_free       = result["is_free"].as_bool().unwrap_or(false);
let provider      = result["provider"].as_str().unwrap_or("desconhecido");

if is_disposable {
    println!("❌ {} é DESCARTÁVEL ({}). Bloqueie.", domain, provider);
} else if is_free {
    println!("⚠️  {} é gratuito. Verificação adicional.", domain);
} else {
    println!("✅ {} é um domínio empresarial. Permitir.", domain);
}

Integrar no handler de registo

Adicione a verificação de domínio ao seu endpoint de registo e devolva um erro de validação antes de criar o registo do utilizador.

import requests

API_KEY = "YOUR_API_KEY"

def is_disposable_email(email: str) -> bool:
    domain = email.split("@")[-1].lower()
    r = requests.get("https://api.veille.io/v1/domain",
        headers={"x-api-key": API_KEY}, params={"domain": domain})
    return r.json().get("is_disposable", False)

def register_user(email: str, password: str) -> dict:
    if is_disposable_email(email):
        return {"success": False, "error": "Endereços de email descartáveis não são permitidos."}
    # ... criar o registo do utilizador na base de dados
    return {"success": True, "message": f"Bem-vindo, {email}!"}

print(register_user("[email protected]", "secret"))
print(register_user("[email protected]",    "secret"))
const API_KEY = "YOUR_API_KEY";

async function isDisposableEmail(email: string): Promise<boolean> {
  const domain = email.split("@").at(-1)!.toLowerCase();
  const params = new URLSearchParams({ domain });
  const res    = await fetch(`https://api.veille.io/v1/domain?${params}`, {
    headers: { "x-api-key": API_KEY },
  });
  return (await res.json()).is_disposable ?? false;
}

async function registerUser(email: string, password: string) {
  if (await isDisposableEmail(email)) {
    return { success: false, error: "Endereços de email descartáveis não são permitidos." };
  }
  // ... criar registo do utilizador
  return { success: true, message: `Bem-vindo, ${email}!` };
}

console.log(await registerUser("[email protected]", "secret"));
console.log(await registerUser("[email protected]",    "secret"));
<?php
function isDisposableEmail(string $apiKey, string $email): bool {
    $domain = strtolower(explode("@", $email)[1]);
    $params = http_build_query(["domain" => $domain]);
    $ch = curl_init("https://api.veille.io/v1/domain?{$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["is_disposable"] ?? false;
}

function registerUser(string $apiKey, string $email, string $password): array {
    if (isDisposableEmail($apiKey, $email)) {
        return ["success" => false, "error" => "Endereços de email descartáveis não são permitidos."];
    }
    // ... criar registo do utilizador
    return ["success" => true, "message" => "Bem-vindo, {$email}!"];
}

print_r(registerUser("YOUR_API_KEY", "[email protected]", "secret"));
print_r(registerUser("YOUR_API_KEY", "[email protected]",    "secret"));
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "strings"
)

func isDisposable(apiKey, email string) bool {
    domain := strings.ToLower(strings.SplitN(email, "@", 2)[1])
    req, _ := http.NewRequest("GET", "https://api.veille.io/v1/domain?domain="+domain, nil)
    req.Header.Set("x-api-key", apiKey)
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    var result map[string]any
    json.Unmarshal(body, &result)
    v, _ := result["is_disposable"].(bool)
    return v
}

func registerUser(apiKey, email, password string) string {
    if isDisposable(apiKey, email) {
        return "❌ Email descartável não permitido."
    }
    return "✅ Bem-vindo, " + email + "!"
}

func main() {
    apiKey := "YOUR_API_KEY"
    fmt.Println(registerUser(apiKey, "[email protected]", "secret"))
    fmt.Println(registerUser(apiKey, "[email protected]",    "secret"))
}
import java.net.URI;
import java.net.http.*;
import org.json.*;

public class Main {
    static HttpClient client = HttpClient.newHttpClient();
    static String API_KEY   = "YOUR_API_KEY";

    static boolean isDisposable(String email) throws Exception {
        var domain  = email.substring(email.indexOf('@') + 1).toLowerCase();
        var request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.veille.io/v1/domain?domain=" + domain))
            .header("x-api-key", API_KEY).GET().build();
        var resp    = client.send(request, HttpResponse.BodyHandlers.ofString());
        return new JSONObject(resp.body()).optBoolean("is_disposable", false);
    }

    static String registerUser(String email, String password) throws Exception {
        if (isDisposable(email)) return "❌ Email descartável não permitido.";
        return "✅ Bem-vindo, " + email + "!";
    }

    public static void main(String[] args) throws Exception {
        System.out.println(registerUser("[email protected]", "secret"));
        System.out.println(registerUser("[email protected]",    "secret"));
    }
}
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<bool> IsDisposable(string email)
{
    var domain = email.Split('@').Last().ToLower();
    var body   = await client.GetStringAsync($"https://api.veille.io/v1/domain?domain={domain}");
    return JsonDocument.Parse(body).RootElement.GetProperty("is_disposable").GetBoolean();
}

async Task<string> RegisterUser(string email, string password) =>
    await IsDisposable(email)
        ? "❌ Email descartável não permitido."
        : $"✅ Bem-vindo, {email}!";

Console.WriteLine(await RegisterUser("[email protected]", "secret"));
Console.WriteLine(await RegisterUser("[email protected]",    "secret"));
use reqwest::Client;
use serde_json::Value;

async fn is_disposable(client: &Client, api_key: &str, email: &str) -> bool {
    let domain = email.split('@').last().unwrap_or("").to_lowercase();
    let result = client.get("https://api.veille.io/v1/domain")
        .header("x-api-key", api_key)
        .query(&[("domain", domain.as_str())])
        .send().await.unwrap().json::<Value>().await.unwrap();
    result["is_disposable"].as_bool().unwrap_or(false)
}

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let client  = Client::new();
    let api_key = "YOUR_API_KEY";

    for email in ["[email protected]", "[email protected]"] {
        if is_disposable(&client, api_key, email).await {
            println!("❌ {} — descartável. Bloqueie.", email);
        } else {
            println!("✅ {} — parece válido. Permitir.", email);
        }
    }
    Ok(())
}

Guarde em cache os resultados de domínios verificados com frequência (por exemplo, no Redis com TTL de 24 horas) para evitar chamadas à API redundantes. A lista de fornecedores descartáveis raramente muda durante um único dia.

Nesta página