Migrate from NeverBounce
This guide maps the NeverBounce API v4.2 (single check, jobs, and account info) to the Tomba Email Verifier and bulk verifier jobs. NeverBounce API behavior checked on 2026-09-29 against the NeverBounce API reference.
Before you begin
- Get your API key (
ta_…) and secret (ts_…); see Authentication. - Check what a verification costs in Credit costs and your plan's throttling in Limits by plan.
- Set your HTTP client timeout to at least 180 seconds. A client timeout of about 10 seconds, as NeverBounce suggests, cuts off Tomba verifications that take longer.
Endpoint mapping
Replace the base URL https://api.neverbounce.com/v4.2 (or /v4) with https://api.tomba.io.
| NeverBounce | Tomba |
|---|---|
GET /single/check (or POST) | GET /v1/email-verifier |
POST /jobs/create | POST /v1/bulk/verifier |
POST /jobs/parse | Not needed. Tomba parses the list when you create the job. |
POST /jobs/start | PUT /v1/bulk/verifier/{id} |
GET /jobs/status | GET /v1/bulk/verifier/{id}/progress |
GET /jobs/results | No equivalent. Download the job's CSV. |
GET /jobs/download | GET /v1/bulk/verifier/{id}/download |
POST /jobs/delete | DELETE /v1/bulk/verifier/{id}/delete |
GET /jobs/search | GET /v1/bulk/verifier |
GET /account/info | GET /v1/me |
Authentication changes
NeverBounce reads the key from the key parameter. Tomba needs two headers, X-Tomba-Key and X-Tomba-Secret, and doesn't accept credentials in the query string or body:
Code
Tomba API keys expire; plan their rotation with Key expiry.
Parameter mapping
| NeverBounce | Tomba | Notes |
|---|---|---|
email | email | Required. A malformed address returns 422 params_invalid instead of a result. |
timeout | No equivalent | Set the timeout in your HTTP client. |
address_info | No equivalent | |
credits_info | No equivalent | Read the X-Verify-Remaining header or GET /v1/me; see Check usage. |
Response field mapping
NeverBounce returns a flat object. Tomba nests the checks in data.email and lists the public pages where the address appears in data.sources. Field definitions are in Email verifier response.
| NeverBounce | Tomba | Notes |
|---|---|---|
status | HTTP status code, errors.type | See Error mapping. |
result | data.email.status, data.email.result | See Status mapping. |
flags | Booleans in data.email | See the flag table below. |
suggested_correction | No equivalent | |
execution_time | No equivalent | |
address_info | No equivalent | data.email.email holds the address that was checked. |
credits_info | X-Verify-Remaining header, GET /v1/me | See Check usage. |
| NeverBounce flag | Tomba field |
|---|---|
has_dns_mx | data.email.mx_check is true |
free_email_host | data.email.webmail is true |
disposable_email | data.email.disposable is true |
accepts_all | data.email.accept_all is true |
bad_syntax | The request fails with 422 params_invalid |
has_dns, bad_dns, temporary_dns_error, smtp_connectable, connect_fails, role_account, profanity, government_host, academic_host, military_host, international_host, squatter_host, spamtrap_network, spelling_mistake, contains_alias, contains_subdomain, historical_response | No equivalent |
Tomba also returns block, greylisted, gibberish, regex, smtp_provider, mx.records, and whois, which have no NeverBounce counterpart.
Status mapping
NeverBounce result | Tomba status | Tomba result |
|---|---|---|
valid | valid | deliverable |
invalid | invalid | undeliverable |
disposable | disposable | Empty string |
catchall | accept_all | risky |
unknown | unknown | risky |
Branch on status: it has one value for each NeverBounce result, while result groups accept_all and unknown as risky. Compare status case-insensitively. Each value is defined in Status values.
Error mapping
NeverBounce reports failures in the status field of an HTTP 200 response. Tomba returns an HTTP error status with an errors object, so check the status code rather than a field in the body.
NeverBounce status | Tomba | What to do |
|---|---|---|
auth_failure | 400 authentication_failed (missing or malformed), 400 api_key_expired, 401 authentication_failed (wrong key or secret) | Check both headers; rotate an expired key. |
throttle_triggered | 429 rate_limit | Retry after the Retry-After delay; see Handle 429 responses. |
temp_unavail | 500 api_error, 504, or 408 proxy_error | Retry with backoff. 408 means the mailbox check failed. |
general_failure | 422 params_invalid for a bad parameter, 402 quota_exceeded when your credits don't cover the request | Read errors.type to find the cause. |
bad_referrer | No equivalent | |
| No equivalent | 451 claimed_email | The owner of the address asked Tomba to stop processing it. Remove it from your list. |
Error responses don't consume credits. Every type is listed in Errors.
Bulk and async jobs
| NeverBounce | Tomba |
|---|---|
jobs/create with input_location: supplied and input | POST /v1/bulk/verifier with name and a newline-separated list of addresses |
jobs/create with input_location: remote_url | No equivalent. Upload the file as file; set email_field_index (zero-based) if its header doesn't name the address column. |
auto_parse, jobs/parse | Not needed |
auto_start, jobs/start | Launch with PUT /v1/bulk/verifier/{id} |
run_sample | No equivalent |
callback_url | webhook_url, which receives a signed bulk.completed event. See Bulk job events. |
jobs/download segmentation (valids, invalids, …) | GET /v1/bulk/verifier/{id}/download with file=full or file=valid |
Code
The launch, progress, and download requests are shown in Lifecycle. Row limits and daily job limits are in Limits, and a job is charged when you first download its results; see Billing.
Code example
This function replaces a call to single/check and returns NeverBounce's result value and the flags Tomba can supply. It needs Node.js 18 or later.
Code
Cutover checklist
- Store the Tomba key and secret as
TOMBA_API_KEYandTOMBA_SECRET_KEY, send them asX-Tomba-KeyandX-Tomba-Secret, and remove thekeyparameter from your URLs and logs. - Point single checks at
GET https://api.tomba.io/v1/email-verifierand raise your client timeout to at least 180 seconds. - Replace checks of the
statusfield with HTTP status handling:402,429withRetry-After,451, and408. - Translate
resultand flags with the status mapping and flag table, comparingstatuscase-insensitively. - Replace jobs with
verifierbulk jobs: create withlistorfile, launch, receive thewebhook_urlevent instead of the callback, and download the CSV. - Verify the same sample list with both services and compare the mapped results before you switch production traffic.