To verify an email list before a go-to-market campaign, run one Cargo batch call over the addresses with a verifier such as waterfall.verifyEmail (0.1 credits per address), then send only to the addresses that come back valid. Verification is billed per check: unlike a finder, a verifier charges for every address it checks, whatever the verdict.
No ZeroBounce, NeverBounce or Bouncer account is needed: Cargo calls each verifier on its own key and bills credits. The steps below are the verify-email-list skill, end to end.
What 2.09M verification runs show #
Cargo platform data, 90 days to Oct 16 2026: 2.09M email verification runs across 603 workspaces, and 66.4% of them came back valid.
The other third came back with some other verdict: invalid, catch-all, unknown, or a provider-specific status. That is the share of a typical list a verifier will not vouch for, and the reason to verify before the send rather than after the bounces.
What the verdicts mean #
- Valid. The receiving server confirmed the mailbox exists. Send.
- Invalid. The domain or the mailbox does not exist. Drop it: these are the hard bounces that hurt a sending domain.
- Catch-all (accept-all). The domain’s server accepts mail for any address, real or not, so no verifier can tell whether this particular mailbox exists. A catch-all result is not a pass and not a fail; it is the absence of an answer. Many company domains are configured this way, and no provider resolves it by checking harder.
- Unknown. The server did not give a usable answer during the check (it timed out, greylisted the request, or refused it). Re-verify later or treat it like catch-all.
What to do with catch-all addresses is a sending decision, not a verification result. The conservative choice is to leave them out of a cold campaign. The other choice is to send to them from a small, separate batch and watch the bounce rate before sending more.
Run it #
1. Install and sign in
npm install -g @cargo-ai/cli
cargo-ai login --email you@company.com # sends a code
cargo-ai login --email you@company.com --code 123456 # creates the account on first use
There is no browser step, so a coding agent can run this itself. A new account starts with 100 free credits and no card, which covers 1,000 checks on waterfall.verifyEmail or zeroBounce.verifyEmail.
2. Pilot on 10 addresses
cargo-ai orchestration action execute-batch \
--action '{"kind":"connector","integrationSlug":"waterfall","actionSlug":"verifyEmail"}' \
--records '[{"email":"ada@example.com"},{"email":"grace@example.org"}]' \
--limit 10 --wait-until-finished
--limit 10 submits only the first ten records, so you can read the verdicts and the cost before the full run. Every record is {"email":"..."}, on every verifier except Findymail, which also takes "objectType":"email".
3. Run the list and download the verdicts
Drop --limit to run every address, then:
cargo-ai orchestration batch download --uuid <batch-uuid>
The result is a CSV: your input columns, plus the verifier’s fields prefixed cargo_, for example cargo_email_status on waterfall.verifyEmail.
4. Split the list
Keep the valid rows, drop the invalid ones, and set catch-all and unknown aside for the decision above. Do not re-verify the whole list with a second provider: every check is billed again.
Verifiers and the field to read #
| Action | Credits per check | Verdict field | Catch-all signal |
|---|---|---|---|
icypeas.verifyEmail | 0.01 | emails[].certainty | none separate |
waterfall.verifyEmail | 0.1 | email_status (valid when deliverable) | none separate |
zeroBounce.verifyEmail | 0.1 | status, with sub_status | catchall_domain (true or false) |
enrichley.verify | 0.1 | valid (true or false), with result | none separate |
neverBounce.verifyEmail | 0.2 | result, with flags | none separate |
findyMail.verifyEmail | 0.25 | verified (true or false) | none separate |
bouncer.verifyEmail | 0.3 | status, with reason and score | domain.acceptAll |
hunter.verifyEmail | 1 | status: valid, invalid, accept_all, webmail, disposable or unknown | accept_all (true or false) |
Prices are each action’s list price. In the run log, Cargo marks a check as passed only when the verifier said valid: status or result equal to valid, valid or verified true. Two verifiers bill differently from the rest:
bouncer.verifyEmailreturns no data, and charges nothing, when Bouncer saysundeliverable. Every other verdict comes back with its data and is charged, so readstatusanddomain.acceptAllrather than assuming a returned row is deliverable.icypeas.verifyEmailreportsprobable,undeliverableandnot_foundcertainties as not valid, and returns no data when Icypeas has no result.
Verify even when the finder sent a status #
A finder grading its own result is not an independent check. If the addresses came from an email finder, run them through a verifier before the send; find and verify work emails at scale covers both steps as one flow, and the find-work-email skill covers the finding.
Frequently asked questions #
Verification is billed per check, whatever the verdict. On
waterfall.verifyEmail or zeroBounce.verifyEmail it is 0.1 credits per
address, so 10,000 addresses cost 1,000 credits. The cheapest verifier in
the catalog, icypeas.verifyEmail, is 0.01 credits per address.
The domain’s mail server accepts every address, real or not, so a verifier cannot confirm that a specific mailbox exists. A catch-all result is the absence of an answer, not a pass. Leave those addresses out of a cold send, or send to them in a small separate batch and watch the bounce rate.
Treat them like catch-all. Unknown means the server gave no usable answer during the check. Re-verifying later sometimes resolves it, at the price of a second check.
No. Unless you connect your own key, Cargo calls the verifier on Cargo’s key and bills the action’s credits. If you already pay a verifier, you can connect your key instead.