Migrate from Findymail
This guide maps the Findymail API (the /api/search/* endpoints, /api/verify, and /api/credits) to Tomba. Findymail API behavior checked on 2026-09-29 against the Findymail API reference.
Before you begin
- Get your API key (
ta_…) and secret (ts_…); see Authentication. - Check what each endpoint costs in Credit costs and your plan's throttling in Limits by plan.
- Findymail endpoints take
POSTrequests with JSON bodies. Tomba lookups areGETrequests with query parameters.
Endpoint mapping
Replace the host app.findymail.com with api.tomba.io.
| Findymail | Tomba | Notes |
|---|---|---|
POST /api/search/name | GET /v1/email-finder | |
POST /api/search/domain | GET /v1/domain-search | |
POST /api/search/employees | GET /v1/domain-search | Returns people with their addresses. Filters by department, not job title. |
POST /api/search/business-profile | GET /v1/linkedin | |
POST /api/search/reverse-email | GET /v1/enrich | Returns the person, company, and LinkedIn URL for an address. |
POST /api/search/phone | GET /v1/phone-finder | Also accepts an email address or a domain. |
POST /api/search/company | GET /v1/companies/find | Looks up by domain only. |
POST /api/verify | GET /v1/email-verifier | |
GET /api/credits | GET /v1/me |
Authentication changes
Findymail reads a bearer token. Tomba needs two headers, X-Tomba-Key and X-Tomba-Secret:
Code
Tomba API keys expire; plan their rotation with Key expiry.
Parameter mapping
| Findymail endpoint and field | Tomba parameter | Notes |
|---|---|---|
search/name name | full_name | Or send first_name and last_name. |
search/name domain | domain or company | Findymail takes a domain or a company name in one field. Send a domain as domain and a company name as company. |
webhook_url | webhook_url | Tomba still returns the result in the response, and also posts it to your URL when the result qualifies. See Per-request callbacks. |
search/domain domain, search/employees website | domain | |
search/domain roles, search/employees job_titles | department | Tomba filters by department from a fixed list, not by free-text role. The values are in the API reference. |
search/employees count | limit | The cost depends on limit; see Credit costs. |
search/business-profile linkedin_url | url | |
search/reverse-email email | email | |
search/reverse-email with_profile | No equivalent | /v1/enrich returns every person field it has. |
search/phone linkedin_url | linkedin | |
search/company domain | domain | |
search/company linkedin_url, name | No equivalent | Get the domain for a company name with GET /v1/domain-suggestions. |
verify email | email |
Response field mapping
Tomba wraps every result in data.
| Findymail | Tomba | Notes |
|---|---|---|
contact.email | data.email | null when no address is found. |
contact.name | data.full_name | data.first_name and data.last_name are also returned. |
contact.domain | data.website_url | |
contacts[] (search/domain) | data.emails[] | Each item has email, full_name, position, department, and verification. |
Employees name, jobTitle, linkedinUrl | data.emails[].full_name, position, linkedin | |
Employees companyName, companyWebsite | data.organization.organization, data.organization.website_url | |
Reverse email linkedin_url | data.linkedin | |
Reverse email profile fullName, jobTitle, companyName, companyWebsite, country | data.full_name, data.position, data.company, data.website_url, data.country | data.country is a two-letter country code. |
Reverse email profile headline, summary, skills, jobs, educations, certificates, city, region | No equivalent | |
Phone phone | data.e164_format | Tomba also returns national and international formats. See Phone. |
Phone line_type | data.line_type | Tomba uses its own line type values. |
Company name, domain, description | data.name, data.domain, data.description | |
Company company_size | data.metrics.employees | A range, such as 51-200. |
Company linkedin_url | data.linkedin.handle | The handle only, not a URL. |
Company industry | No equivalent | GET /v1/domain-search returns it in data.organization.industries. |
Verify email | data.email.email | |
Verify verified | data.email.status | See Status mapping. |
Verify provider | data.email.smtp_provider | |
Credits credits, verifier_credits | GET /v1/me | See Check usage. |
The email finder returns its best match with a verification status in data.verification.status, including catch-all (accept_all) and unconfirmed (unknown) matches. If your code expects only verified addresses, keep results whose status is valid.
Status mapping
Findymail's verifier returns a boolean. Tomba returns a detailed status and a result verdict:
Findymail verified | Tomba status | Tomba result |
|---|---|---|
true | valid | deliverable |
false | invalid | undeliverable |
false | accept_all or unknown | risky |
false | disposable | Empty string |
Compare status case-insensitively. Each value is defined in Status values.
Error mapping
| Findymail | Tomba | What to do |
|---|---|---|
401 Unauthenticated. | 400 authentication_failed (missing or malformed), 400 api_key_expired, 401 authentication_failed (wrong key or secret) | Check both headers; rotate an expired key. |
402 Not enough credits | 402 quota_exceeded | Wait for your usage window to renew or add credits. |
423 Subscription is paused | 401 authentication_failed | The message says the subscription has expired. Renew it. |
422 invalid data | 422 params_invalid | Fix the parameter named in the message. |
404 company not found | 200 with an errors body, type not_found | Check the body for errors on /v1/companies/find. |
429 Too Many Attempts. | 429 rate_limit | Retry after the Retry-After delay; see Handle 429 responses. |
| No equivalent | 400 unknown_record | The email finder received a disposable or webmail domain. |
| No equivalent | 451 claimed_email | The owner of the address asked Tomba to stop processing it. Remove it from your data. |
Error responses don't consume credits. Every type is listed in Errors.
Bulk and async jobs
A Tomba lookup always returns its result in the response. With webhook_url it also posts a copy, but the request doesn't move to the background as it does on Findymail.
Findymail has no bulk endpoint. To process a list with Tomba, replace per-contact loops with a bulk job: finder for names and companies, linkedin for profile URLs, enrich for email addresses, search for domains, and verifier for verification. Email finder jobs take a CSV file:
Code
Tomba treats the first row of the file as a header. Launch the job, poll its progress, and download the results as shown in Lifecycle. Input formats per type are in Bulk types, and a job is charged when you first download its results; see Billing.
Code example
This function replaces a call to POST /api/search/name and returns Findymail's contact shape, or null when no address is found. It needs Node.js 18 or later.
Code
Cutover checklist
- Store the Tomba key and secret as
TOMBA_API_KEYandTOMBA_SECRET_KEY, and send them asX-Tomba-KeyandX-Tomba-Secretinstead of a bearer token. - Change each
POSTwith a JSON body into aGETwith query parameters, and send Findymail'sdomainvalue asdomainorcompany. - Read results from
datainstead ofcontact, treatdata.email: nullas no match, and filter ondata.verification.statusif you need verified addresses only. - Handle
402as before, retry429afterRetry-After, skip400 unknown_recorddomains, and remove addresses that return451. - Move large lists from per-contact loops to bulk jobs, and set
webhook_urlor poll/progressto know when they end. - Run the same sample of contacts through both services and compare the results before you switch production traffic.