Skip to main content
BeginnerContacts and Data

Email Verification

Verify email addresses before sending in NimbusOS with provider integrations, catch-all detection, syntax validation, and bulk verification jobs.

8 min read
Updated April 23, 2026
1,800 words

Bounces kill sending reputation. A 5 percent bounce rate over a week can push a fleet into ISP spam folders that take months to escape. Email verification before the first send is the cheapest insurance you can buy. NimbusOS integrates with multiple verification providers, runs a three-layer validation on every address, caches verdicts to avoid double-charging, and runs bulk verification jobs for freshly imported lists. This article covers the verification layers, the provider choice, the catch-all handling, and the operational patterns.

The Three Layers of Validation

Every email that enters NimbusOS passes through three validation layers. The first two run immediately and have no cost. The third calls an external provider and costs a credit per verification.

Layer 1: Syntax Validation

Runs at parse time during CSV import and whenever a contact is created via API. Checks:

  • The email matches RFC 5321 grammar.
  • The local part (before the @) is at most 64 characters.
  • The domain part is at most 255 characters.
  • No illegal characters in either part.

Failures: invalid_syntax. Rejected immediately; no cost, no provider call.

Layer 2: Disposable and Role Detection

Runs after syntax. Checks the domain against a built-in list of known disposable email providers (mailinator, guerrillamail, 10minutemail, and several hundred more). Also flags role-based addresses like info@, sales@, support@, admin@.

Outcomes:

  • disposable: Rejected. Disposable addresses are not usable prospects.
  • role_based: Flagged but not rejected. You can still send, but these addresses rarely generate individual replies.

The disposable list is maintained by NimbusOS and updated weekly.

Layer 3: Provider Verification

Runs on demand. Calls an external provider to attempt SMTP verification, MX record checks, and catch-all detection.

The provider returns a verdict:

  • valid: Verified deliverable. Safe to send.
  • invalid: Confirmed undeliverable. Reject.
  • catch_all: Domain accepts all email; cannot distinguish valid from invalid.
  • unknown: Provider could not verify. Treat as risky.
  • abuse: Address is on a known abuse list. Reject and suppress.

Catch-all handling is the tricky part and has its own section below.

Supported Providers

Three providers integrated directly.

ZeroBounce. Widely used, moderate cost, strong catch-all detection. Accuracy around 98 percent on clean addresses.

NeverBounce. Fast, strong on enterprise domains, weaker on niche small-business domains.

Hunter. Best when the email was sourced through Hunter's finder in the first place. Integrated verification is cheap for Hunter-sourced contacts.

All three support BYOK. Your API key in Integrations, your credits from your account, no NimbusOS markup.

Catch-All Domains

A catch-all domain accepts email for any local part at the domain. any-random-string@catch-all-example.com is accepted. The SMTP handshake cannot distinguish a real mailbox from a fake one.

About 15 percent of B2B domains are catch-all. The verification provider will return catch_all rather than valid or invalid for these.

NimbusOS maintains a DomainCatchAllCache table. Once a domain is confirmed catch-all, all future verification requests for that domain return catch-all from the cache without a provider call, saving credits.

Three strategies for handling catch-all addresses.

Accept them. Catch-all bounce rates are higher than verified-valid addresses (5 to 10 percent vs under 1 percent), but they are not universally bad. For a tier A prospect, the risk is worth it.

Reject them conservatively. Drop every catch-all from your sending list. Lower volume but minimum bounce risk.

Tiered approach. Accept catch-all for tier A and B, reject for tier C and D. This balances volume against reputation risk.

The campaign-level setting allow_catch_all is a boolean. Workspace default applies unless the campaign overrides.

Bulk Verification Jobs

A BulkVerificationJob verifies a large list at once. Two common triggers.

Post-import. After an ImportJob completes, kick off a bulk verification of the new contacts. This is the most common pattern for cold outreach.

Pre-launch. Right before launching a campaign, verify the target segment. Useful when the segment is dynamic and members have been added since the last verification pass.

Bulk jobs run asynchronously. A 10k contact list typically completes in 20 to 60 minutes depending on provider rate limits. The job summary shows counts by verdict.

Bulk jobs write results to each contact's verification_status field and update the cache.

Verification Status on the Contact

Every contact carries a verification_status field.

  • unverified: No verification has run.
  • valid: Most recent verification returned valid.
  • invalid: Confirmed undeliverable. Contact is marked invalid and auto-suppressed.
  • catch_all: Domain is catch-all.
  • role_based: Flagged role address.
  • disposable: Rejected at parse.
  • unknown: Provider could not determine.
  • stale: Last verification over 180 days old, recommend re-verify.

