MX Record Validatie: Gids voor Ontwikkelaars

Leo
LeoFounder, BillionVerify

Leer MX record validatie implementeren. Deze gids behandelt DNS lookups, MX parsing en best practices voor domeinverificatie.

Cover Image for MX Record Validatie: Gids voor Ontwikkelaars

Elke e-mail die je verstuurt, reist door een zorgvuldig georkestreerd netwerk van servers, en Mail Exchange (MX) records zijn de wegwijzers die deze reis begeleiden. Het begrijpen van hoe je MX records valideert, is een fundamentele vaardigheid voor elke ontwikkelaar die e-mailverificatiesystemen, contactformulieren of applicaties bouwt die e-mailadressen verzamelen. Deze uitgebreide gids verkent MX record validatie van basisconcepten tot geavanceerde implementatiestrategieën, waardoor je de kennis krijgt om robuuste e-mailverificatie in je applicaties te bouwen.

MX Records Begrijpen

Mail Exchange records zijn DNS-records die specificeren welke mailservers verantwoordelijk zijn voor het accepteren van e-mail namens een domein. Wanneer je een e-mail stuurt naar user@example.com, moet je mailserver weten waar deze te bezorgen. MX records leveren deze informatie door te verwijzen naar de mailservers van het domein.

Hoe MX Records Werken

Wanneer een e-mail wordt verzonden, voert de verzendende mailserver een DNS lookup uit om de MX records voor het domein van de ontvanger te vinden. Deze lookup retourneert een of meer mailserver hostnamen samen met prioriteitswaarden die de voorkeursvolgorde aangeven.

Een typische MX record lookup voor gmail.com zou kunnen teruggeven:

gmail.com.    MX    5     gmail-smtp-in.l.google.com.
gmail.com.    MX    10    alt1.gmail-smtp-in.l.google.com.
gmail.com.    MX    20    alt2.gmail-smtp-in.l.google.com.
gmail.com.    MX    30    alt3.gmail-smtp-in.l.google.com.
gmail.com.    MX    40    alt4.gmail-smtp-in.l.google.com.

De verzendende server probeert eerst bezorging naar de server met de laagste prioriteit (in dit geval prioriteit 5). Als die server niet beschikbaar is, probeert deze het volgende prioriteitsniveau, enzovoort. Deze redundantie zorgt voor e-mailbezorging zelfs wanneer individuele servers offline zijn.

MX Record Componenten

Elk MX record bevat twee essentiële informatiestukken:

Prioriteit (Voorkeur)

Een numerieke waarde die de volgorde aangeeft waarin mailservers geprobeerd moeten worden. Lagere nummers geven hogere prioriteit aan. Servers met dezelfde prioriteit worden in willekeurige volgorde geprobeerd, wat load balancing biedt.

Mailserver Hostnaam

De Fully Qualified Domain Name (FQDN) van de mailserver die e-mail afhandelt voor het domein. Deze hostnaam moet oplossen naar een IP-adres via een A of AAAA record.

Waarom MX Records Belangrijk Zijn voor E-mailverificatie

MX record validatie dient als een kritisch controlepunt in het e-mailverificatieproces:

Bevestiging van Domeinbestaan

Als een domein geen MX records heeft, kan het doorgaans geen e-mail ontvangen. Sommige domeinen hebben mogelijk een A record fallback, maar de afwezigheid van MX records is vaak een sterke indicator dat het domein niet is geconfigureerd voor e-mail.

Infrastructuurverificatie

Geldige MX records die oplossen naar werkende mailservers geven aan dat het domein e-mailinfrastructuur heeft. Dit garandeert niet dat een specifiek adres bestaat, maar bevestigt wel dat het domein e-mail kan ontvangen.

Spam en Fraudedetectie

Legitieme bedrijven onderhouden correcte MX records. Verdachte domeinen die worden gebruikt voor spam of fraude hebben vaak verkeerd geconfigureerde of ontbrekende MX records.

Prestatieoptimalisatie

Het controleren van MX records voordat je SMTP-verificatie probeert, voorkomt verspilde tijd bij het verbinden met domeinen die geen e-mail kunnen ontvangen.

MX Record Lookups Implementeren

Laten we verkennen hoe je MX record validatie implementeert in verschillende programmeeromgevingen.

Node.js Implementatie

Node.js biedt ingebouwde DNS-resolutie via de dns module:

