Cold Leads

Jak funguje detekce accept-all a jak číst výsledky Cold Leads

Pro koho
Vývojáři a provozní týmy, kteří rozhodují, co dělat s rizikovými výsledky
Problém
Některé poštovní servery přijímají poštu pro jakoukoli adresu na své doméně, takže kontrola schránky nerozliší skutečného člověka od vymyšleného jména. Jiné servery odpovídají jen dočasně nebo nejsou dosažitelné vůbec a samotné označení valid může zakrýt, že se schránka nikdy nekontrolovala.
Řešení
Pochopte SMTP dialog, který ověřovač vede, a co která odpověď znamená, a pak čtěte stav, skóre a kódy důvodu, které Cold Leads vrací, včetně případů, kdy test schránky neproběhl.
Co získáte
Rozhodovací tabulka, která každému kódu důvodu Cold Leads přiřadí akci, a skript, který ji použije na jednu adresu.

Adresy, identifikátory a výsledky v příkladech jsou ilustrativní. Doména example.com je vyhrazená pro dokumentaci, takže skutečná kontrola těchto adres vrátí invalid.

Ukázky kódu jsou ve všech jazycích stejné, komentáře v nich jsou anglicky.

SMTP dialog za kontrolou schránky

Ověřovač vyhledá MX hosty domény a otevře SMTP spojení k jednomu z nich na portu 25. Pozdraví server, uvede odesílatele a příjemce, přečte odpověď na příjemce a rozloučí se dřív, než by se odeslala jakákoli zpráva. Druhá relace se stejného serveru zeptá na adresu, která nemůže existovat.

Dvě SMTP relace (ilustrace)
# Session 1: is the address accepted?
S: 220 mx1.example.com ESMTP
C: EHLO verifier.example.net
S: 250-mx1.example.com
S: 250 SIZE 52428800
C: MAIL FROM:<check@verifier.example.net>
S: 250 2.1.0 Sender OK
C: RCPT TO:<anna@example.com>
S: 250 2.1.5 Recipient OK          <- accepted (a 550 here would mean: rejected)
C: QUIT                            <- no DATA command: nothing is delivered
S: 221 2.0.0 Bye

# Session 2: would the same server also accept an address that cannot exist?
S: 220 mx1.example.com ESMTP
C: EHLO verifier.example.net
S: 250 mx1.example.com
C: MAIL FROM:<check@verifier.example.net>
S: 250 2.1.0 Sender OK
C: RCPT TO:<zq7c41e09b2a6f5d@example.com>
S: 250 2.1.5 Recipient OK          <- also accepted: the server accepts all addresses
C: QUIT
S: 221 2.0.0 Bye

Kódy odpovědí a co z nich lze vyvodit

Kódy odpovědí definuje RFC 5321. Význam nese první číslice: 2 je úspěch, 4 dočasné selhání, 5 trvalé selhání.

OdpověďVýznam podle RFC 5321Co z toho ověřovač může vyvodit
220Služba připravena (uvítací banner)Server mluví SMTP; kontrola může pokračovat.
250, 251, 252Akce dokončena, zprávu přepošle, nebo nemůže ověřit, ale zprávu přijmeServer teď poštu pro tohoto příjemce převezme. U accept-all serveru to o schránce nic neříká.
421Služba není k dispozici, spojení se uzavíráNic nelze vyvodit; server je vytížený nebo ověřovač odmítá.
450, 451, 452Schránka nedostupná, lokální chyba, nedostatek úložiště (dočasně)Nic nelze vyvodit. Servery s greylistingem takto odpovídají neznámým odesílatelům a čekají nový pokus o několik minut později.
550Schránka nedostupná, například nenalezena, nebo odmítnuto podle pravidel (policy)Obvykle schránka neexistuje, ale blokace ověřujícího serveru podle pravidel vypadá stejně.
551, 552, 553, 554Uživatel není místní, překročeno úložiště, nepovolený název schránky, transakce selhalaTrvalé odmítnutí tohoto příjemce v této relaci.