Verification status is visible in the Contact detail and queryable in segments.

Verification Caching

Every verification verdict is cached with a 180 day TTL. Re-verifying the same email within 180 days returns the cached verdict without a provider call.

Cache bypass: set force_refresh=true on the verification job. Useful when you suspect the address may have changed status (e.g., a valid address that started bouncing).

Cache entries are scoped by email hash. Cross-workspace sharing is on by default because verification verdicts do not carry PII beyond the address itself, and sharing the cache is beneficial to every workspace on the platform. You can opt out in Account Settings if compliance requires.

Re-Verification on Stale Contacts

Contacts with verification_status = stale should be re-verified before the next cold send. A stale verdict usually means a valid address that has not been used in a while and may have since changed.

Automation pattern:

Trigger: on_schedule, weekly
Condition: verification_status == 'stale' AND contact_active == true
Action: enqueue_bulk_verification

This is a standard rule many agencies enable globally.

Integration with Campaign Launch

A campaign can require verification before enrolling contacts. On the campaign configuration, set require_verification=true. The enrollment step checks verification_status:

  • valid: enrolled.
  • catch_all: enrolled only if allow_catch_all=true.
  • invalid or disposable: skipped.
  • unverified or stale: triggers a just-in-time verification before enrollment.

Just-in-time verification can slow the first batch by 10 to 30 minutes depending on the list size. For time-sensitive campaigns, run a bulk verification in advance.

Verification and Bounce Intelligence

A bounce event feeds back to verification. If an address that was verified valid produces a hard bounce, the verification cache is invalidated for that address. Future sends re-verify.

The bounce intelligence model tracks accuracy per provider. Over time you can see that provider X has 99.2 percent accuracy on valid verdicts and provider Y has 97.8 percent. Use this to tune your provider choice.

Cost Estimation

Every provider charges per verification. Typical costs:

  • ZeroBounce: roughly 0.5 cent per verification in bulk pricing
  • NeverBounce: roughly 0.4 cent per verification in bulk pricing
  • Hunter: free for Hunter-sourced contacts, 0.3 cent for others

A 50,000 contact bulk verification costs between 150 and 250 USD depending on provider. Cache hits are free; at 40 percent cache hit rate the actual cost is 60 to 100 USD.

Troubleshooting

"Bulk verification is slow"

Rate limits on the provider. ZeroBounce caps at 100 per second, NeverBounce at 200 per second. A 10k list at 100 per second takes 100 seconds minimum. Large lists are not instant.

"Verification says valid but bounces are high"

Two possibilities. The list has aged (addresses were valid at verification time but have since changed). Re-verify. Or the catch-all rate is high and allow_catch_all=true is including too many risky addresses.

"Verification credits are zero unexpectedly"

Check the provider dashboard for your account balance. BYOK credits burn from your provider account. If the balance is zero, verification fails with credit_exhausted.

"Enabled catch-all disabled but still seeing catch-all sends"

The allow_catch_all setting may be set at the workspace level and overridden per campaign. Check the campaign's individual setting.

Frequently Asked Questions

Do I need to verify every contact, even ones from a trusted source?

Verifying every imported contact is the safe default. Even trusted sources (CRM syncs, vendor exports) carry stale addresses that have changed since the last sync. The cost is low and the reputation savings are high.

Does NimbusOS have a built-in verifier?

The syntax and disposable layers are built in. The deep SMTP verification is provider-dependent. NimbusOS does not run its own SMTP verification at scale because doing so from shared NimbusOS infrastructure would burn its IP reputation for verification traffic.

Can I verify email addresses without adding them to NimbusOS?

Yes, through the API. POST /api/v1/contacts/verify accepts an array of emails and returns verdicts without creating contacts. Useful for pre-intake verification in external pipelines.

What is the accuracy difference between providers?

Published accuracy claims range from 95 to 99 percent. Real-world accuracy depends heavily on the target market. Enterprise Microsoft 365 domains verify reliably across all providers. Niche European providers have more variance.

Useful next pages after this one: Data Enrichment for the sibling data quality flow, Bounce Intelligence for the bounce classification downstream of verification, and Deliverability Overview for how verification feeds the NDS score.

Related articles

Still stuck?

Our team answers every support ticket. If the answer is not in the docs, open a ticket and we will write the missing page.