const dns = require('dns').promises;

async function getMxRecords(domain) {
  try {
    const records = await dns.resolveMx(domain);

    // Sort by priority (lowest first)
    records.sort((a, b) => a.priority - b.priority);

    return {
      success: true,
      domain,
      records: records.map(r => ({
        exchange: r.exchange,
        priority: r.priority
      }))
    };
  } catch (error) {
    return {
      success: false,
      domain,
      error: error.code,
      message: getMxErrorMessage(error.code)
    };
  }
}

function getMxErrorMessage(code) {
  const messages = {
    'ENODATA': 'No MX records found for this domain',
    'ENOTFOUND': 'Domain does not exist',
    'ETIMEOUT': 'DNS lookup timed out',
    'ESERVFAIL': 'DNS server failed to respond'
  };
  return messages[code] || 'Unknown DNS error';
}

// Usage
const result = await getMxRecords('gmail.com');
console.log(result);

Python Implementatie

Python's dns.resolver module uit de dnspython bibliotheek biedt uitgebreide DNS lookup mogelijkheden:

import dns.resolver
import dns.exception

def get_mx_records(domain):
    try:
        answers = dns.resolver.resolve(domain, 'MX')

        records = []
        for rdata in answers:
            records.append({
                'exchange': str(rdata.exchange).rstrip('.'),
                'priority': rdata.preference
            })

        # Sort by priority
        records.sort(key=lambda x: x['priority'])

        return {
            'success': True,
            'domain': domain,
            'records': records
        }

    except dns.resolver.NXDOMAIN:
        return {
            'success': False,
            'domain': domain,
            'error': 'NXDOMAIN',
            'message': 'Domain does not exist'
        }

    except dns.resolver.NoAnswer:
        return {
            'success': False,
            'domain': domain,
            'error': 'NoAnswer',
            'message': 'No MX records found for this domain'
        }

    except dns.exception.Timeout:
        return {
            'success': False,
            'domain': domain,
            'error': 'Timeout',
            'message': 'DNS lookup timed out'
        }

# Usage
result = get_mx_records('gmail.com')
print(result)

Go Implementatie

Go's net package biedt eenvoudige DNS lookup functies:

package main

import (
    "fmt"
    "net"
    "sort"
)

type MxResult struct {
    Success bool
    Domain  string
    Records []MxRecord
    Error   string
}

type MxRecord struct {
    Exchange string
    Priority uint16
}

func getMxRecords(domain string) MxResult {
    records, err := net.LookupMX(domain)

    if err != nil {
        return MxResult{
            Success: false,
            Domain:  domain,
            Error:   err.Error(),
        }
    }

    if len(records) == 0 {
        return MxResult{
            Success: false,
            Domain:  domain,
            Error:   "No MX records found",
        }
    }

    // Sort by priority
    sort.Slice(records, func(i, j int) bool {
        return records[i].Pref < records[j].Pref
    })

    result := MxResult{
        Success: true,
        Domain:  domain,
        Records: make([]MxRecord, len(records)),
    }

    for i, r := range records {
        result.Records[i] = MxRecord{
            Exchange: r.Host,
            Priority: r.Pref,
        }
    }

    return result
}

func main() {
    result := getMxRecords("gmail.com")
    fmt.Printf("%+v\n", result)
}

Geavanceerde MX Validatietechnieken

Basis MX lookups bevestigen dat records bestaan, maar uitgebreide e-mailvalidatie vereist diepere analyse.

Mailserver Connectiviteit Valideren

MX records verwijzen naar hostnamen die moeten oplossen naar IP-adressen. Verifieer dat de mailservers daadwerkelijk bereikbaar zijn:

const dns = require('dns').promises;
const net = require('net');

async function validateMxConnectivity(domain) {
  // Get MX records
  const mxResult = await getMxRecords(domain);

  if (!mxResult.success) {
    return mxResult;
  }

  // Validate each mail server
  const validatedRecords = [];

  for (const record of mxResult.records) {
    const validation = await validateMailServer(record.exchange);
    validatedRecords.push({
      ...record,
      ...validation
    });
  }

  return {
    success: true,
    domain,
    records: validatedRecords,
    hasReachableServer: validatedRecords.some(r => r.reachable)
  };
}

