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.
# 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 ByeKó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 5321 | Co z toho ověřovač může vyvodit |
|---|---|---|
| 220 | Služba připravena (uvítací banner) | Server mluví SMTP; kontrola může pokračovat. |
| 250, 251, 252 | Akce dokončena, zprávu přepošle, nebo nemůže ověřit, ale zprávu přijme | Server teď poštu pro tohoto příjemce převezme. U accept-all serveru to o schránce nic neříká. |
| 421 | Služba není k dispozici, spojení se uzavírá | Nic nelze vyvodit; server je vytížený nebo ověřovač odmítá. |
| 450, 451, 452 | Schrá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. |
| 550 | Schrá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, 554 | Uživatel není místní, překročeno úložiště, nepovolený název schránky, transakce selhala | Trvalé 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.
{
"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ůvod | status | score | Význam |
|---|---|---|---|
| ok | valid | 97 (80 u rolových adres) | Server adresu přijal a náhodnou adresu nepřijal. |
| catch_all | risky | 60 | Server přijal adresu i náhodnou adresu. |
| mailbox_missing | invalid | 2 | Server příjemce odmítl odpovědí v rozsahu 500 až 559. |
| smtp_unknown | risky | 50 | Žá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_unreachable | valid | 75 (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. |
| timeout | risky | 50, nebo 60, pokud byla adresa přijata, ale test accept-all nedoběhl | Vypršel volitelný časový limit timeout_ms. Výsledek se do cache neukládá. |
| no_mx | invalid | 0 | Doména nemá MX ani A záznam. |
| syntax | invalid | 0 | Adresa 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ůvod | Doporučená akce |
|---|---|
| ok | Odeslat. |
| smtp_unreachable | Odesílat opatrně: po malých dávkách a adresy s hard bounce hned odstraňovat. Schránka nebyla potvrzena. |
| catch_all | Zkontrolovat. Ponechat, jen pokud máte jiný signál, že osoba existuje, například odpověď nebo známý vzor adres v dané firmě. |
| smtp_unknown | Zkontrolovat. Nová kontrola do 30 dnů vrátí výsledek z cache a stejně stojí kredit. |
| timeout | Zkontrolovat znovu s vyšším timeout_ms, až 30 000; timeouty se do cache neukládají. |
| mailbox_missing, no_mx, syntax | Vyřadit. |
| disposable v reasons | Pro B2B oslovování vyřadit. |
// 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čí.