// post /v1/bulk/author
Bulk Author Finder API
Turn thousands of article URLs into verified author contact records with one asynchronous bulk request.
Article URLsUp to 5,000 rows
curl -X POST "https://api.tomba.io/v1/bulk/author" \
-H "X-Tomba-Key: $TOMBA_API_KEY" \
-H "X-Tomba-Secret: $TOMBA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Author Finder job","list":"https://piedpiper.com/blog/middle-out-compression","launch":true,"webhook_url":"https://hooks.example.com/tomba"}'const res = await fetch("https://api.tomba.io/v1/bulk/author", {
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": "Author Finder job",
"list": "https://piedpiper.com/blog/middle-out-compression",
"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/author",
headers={
"X-Tomba-Key": os.environ["TOMBA_API_KEY"],
"X-Tomba-Secret": os.environ["TOMBA_SECRET_KEY"],
},
json={
"name": "Author Finder job",
"list": "https://piedpiper.com/blog/middle-out-compression",
"launch": True,
"webhook_url": "https://hooks.example.com/tomba"
},
)
job_id = res.json()["data"]["id"]// 01 · request
Bulk Author 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
- author
- list | data | file
- Article URLs
- launch
- true starts the job at once
- webhook_url
- Receives a signed event when the job ends
- rows
- Up to 5,000 per job
curl -X POST "https://api.tomba.io/v1/bulk/author" \
-H "X-Tomba-Key: $TOMBA_API_KEY" \
-H "X-Tomba-Secret: $TOMBA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Author Finder job","list":"https://piedpiper.com/blog/middle-out-compression","launch":true,"webhook_url":"https://hooks.example.com/tomba"}'const res = await fetch("https://api.tomba.io/v1/bulk/author", {
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": "Author Finder job",
"list": "https://piedpiper.com/blog/middle-out-compression",
"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/author",
headers={
"X-Tomba-Key": os.environ["TOMBA_API_KEY"],
"X-Tomba-Secret": os.environ["TOMBA_SECRET_KEY"],
},
json={
"name": "Author Finder job",
"list": "https://piedpiper.com/blog/middle-out-compression",
"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
/author-finderFielddata.emailstring | null- The address, or null when none is found
data.scoreinteger- Confidence from 0 to 100
data.verification.statusstring | null- valid, accept_all, invalid or unknown, with verification.date
data.full_name, data.position, data.departmentstring | null- Name, job title and team
data.typestring | null- personal or generic (a role address such as sales@)
data.linkedin, data.twitterstring | null- Public profiles
data.sources[]array | null- Up to 20 public pages where the address was found, with dates
data.info.title, data.info.publisher_name, data.info.publish_datestring- The article, who published it and when
data.info.candidates[]array | null- Every author candidate on the page, with a name confidence and score
POST /bulk/author
201 Created
{
"data": {
"id": 1042
}
}Each row, as GET /author-finder returns it
200 OK
{
"data": {
"email": "richard@piedpiper.com",
"first_name": "Richard",
"last_name": "Hendricks",
"full_name": "Richard Hendricks",
"website_url": "piedpiper.com",
"company": "Pied Piper",
"pattern": "{first}",
"department": "executive",
"type": "personal",
"position": "CEO",
"country": "US",
"gender": "male",
"twitter": null,
"linkedin": "https://www.linkedin.com/in/richard-hendricks",
"score": 100,
"accept_all": false,
"phone_number": true,
"verification": {
"date": "2025-01-15T10:32:00+01:00",
"status": "valid"
},
"sources": [
{
"uri": "https://piedpiper.com/blog/engineering",
"website_url": "piedpiper.com",
"extracted_on": "2024-06-01T09:14:07+01:00",
"last_seen_on": "2025-01-10T17:02:44+01:00",
"still_on_page": true
}
],
"info": {
"url": "https://piedpiper.com/blog/middle-out-compression",
"title": "Middle-out compression, explained",
"og_image": "https://piedpiper.com/blog/middle-out-compression/cover.png",
"description": "How middle-out compression reached a Weissman score of 5.2.",
"article_domain": "piedpiper.com",
"publisher_name": "Pied Piper",
"publish_date": "2025-03-04",
"candidates": [
{
"full_name": "Richard Hendricks",
"first_name": "Richard",
"last_name": "Hendricks",
"job_title": "CEO",
"linkedin": "https://www.linkedin.com/in/richard-hendricks",
"name_confidence": 0.98,
"score": 0.95,
"count": 3
}
]
}
}
}// 03 · cost and limits
What a call costs
A call is charged only under the condition below. Rate limits depend on your plan.
// cost
1 search credit per article with an author address.
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 article URLs, then launch the operation. The API extracts author information and finds their email addresses asynchronously for all URLs.
You can process up to 10,000 article URLs per bulk operation. For larger datasets, create multiple bulk operations.
The API works with blog posts, news articles, and content pages from most CMS platforms including WordPress, Medium, Ghost, and custom publishing systems.
Each result includes the author's email address, full name, company, position, LinkedIn profile, confidence score, and sources where the information was found.
Processing time depends on the number of URLs. Typical processing is 2-3 seconds per URL. A batch of 5,000 URLs typically completes within several hours.
Each URL that returns an author email counts as 1 request. URLs where no author email is found are not counted against your quota.
Yes, configure a webhook URL to receive a notification when your bulk author finder operation completes with results ready for download.
The API returns the primary author's email address. For articles with multiple authors, consider using individual Author Finder API calls.
Yes. Teams use Bulk Author Finder to build media and contributor lists at scale, then route high-confidence contacts into outreach sequences.
Provide clean canonical article URLs, avoid homepage/category pages, and remove URL duplicates before submission to maximize extraction quality.