async function validateMailServer(hostname) {
  try {
    // Resolve hostname to IP
    const addresses = await dns.resolve4(hostname);

    if (addresses.length === 0) {
      return { reachable: false, error: 'No A record' };
    }

    // Test connection to port 25
    const connected = await testConnection(addresses[0], 25);

    return {
      reachable: connected,
      ip: addresses[0],
      error: connected ? null : 'Connection refused'
    };
  } catch (error) {
    return {
      reachable: false,
      error: error.message
    };
  }
}

function testConnection(host, port, timeout = 5000) {
  return new Promise((resolve) => {
    const socket = new net.Socket();

    socket.setTimeout(timeout);

    socket.on('connect', () => {
      socket.destroy();
      resolve(true);
    });

    socket.on('timeout', () => {
      socket.destroy();
      resolve(false);
    });

    socket.on('error', () => {
      resolve(false);
    });

    socket.connect(port, host);
  });
}

A Record Fallback Afhandelen

Wanneer er geen MX records bestaan, specificeren e-mailstandaarden (RFC 5321) dat het A record van het domein als fallback gebruikt moet worden. Implementeer deze fallback in je validatie:

async function getMailServers(domain) {
  // Try MX records first
  try {
    const mxRecords = await dns.resolveMx(domain);

    if (mxRecords.length > 0) {
      return {
        type: 'MX',
        servers: mxRecords.sort((a, b) => a.priority - b.priority)
      };
    }
  } catch (error) {
    if (error.code !== 'ENODATA') {
      throw error;
    }
  }

  // Fallback to A record
  try {
    const aRecords = await dns.resolve4(domain);

    if (aRecords.length > 0) {
      return {
        type: 'A_FALLBACK',
        servers: [{ exchange: domain, priority: 0 }],
        warning: 'Using A record fallback - no MX records found'
      };
    }
  } catch (error) {
    if (error.code !== 'ENODATA') {
      throw error;
    }
  }

  return {
    type: 'NONE',
    servers: [],
    error: 'No mail servers found for domain'
  };
}

Null MX Records Detecteren

RFC 7505 definieert "null MX" records die expliciet aangeven dat een domein geen e-mail accepteert. Deze records hebben een enkel MX entry met prioriteit 0 en een lege hostnaam ("."):

function hasNullMx(mxRecords) {
  if (mxRecords.length === 1) {
    const record = mxRecords[0];
    if (record.priority === 0 &&
        (record.exchange === '.' || record.exchange === '')) {
      return true;
    }
  }
  return false;
}

async function validateDomainMx(domain) {
  const mxResult = await getMxRecords(domain);

  if (!mxResult.success) {
    return mxResult;
  }

  if (hasNullMx(mxResult.records)) {
    return {
      success: false,
      domain,
      error: 'NULL_MX',
      message: 'Domain explicitly does not accept email'
    };
  }

  return mxResult;
}

MX Lookups Cachen

DNS lookups voegen latency toe aan elke verificatie. Implementeer caching om de prestaties te verbeteren:

class MxCache {
  constructor(ttlMs = 3600000) { // 1 hour default TTL
    this.cache = new Map();
    this.ttl = ttlMs;
  }

  get(domain) {
    const entry = this.cache.get(domain.toLowerCase());

    if (!entry) return null;

    if (Date.now() > entry.expiry) {
      this.cache.delete(domain.toLowerCase());
      return null;
    }

    return entry.data;
  }

  set(domain, data) {
    this.cache.set(domain.toLowerCase(), {
      data,
      expiry: Date.now() + this.ttl
    });
  }

  // Respect DNS TTL values when available
  setWithTtl(domain, data, ttlSeconds) {
    const ttlMs = Math.min(ttlSeconds * 1000, this.ttl);
    this.cache.set(domain.toLowerCase(), {
      data,
      expiry: Date.now() + ttlMs
    });
  }
}

const mxCache = new MxCache();

async function getMxRecordsCached(domain) {
  const cached = mxCache.get(domain);

  if (cached) {
    return { ...cached, fromCache: true };
  }

  const result = await getMxRecords(domain);

  if (result.success) {
    mxCache.set(domain, result);
  }

  return { ...result, fromCache: false };
}

Veelvoorkomende MX Record Patronen

Het begrijpen van veelvoorkomende MX configuraties helpt je validatieresultaten te interpreteren en potentiële problemen te identificeren.

Grote E-mailproviders

Het herkennen van MX patronen voor grote providers kan helpen gratis e-mailadressen te identificeren:

