// post /v1/bulk/phone-finder
Bulk Phone Finder API
Resolve large contact datasets into usable phone numbers with line type and carrier metadata in one async job.
Email addresses, LinkedIn URLs or domainsUp to 10,000 rows
curl -X POST "https://api.tomba.io/v1/bulk/phone-finder" \
-H "X-Tomba-Key: $TOMBA_API_KEY" \
-H "X-Tomba-Secret: $TOMBA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Phone Finder job","list":"richard@piedpiper.com","launch":true,"webhook_url":"https://hooks.example.com/tomba"}'const res = await fetch("https://api.tomba.io/v1/bulk/phone-finder", {
method: "POST",
headers: {
"X-Tomba-Key": process.env.TOMBA_API_KEY,
"X-Tomba-Secret": process.env.TOMBA_SECRET_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": "Phone Finder job",
"list": "richard@piedpiper.com",
"launch": true,
"webhook_url": "https://hooks.example.com/tomba"
})
});
const { data } = await res.json(); // { id }import os, requests
res = requests.post(
"https://api.tomba.io/v1/bulk/phone-finder",
headers={
"X-Tomba-Key": os.environ["TOMBA_API_KEY"],
"X-Tomba-Secret": os.environ["TOMBA_SECRET_KEY"],
},
json={
"name": "Phone Finder job",
"list": "richard@piedpiper.com",
"launch": True,
"webhook_url": "https://hooks.example.com/tomba"
},
)
job_id = res.json()["data"]["id"]// 01 · request
Bulk Phone Finder is one HTTPS request
Send the parameters with your key and secret. Every SDK, the CLI and the MCP server make this same call.
- type
- phone-finder
- list | data | file
- Email addresses, LinkedIn URLs or domains
- launch
- true starts the job at once
- webhook_url
- Receives a signed event when the job ends
- rows
- Up to 10,000 per job
curl -X POST "https://api.tomba.io/v1/bulk/phone-finder" \
-H "X-Tomba-Key: $TOMBA_API_KEY" \
-H "X-Tomba-Secret: $TOMBA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Phone Finder job","list":"richard@piedpiper.com","launch":true,"webhook_url":"https://hooks.example.com/tomba"}'const res = await fetch("https://api.tomba.io/v1/bulk/phone-finder", {
method: "POST",
headers: {
"X-Tomba-Key": process.env.TOMBA_API_KEY,
"X-Tomba-Secret": process.env.TOMBA_SECRET_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": "Phone Finder job",
"list": "richard@piedpiper.com",
"launch": true,
"webhook_url": "https://hooks.example.com/tomba"
})
});
const { data } = await res.json(); // { id }import os, requests
res = requests.post(
"https://api.tomba.io/v1/bulk/phone-finder",
headers={
"X-Tomba-Key": os.environ["TOMBA_API_KEY"],
"X-Tomba-Secret": os.environ["TOMBA_SECRET_KEY"],
},
json={
"name": "Phone Finder job",
"list": "richard@piedpiper.com",
"launch": True,
"webhook_url": "https://hooks.example.com/tomba"
},
)
job_id = res.json()["data"]["id"]// 02 · response
What comes back
JSON, the same in every language. Fields Tomba doesn't know are null, never guessed.
GET
/phone-finderdataobject | array- The number; an array with full=true, and an empty array when none is found
data.validboolean | null- Whether the number is a valid phone number
data.intl_format, data.e164_format, data.local_formatstring | null- The number in international, E.164 and national formats
data.country_codestring | null- Country of the number (ISO code)
data.line_typestring | null- MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, VOIP, TOLL_FREE…
data.carrierstring | null- The network operator
data.region, data.timezonesobject | null, array | null- Where the number is registered, and its time zones
POST /bulk/phone-finder
201 Created
{
"data": {
"id": 1042
}
}Each row, as GET /phone-finder returns it
200 OK
{
"email": "richard@piedpiper.com",
"data": {
"email": "richard@piedpiper.com",
"valid": true,
"local_format": "(650) 555-0132",
"intl_format": "+1 650-555-0132",
"e164_format": "+16505550132",
"rfc3966_format": "tel:+1-650-555-0132",
"country_code": "US",
"line_type": "MOBILE",
"carrier": "AT&T",
"region": {
"name": "California",
"code": "CA"
},
"timezones": [
"America/Los_Angeles"
]
}
}// 03 · cost and limits
What a call costs
A call is charged only under the condition below. Rate limits depend on your plan.
// cost
5 search credits per row with at least one phone number.
Charged once, at the first download; later downloads are free
- Jobs created: 15 per day for each type
- Running jobs: 2 per type
- Downloads: 25 per day for each job
- Request size: 4 MB (CSV, list or rows)
Create a bulk operation by uploading emails, domains, or LinkedIn URLs, then launch the operation. The API finds phone numbers for each contact asynchronously.
You can process up to 10,000 lookups per bulk operation. For larger datasets, create multiple bulk operations.
You can find phone numbers using email addresses, company domains, or LinkedIn profile URLs. Provide one type per lookup.
Each result includes the phone number in multiple formats (local, international, E164), country code, line type (mobile, landline, VoIP), carrier information, and timezone.
Processing time depends on the list size and the lookups it needs. Poll the job or set a webhook to hear when it finishes.
Each lookup that returns a phone number counts as 1 request. Lookups with no phone found are not counted against your quota.
Yes, configure a webhook URL to receive a notification when your bulk phone finder operation completes with results ready for download.
The Phone Finder API provides phone data for 100+ countries worldwide with proper international formatting.
Yes. After a bulk phone finder run, send results to Bulk Phone Validator to classify validity, line type, and deliverability confidence.
Remove duplicates, normalize domains, and ensure profile/email values are valid and complete. Clean inputs improve match rates and reduce wasted requests.