Leads Database
Search a global B2B database of people and companies, enrich profiles, and feed the results into your lists and campaigns.
The Leads Database is a prospecting search over a global B2B database of people and companies. It runs entirely on the Swarmhit side: you do not need a connected LinkedIn account to use it, and no LinkedIn action limits apply. Use it to build lead lists from scratch, then hand the results to a campaign for outreach.
Two things shape how you should use it:
Every search result returned and every enrichment consumes workspace credits. Keep pages small and filters tight. Results are transient: nothing you find is stored in your workspace until you add the person to a list or campaign.
Endpoints
Search people
POST /database/people/search
Search companies
POST /database/companies/search
Enrich a person
POST /database/people/enrich
Enrich a company
POST /database/companies/enrich
List valid filter values
POST /database/suggestions (free)
Searching people
searchPeopleDatabase takes a filters object, an optional limit (1 to 100, default 25), and an optional cursor. At least one filter is required, and unknown filter keys are rejected with a 400. Array filters match any of their values; text filters are fuzzy.
curl -X POST https://app.swarmhit.com/api/v1/database/people/search \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{
"filters": {
"titles": ["CTO", "VP Engineering"],
"countries": ["United States"],
"headcountRanges": ["51-200", "201-500"]
},
"limit": 25
}'People filters
| Filter | Type | Matches |
|---|---|---|
titles / excludeTitles / pastTitles | string[] | Current job titles (fuzzy), title words to exclude, past titles (fuzzy) |
seniorities, departments, functions | string[] | Seniority levels, departments, job functions (use suggestions for valid values) |
keywords | string or string[] | Headline keywords (fuzzy, ANY of the array) |
keywordInProfile | string or string[] | Profile summary/bio keywords (fuzzy, ANY of the array) |
minTenure / maxTenure | number | Years in the current role |
minYearsExperience / maxYearsExperience | number | Total years of experience |
recentlyChangedJobs | boolean | Only people who recently started a new role |
companyNames / pastCompanyNames | string[] | Current or past employer names (fuzzy) |
companyDomains | string[] | Current company website domains |
industries, companyTypes, companyHqCountries | string[] | Current company industry, type, HQ country |
headcountRanges | string[] | Current company size ranges, e.g. "51-200" |
locations, states, countries, continents | string[] | Person location: free-text (fuzzy), states/regions (fuzzy), full country names like "United States", continents |
fullName | string | Person full name (fuzzy) |
languages, skills, schools, degrees, fieldsOfStudy | string[] | Profile attributes (degrees and fields of study are fuzzy) |
hasVerifiedEmail | boolean | Only people with a verified business email at their current company |
excludeExisting | boolean | Hide people already saved as workspace leads |
Each result is a person record with a stable database id, name, headline, title, location, picture, current company (with domain, headcount, industries), pastCompanies, education, yearsOfExperience, and three fields worth special attention:
linkedinUrl: use this to add the person to a list or campaign.contact: availability flags only (hasBusinessEmail,hasPersonalEmail,hasPhone). The actual email comes from enrichment.saved: true when the person is already saved as a workspace lead.
Searching companies
searchCompaniesDatabase works the same way (at least one filter, limit 1 to 100, cursor paging) and additionally accepts a sort with key (headcount, funding, founded, followers, lastRound) and dir (asc, desc).
curl -X POST https://app.swarmhit.com/api/v1/database/companies/search \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{
"filters": {
"industries": ["Software Development"],
"countries": ["USA"],
"minHeadcount": 50
},
"sort": { "key": "headcount", "dir": "desc" },
"limit": 25
}'Company filters
| Filter | Type | Matches |
|---|---|---|
names | string[] | Company names (fuzzy) |
domains | string[] | Website domains |
industries | string[] | Industries (use suggestions for valid values) |
countries | string[] | ISO 3-letter HQ country codes, e.g. "USA" |
headcountRanges, minHeadcount, maxHeadcount | string[] / number | Company size |
minGrowth12m | number | Minimum 12-month headcount growth, percent |
foundedAfter / foundedBefore | number | Founding year |
minFundingUsd, lastRoundTypes, investors | number / string[] | Funding raised, last round type, investors |
technologies | string[] | Technologies in use |
Note the country formats differ: people search takes full country names ("United States"), company search takes ISO 3-letter codes ("USA").
Finding valid filter values
Several filters only accept known values (industries, seniorities, headcount ranges, and so on). databaseSuggestions autocompletes them, and it is free: it consumes no credits.
curl -X POST https://app.swarmhit.com/api/v1/database/suggestions \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{ "entity": "companies", "field": "industry", "query": "software" }'Pass entity (people or companies) and a field. Omit query to get the most common values. Supported fields:
- People:
title,seniority,company,country,city,skill,school,headcountRange - Companies:
industry,country,headcountRange,lastRoundType,investor,technology,name
Paging
Search responses carry a paging object with nextCursor (null when the result set is exhausted) and totalCount (when the database reports it). To get the next page, send the same request again with cursor set to the returned nextCursor. Filters must stay identical between pages.
curl -X POST https://app.swarmhit.com/api/v1/database/people/search \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{
"filters": { "titles": ["CTO"], "countries": ["United States"] },
"limit": 25,
"cursor": "eyJwYWdlIjoyfQ"
}'Since credits are charged per result returned, do not page further than you need. Fetching 4 pages of 25 costs the same as one page of 100, so there is no discount for large pages either: the lever is total results, and tighter filters are how you reduce it.
Enrichment
Search results are summaries. Enrichment fetches the full record for one person or company.
People
enrichPersonDatabase takes a linkedinUrl (required) and an includeEmail flag (default false). It returns everything a search result has plus summary, connections, followers, skills, and websites. With includeEmail: true it also returns businessEmails, a list of verified business emails; this costs more credits. Without includeEmail the response omits the contact availability flags.
curl -X POST https://app.swarmhit.com/api/v1/database/people/enrich \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{
"linkedinUrl": "https://www.linkedin.com/in/jane-doe",
"includeEmail": true
}'To avoid paying for enrichments that return no email, filter your search with hasVerifiedEmail: true, or check the contact.hasBusinessEmail flag on the search result first.
Companies
enrichCompanyDatabase resolves a company from its website domain (preferred), linkedinUrl, or name, and returns the full record: headcount and headcountGrowth12m, funding (total, last round amount/type/date, investors), estimatedRevenue range, followers, and openings (open job listings).
curl -X POST https://app.swarmhit.com/api/v1/database/companies/enrich \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{ "domain": "stripe.com" }'Both enrich endpoints return 404 when nothing matches.
Keeping results: lists and campaigns
Database results are transient. Swarmhit does not store them, and re-running a search bills again. As soon as a person is worth keeping, save them using the linkedinUrl from the result as the lead's profileUrl:
- Add them to a list with
addListLeads, then enroll the list later. - Or enroll them directly with
addLeadsToCampaign.
Both upsert the workspace lead and attach it in one call. See Leads and lists for how leads work.
curl -X POST https://app.swarmhit.com/api/v1/lists/LIST_ID/leads \
-H "Authorization: Bearer swh_live_..." \
-H "Content-Type: application/json" \
-d '{
"leads": [
{ "profileUrl": "https://www.linkedin.com/in/jane-doe", "firstName": "Jane", "lastName": "Doe", "company": "Acme" }
]
}'Two fields help you avoid duplicating work: set excludeExisting: true in your people search to hide anyone already saved as a workspace lead, and check the saved flag on each result before adding.
Credits and errors
Credit consumption in one place:
| Call | Credits |
|---|---|
| People or company search | Charged per result returned |
| Person enrichment | Charged per call, more with includeEmail |
| Company enrichment | Charged per call |
| Suggestions | Free |
Database endpoints can also return two retryable errors specific to the database:
429withcode: rate_limited: the database is busy right now. Retry after a short delay.503withcode: unavailable: the database is temporarily unavailable. Retry later.
A 400 means your filters are invalid (an unknown filter key, or no filter at all). See Authentication for the error envelope format.
Inbox
List LinkedIn conversations, read message history, reply with text, attachments or voice notes, and react to replies programmatically.
Direct actions
Send connection requests, messages, InMails and other one-off LinkedIn actions from a sender account, outside campaigns, with idempotent retries and an approvals queue.