const knownProviders = {
  'google': [
    'gmail-smtp-in.l.google.com',
    'googlemail-smtp-in.l.google.com',
    'aspmx.l.google.com'
  ],
  'microsoft': [
    'outlook-com.olc.protection.outlook.com',
    'mail.protection.outlook.com'
  ],
  'yahoo': [
    'mta5.am0.yahoodns.net',
    'mta6.am0.yahoodns.net',
    'mta7.am0.yahoodns.net'
  ],
  'protonmail': [
    'mail.protonmail.ch',
    'mailsec.protonmail.ch'
  ]
};

function identifyEmailProvider(mxRecords) {
  const exchanges = mxRecords.map(r => r.exchange.toLowerCase());

  for (const [provider, patterns] of Object.entries(knownProviders)) {
    for (const pattern of patterns) {
      if (exchanges.some(ex => ex.includes(pattern.toLowerCase()))) {
        return provider;
      }
    }
  }

  return 'unknown';
}

Google Workspace Detectie

Google Workspace (voorheen G Suite) domeinen gebruiken Google's mailservers maar zijn geen gratis e-mailaccounts:

function isGoogleWorkspace(domain, mxRecords) {
  const isGoogleMx = mxRecords.some(r =>
    r.exchange.toLowerCase().includes('google') ||
    r.exchange.toLowerCase().includes('googlemail')
  );

  // Check if domain is not a known Google consumer domain
  const googleConsumerDomains = ['gmail.com', 'googlemail.com'];
  const isConsumerDomain = googleConsumerDomains.includes(domain.toLowerCase());

  return isGoogleMx && !isConsumerDomain;
}

Zelf-gehoste E-mail Detectie

Domeinen die hun eigen e-mail hosten, hebben vaak MX records die verwijzen naar subdomeinen:

function isSelfHosted(domain, mxRecords) {
  const domainParts = domain.toLowerCase().split('.');
  const baseDomain = domainParts.slice(-2).join('.');

  return mxRecords.some(r => {
    const exchange = r.exchange.toLowerCase();
    return exchange.includes(baseDomain) &&
           !isKnownProvider(exchange);
  });
}

function isKnownProvider(exchange) {
  const providers = ['google', 'microsoft', 'yahoo', 'outlook', 'protonmail'];
  return providers.some(p => exchange.includes(p));
}

MX Validatie in E-mailverificatie Pipelines

MX validatie is een stap in een uitgebreid e-mailverificatieproces. Het begrijpen van zijn rol helpt effectieve verificatiepipelines te bouwen.

Verificatievolgorde

MX validatie vindt doorgaans vroeg in de verificatiepipeline plaats:

async function verifyEmail(email) {
  // 1. Syntax validation (fastest, no network)
  const syntaxResult = validateEmailSyntax(email);
  if (!syntaxResult.valid) {
    return { valid: false, reason: 'invalid_syntax', details: syntaxResult };
  }

  const domain = email.split('@')[1];

  // 2. MX record validation (fast DNS lookup)
  const mxResult = await validateMxRecords(domain);
  if (!mxResult.valid) {
    return { valid: false, reason: 'no_mx_records', details: mxResult };
  }

  // 3. Additional checks (disposable, role-based, etc.)
  const domainCheck = await checkDomainReputation(domain);
  if (domainCheck.isDisposable) {
    return { valid: true, risky: true, reason: 'disposable_domain' };
  }

  // 4. SMTP verification (slowest, most thorough)
  const smtpResult = await verifySmtp(email, mxResult.records);

  return {
    valid: smtpResult.exists,
    deliverable: smtpResult.deliverable,
    mxRecords: mxResult.records,
    provider: mxResult.provider
  };
}

Parallelle MX Lookups

Bij het verifiëren van meerdere e-mails, parallelliseer MX lookups voor verschillende domeinen:

async function verifyEmailsBatch(emails) {
  // Group emails by domain
  const emailsByDomain = {};

  for (const email of emails) {
    const domain = email.split('@')[1];
    if (!emailsByDomain[domain]) {
      emailsByDomain[domain] = [];
    }
    emailsByDomain[domain].push(email);
  }

  // Lookup MX records for all domains in parallel
  const domains = Object.keys(emailsByDomain);
  const mxResults = await Promise.all(
    domains.map(domain => getMxRecordsCached(domain))
  );

  // Map results back to domains
  const mxByDomain = {};
  domains.forEach((domain, index) => {
    mxByDomain[domain] = mxResults[index];
  });

  // Process emails with MX data
  const results = [];

  for (const email of emails) {
    const domain = email.split('@')[1];
    const mx = mxByDomain[domain];

    if (!mx.success) {
      results.push({ email, valid: false, reason: 'invalid_domain' });
      continue;
    }

    // Continue with SMTP verification using cached MX data
    const smtpResult = await verifySmtp(email, mx.records);
    results.push({ email, ...smtpResult });
  }

  return results;
}