Test accept-all, greylisting a další omezení

  • Accept-all: když server přijme skutečnou adresu, ověřovač se ho zeptá na náhodnou lokální část na stejné doméně. Pokud přijme i tu, první přijetí nenese žádnou informaci a výsledek je risky s důvodem catch_all.
  • Greylisting (RFC 6647): server dočasně odmítá neznámé kombinace odesílatele a příjemce odpovědí 4xx a pozdější pokus přijme. Jediný průchod vidí jen 4xx a Cold Leads v rámci jedné kontroly nečeká a pokus neopakuje, takže výsledek je risky se smtp_unknown.
  • Pozdní bounce: některé servery během dialogu přijmou každého příjemce a neznámé odmítnou až po přijetí zprávy, vrácením (bounce). Kontrola to nevidí.
  • Blokace podle pravidel: server může odmítnout samotný ověřující host. Cold Leads vyhodnotí odmítnutí v kroku pozdravu, EHLO nebo MAIL FROM jako smtp_unknown a jakoukoli odpověď 500–559 u RCPT TO jako mailbox_missing.
  • Port 25: test potřebuje odchozí SMTP spojení. Mnoho cloudových a serverless platforem odchozí port 25 blokuje a pak žádný dialog vůbec neproběhne.

Co Cold Leads vrací a kdy test neproběhl

Kontrola probíhá v tomto pořadí: syntaxe (chyba kontrolu ukončí), vestavěný seznam 40 jednorázových e-mailových domén, seznam 25 rolových názvů (info, sales, support, admin a další) a vyhledání MX, které se při chybějícím MX záznamu vrátí k A záznamu domény. SMTP test schránky a accept-all proběhne jen tehdy, když Cold Leads dokáže otevřít SMTP spojení s jedním z prvních dvou MX hostů. Pole reasons vám vždy řekne, o který případ jde.

POST /api/v1/verify, doména, jejíž poštovní server nebyl přes SMTP dosažitelný
{
  "email": "anna@example.com",
  "status": "valid",
  "score": 75,
  "reasons": ["smtp_unreachable"],
  "mx": "mx1.example.com",
  "catch_all": false,
  "disposable": false,
  "role": false,
  "checked_at": "2026-09-30T08:15:02.114Z",
  "cached": false
}
Poslední důvodstatusscoreVýznam
okvalid97 (80 u rolových adres)Server adresu přijal a náhodnou adresu nepřijal.
catch_allrisky60Server přijal adresu i náhodnou adresu.
mailbox_missinginvalid2Server příjemce odmítl odpovědí v rozsahu 500 až 559.
smtp_unknownrisky50Žádná jednoznačná odpověď: dočasná odpověď 4xx, odmítnutí ověřovače, MX host v privátní síti nebo kombinace nedosažitelných a nejasných hostů.
smtp_unreachablevalid75 (65 u rolových adres)Z ověřujícího hostu neodpověděl na portu 25 žádný MX host. Doména přijímá poštu, ale schránka ani accept-all se netestovaly.
timeoutrisky50, nebo 60, pokud byla adresa přijata, ale test accept-all nedoběhlVypršel volitelný časový limit timeout_ms. Výsledek se do cache neukládá.
no_mxinvalid0Doména nemá MX ani A záznam.
syntaxinvalid0Adresa nesplňuje syntaktická pravidla; nic dalšího se nekontroluje.
  • disposable a role se objeví před posledním důvodem, pokud platí. Jednorázová doména změní status na risky se skóre 40 (ok), 30 (smtp_unreachable) nebo 20 (smtp_unknown).
  • catch_all je true, jen když test accept-all proběhl a náhodná adresa byla přijata. Hodnota false něco vypovídá, jen když je poslední důvod ok nebo mailbox_missing; po smtp_unreachable, smtp_unknown nebo timeout se accept-all netestoval. MCP nástroj verify_email, hostovaný i lokální, v těchto případech vrací catch_all jako null; REST API vrací false.
  • cached je true, když výsledek pochází z 30denní cache; checked_at pak ukazuje čas původní kontroly.
  • Výsledky hromadných úloh nesou jen poslední kód důvodu, v poli reason.