Foutafhandeling en Randgevallen

Robuuste MX validatie handelt verschillende foutcondities netjes af.

DNS Timeout Afhandeling

Netwerkproblemen kunnen ervoor zorgen dat DNS lookups vastlopen. Implementeer timeout afhandeling:

async function getMxRecordsWithTimeout(domain, timeoutMs = 10000) {
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('DNS_TIMEOUT')), timeoutMs);
  });

  try {
    const result = await Promise.race([
      getMxRecords(domain),
      timeoutPromise
    ]);
    return result;
  } catch (error) {
    if (error.message === 'DNS_TIMEOUT') {
      return {
        success: false,
        domain,
        error: 'TIMEOUT',
        message: 'DNS lookup timed out',
        retryable: true
      };
    }
    throw error;
  }
}

Ongeldige Domein Afhandeling

Behandel domeinen die syntactisch ongeldig zijn voordat je DNS lookups probeert:

function isValidDomain(domain) {
  if (!domain || typeof domain !== 'string') {
    return false;
  }

  // Check length
  if (domain.length > 253) {
    return false;
  }

  // Check for valid characters and structure
  const domainRegex = /^(?!-)[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;

  if (!domainRegex.test(domain)) {
    return false;
  }

  // Check each label length
  const labels = domain.split('.');
  for (const label of labels) {
    if (label.length > 63) {
      return false;
    }
  }

  return true;
}

async function validateDomainMxSafe(domain) {
  if (!isValidDomain(domain)) {
    return {
      success: false,
      domain,
      error: 'INVALID_DOMAIN',
      message: 'Domain format is invalid'
    };
  }

  return await getMxRecordsWithTimeout(domain);
}

Tijdelijke DNS Fouten Afhandelen

DNS fouten kunnen tijdelijk zijn. Implementeer retry logica met exponential backoff:

async function getMxRecordsWithRetry(domain, maxRetries = 3) {
  const delays = [1000, 2000, 4000];

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const result = await getMxRecordsWithTimeout(domain);

    // Don't retry for definitive failures
    if (result.success ||
        result.error === 'NXDOMAIN' ||
        result.error === 'ENOTFOUND') {
      return result;
    }

    // Retry for temporary failures
    if (result.retryable && attempt < maxRetries - 1) {
      await sleep(delays[attempt]);
      continue;
    }

    return result;
  }
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Beveiligingsoverwegingen

MX validatie introduceert beveiligingsoverwegingen die ontwikkelaars moeten aanpakken.

DNS Spoofing Preventie

Standaard DNS queries zijn onversleuteld en kwetsbaar voor spoofing. Overweeg DNS over HTTPS (DoH) te gebruiken voor gevoelige applicaties:

const https = require('https');

async function getMxRecordsDoH(domain) {
  const url = `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(domain)}&type=MX`;

  return new Promise((resolve, reject) => {
    https.get(url, {
      headers: { 'Accept': 'application/dns-json' }
    }, (res) => {
      let data = '';

      res.on('data', chunk => data += chunk);

      res.on('end', () => {
        try {
          const response = JSON.parse(data);

          if (response.Status !== 0) {
            resolve({
              success: false,
              domain,
              error: 'DNS_ERROR',
              status: response.Status
            });
            return;
          }

          const records = (response.Answer || [])
            .filter(a => a.type === 15)
            .map(a => {
              const [priority, exchange] = a.data.split(' ');
              return {
                priority: parseInt(priority),
                exchange: exchange.replace(/\.$/, '')
              };
            })
            .sort((a, b) => a.priority - b.priority);

          resolve({
            success: records.length > 0,
            domain,
            records
          });
        } catch (error) {
          reject(error);
        }
      });
    }).on('error', reject);
  });
}

Rate Limiting DNS Queries

Voorkom misbruik door de snelheid van DNS queries te beperken:

class DnsRateLimiter {
  constructor(maxQueriesPerSecond = 100) {
    this.tokens = maxQueriesPerSecond;
    this.maxTokens = maxQueriesPerSecond;
    this.lastRefill = Date.now();
  }

  async acquire() {
    this.refillTokens();

    if (this.tokens > 0) {
      this.tokens--;
      return true;
    }

    // Wait for token availability
    await sleep(1000 / this.maxTokens);
    return this.acquire();
  }

  refillTokens() {
    const now = Date.now();
    const elapsed = now - this.lastRefill;
    const tokensToAdd = (elapsed / 1000) * this.maxTokens;

    this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
    this.lastRefill = now;
  }
}

const dnsLimiter = new DnsRateLimiter(50);

async function getMxRecordsRateLimited(domain) {
  await dnsLimiter.acquire();
  return getMxRecords(domain);
}

BillionVerify Gebruiken voor MX Validatie

Hoewel het zelf implementeren van MX validatie educatieve waarde biedt, behandelen professionele e-mailverificatieservices zoals BillionVerify MX validatie als onderdeel van uitgebreide e-mailverificatie.

Voordelen van een E-mailverificatie API Gebruiken

Uitgebreide Controles

BillionVerify's e-mailverificatie API combineert MX validatie met syntaxcontrole, SMTP-verificatie, detectie van wegwerp-e-mail en meer in een enkele API call. Dit elimineert de noodzaak om meerdere validatiesystemen te onderhouden.

Geoptimaliseerde Infrastructuur

Professionele services onderhouden wereldwijd verspreide DNS resolvers, handelen caching op schaal af en optimaliseren voor prestaties over miljoenen verificaties.

Continue Updates

Mailserver configuraties veranderen constant. E-mailverificatieservices updaten voortdurend hun databases van bekende providers, wegwerpdomeinen en mailserver patronen.

API Integratie Voorbeeld

async function verifyEmailWithBillionVerify(email) {
  const response = await fetch('https://api.billionverify.com/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.BV_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })
  });

  const result = await response.json();

  // MX information is included in the response
  console.log('MX Valid:', result.mx_found);
  console.log('Domain Valid:', result.domain_valid);
  console.log('Is Deliverable:', result.is_deliverable);

  return result;
}