Rozhodovací tabulka a skript, který ji použije

Poslední důvodDoporučená akce
okOdeslat.
smtp_unreachableOdesílat opatrně: po malých dávkách a adresy s hard bounce hned odstraňovat. Schránka nebyla potvrzena.
catch_allZkontrolovat. Ponechat, jen pokud máte jiný signál, že osoba existuje, například odpověď nebo známý vzor adres v dané firmě.
smtp_unknownZkontrolovat. Nová kontrola do 30 dnů vrátí výsledek z cache a stejně stojí kredit.
timeoutZkontrolovat znovu s vyšším timeout_ms, až 30 000; timeouty se do cache neukládají.
mailbox_missing, no_mx, syntaxVyřadit.
disposable v reasonsPro B2B oslovování vyřadit.
decide.mjs
// node decide.mjs anna@example.com   (Node 18+, COLDLEADS_API_KEY=sk_... in the environment)
const email = process.argv[2];
const res = await fetch("https://coldleads.app/api/v1/verify", {
  method: "POST",
  headers: { "x-api-key": process.env.COLDLEADS_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ email, timeout_ms: 10000 }),
});
const r = await res.json();
if (!res.ok) throw new Error(`HTTP ${res.status}: ${r.error}`);

const final = r.reasons[r.reasons.length - 1];
// catch_all only carries information when a mail server answered the probe
const smtpAnswered = ["ok", "catch_all", "mailbox_missing"].includes(final);
const ACTION = {
  ok: "send",
  smtp_unreachable: "send carefully: domain accepts mail, mailbox not checked",
  catch_all: "review: the server accepts every address",
  smtp_unknown: "review: no definite answer from the server",
  timeout: "check again with a larger timeout_ms",
  mailbox_missing: "drop",
  no_mx: "drop",
  syntax: "drop",
};
console.log({
  email: r.email,
  status: r.status,
  score: r.score,
  reasons: r.reasons,
  mailbox_checked: smtpAnswered,
  catch_all: smtpAnswered ? r.catch_all : "not tested",
  cached: r.cached,
  action: r.disposable ? "drop: disposable domain" : ACTION[final] ?? "review",
});

Limity a náklady

  • 1 kredit za ověření, včetně chyb syntaxe a výsledků z 30denní cache.
  • timeout_ms je volitelný a přijímá 1 000 až 30 000 milisekund; na jakoukoli jinou hodnotu API odpoví 400 bad_timeout.
  • API je součástí tarifu Business: $99 měsíčně s 10 000 kredity měsíčně; další balíčky po 1 000 kreditech stojí $5. 120 požadavků za minutu na klíč.

Otázky

Proč je adresa valid, když se její schránka nekontrolovala?

Protože to, že se z ověřujícího hostu nepodařilo spojit s poštovním serverem, není důkaz proti adrese. Stav odráží kontroly, které proběhly: syntaxe je správná a doména přijímá poštu. Nižší skóre (75 místo 97) a důvod smtp_unreachable vám říkají, že samotná schránka se netestovala.

Znamená catch_all false, že doména není accept-all?

Jen pokud test proběhl, což poznáte podle posledního důvodu ok nebo mailbox_missing. Po smtp_unreachable, smtp_unknown nebo timeout se accept-all vůbec netestoval.

Změní opakovaná kontrola rizikové adresy výsledek?

Do 30 dnů vrátí nová kontrola výsledek z cache (cached: true) a stejně stojí 1 kredit. Výsledky s timeout se do cache neukládají, takže ty se vyplatí zkontrolovat znovu s vyšším timeout_ms.

Pošle ověření dané osobě e-mail?

Ne. Dialog končí příkazem QUIT hned po kroku s příjemcem, před příkazem DATA, takže se žádná zpráva nedoručí.