Conclusie

MX record validatie is een fundamenteel onderdeel van e-mailverificatie dat bevestigt dat een domein e-mail kan ontvangen voordat meer resource-intensieve controles worden geprobeerd. Door correcte MX validatie te implementeren, kun je snel ongeldige domeinen filteren, verificatieprestaties optimaliseren en betrouwbaardere e-mailverwerkende applicaties bouwen.

Belangrijkste lessen voor MX record validatie:

  1. Controleer altijd MX records voordat je SMTP-verificatie probeert om tijd en resources te besparen
  2. Behandel de A record fallback volgens RFC-standaarden voor domeinen zonder MX records
  3. Implementeer caching om DNS lookup overhead te verminderen voor herhaalde validaties
  4. Herken veelvoorkomende patronen om e-mailproviders en potentiële risico's te identificeren
  5. Behandel fouten netjes met timeouts, retries en correcte foutmeldingen

Of je nu een aangepast e-mailverificatiesysteem bouwt of integreert met een service zoals BillionVerify, het begrijpen van MX records helpt je betere e-mailafhandeling in je applicaties te bouwen. Begin vandaag nog met het implementeren van MX validatie en zet de eerste stap naar uitgebreide e-mailverificatie.

Teams die Instantly of Smartlead gebruiken, verbeteren hun bezorgbaarheid door lijsten met BillionVerify te reinigen voor elke campagne.

Vergelijk BillionVerify met ZeroBounce op nauwkeurigheid en snelheid voordat u een verificatieprovider kiest.

Leo
LeoFounder, BillionVerify
E-mailverificatie-inzichten

Begin Vandaag met Verifiëren

Begin vandaag nog met het verifiëren van e-mails met BillionVerify. Ontvang 100 gratis credits bij aanmelding - geen creditcard vereist. Sluit u aan bij duizenden bedrijven die hun e-mailmarketing-ROI verbeteren met nauwkeurige e-mailverificatie.

Geen creditcard vereist · 100+ gratis credits per dag · Start binnen 30 seconden

99.9%
Nauwkeurigheid
Real-time
API-snelheid
$0.00014
Per e-mail
100/day
Altijd gratis