The Seamless API follows a three-step flow: search for the record you want, submit it for research, and retrieve the enriched result. Authentication is handled by passing your API key in a Token request header. This guide walks through each step using companies and contacts as parallel examples, with code samples in curl, Python, and Node.js.
Prerequisites
Before you begin:
Store your API key in an environment variable. The examples below reference it as $SEAMLESS_API_KEY.
Search for a company or contact
Search returns a list of matching records. Each result includes a searchResultId you’ll use in the next step. curl -X POST https://api.seamless.ai/api/client/v1/search/companies \
-H "Content-Type: application/json" \
-H "Token: $SEAMLESS_API_KEY " \
-d '{
"companyName": ["Acme Corp"],
"limit": 5
}'
import os
import requests
response = requests.post(
"https://api.seamless.ai/api/client/v1/search/companies" ,
headers = {
"Content-Type" : "application/json" ,
"Token" : os.environ[ "SEAMLESS_API_KEY" ],
},
json = {
"companyName" : [ "Acme Corp" ],
"limit" : 5 ,
},
)
print (response.json())
const response = await fetch (
"https://api.seamless.ai/api/client/v1/search/companies" ,
{
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
Token: process . env . SEAMLESS_API_KEY ,
},
body: JSON . stringify ({
companyName: [ "Acme Corp" ],
limit: 5 ,
}),
}
);
const data = await response . json ();
console . log ( data );
Example response: {
"data" : [
{
"searchResultId" : "YOUR_SEARCH_RESULT_ID" ,
"name" : "Acme Corp" ,
"domain" : "acmecorp.com" ,
"industries" : [ "Information Technology and Services" ],
"staffCountRange" : "51 - 200" ,
"revenueRange" : "$20M - $50M"
}
],
"supplementalData" : {
"isMore" : true ,
"total" : 12 ,
"perPage" : 5 ,
"nextToken" : "eyJwYWdlIjoyLCJzZWFyY2hJZCI6ImFiYzEyMyJ9"
}
}
Save the searchResultId from the record you want to enrich. You’ll pass it to the research endpoint in step 2. curl -X POST https://api.seamless.ai/api/client/v1/search/contacts \
-H "Content-Type: application/json" \
-H "Token: $SEAMLESS_API_KEY " \
-d '{
"jobTitle": ["Chief Technology Officer"],
"companyName": ["Acme Corp"],
"limit": 5
}'
import os
import requests
response = requests.post(
"https://api.seamless.ai/api/client/v1/search/contacts" ,
headers = {
"Content-Type" : "application/json" ,
"Token" : os.environ[ "SEAMLESS_API_KEY" ],
},
json = {
"jobTitle" : [ "Chief Technology Officer" ],
"companyName" : [ "Acme Corp" ],
"limit" : 5 ,
},
)
print (response.json())
const response = await fetch (
"https://api.seamless.ai/api/client/v1/search/contacts" ,
{
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
Token: process . env . SEAMLESS_API_KEY ,
},
body: JSON . stringify ({
jobTitle: [ "Chief Technology Officer" ],
companyName: [ "Acme Corp" ],
limit: 5 ,
}),
}
);
const data = await response . json ();
console . log ( data );
The response structure mirrors the company search. Save the searchResultId for the contact you want to enrich.
Submit a research request
Pass one or more searchResultIds to the research endpoint. The API returns a requestId for each submitted record — you’ll use this to retrieve results in step 3. curl -X POST https://api.seamless.ai/api/client/v1/companies/research \
-H "Content-Type: application/json" \
-H "Token: $SEAMLESS_API_KEY " \
-d '{
"searchResultIds": ["YOUR_SEARCH_RESULT_ID"]
}'
import os
import requests
response = requests.post(
"https://api.seamless.ai/api/client/v1/companies/research" ,
headers = {
"Content-Type" : "application/json" ,
"Token" : os.environ[ "SEAMLESS_API_KEY" ],
},
json = {
"searchResultIds" : [ "YOUR_SEARCH_RESULT_ID" ],
},
)
print (response.json())
const response = await fetch (
"https://api.seamless.ai/api/client/v1/companies/research" ,
{
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
Token: process . env . SEAMLESS_API_KEY ,
},
body: JSON . stringify ({
searchResultIds: [ "YOUR_SEARCH_RESULT_ID" ],
}),
}
);
const data = await response . json ();
console . log ( data );
curl -X POST https://api.seamless.ai/api/client/v1/contacts/research \
-H "Content-Type: application/json" \
-H "Token: $SEAMLESS_API_KEY " \
-d '{
"searchResultIds": ["YOUR_SEARCH_RESULT_ID"]
}'
import os
import requests
response = requests.post(
"https://api.seamless.ai/api/client/v1/contacts/research" ,
headers = {
"Content-Type" : "application/json" ,
"Token" : os.environ[ "SEAMLESS_API_KEY" ],
},
json = {
"searchResultIds" : [ "YOUR_SEARCH_RESULT_ID" ],
},
)
print (response.json())
const response = await fetch (
"https://api.seamless.ai/api/client/v1/contacts/research" ,
{
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
Token: process . env . SEAMLESS_API_KEY ,
},
body: JSON . stringify ({
searchResultIds: [ "YOUR_SEARCH_RESULT_ID" ],
}),
}
);
const data = await response . json ();
console . log ( data );
Both endpoints return HTTP 202 Accepted with the same JSON body: {
"success" : true ,
"requestIds" : [ "YOUR_REQUEST_ID" ]
}
You can submit multiple searchResultIds in a single request. Each one gets its own requestId in the response array.
Retrieve results by polling
Call the poll endpoint with your requestId to check research status. Research runs asynchronously, so poll every few seconds until the status is done. curl -X GET "https://api.seamless.ai/api/client/v1/companies/research/poll?requestIds=YOUR_REQUEST_ID" \
-H "Token: $SEAMLESS_API_KEY "
import os
import requests
response = requests.get(
"https://api.seamless.ai/api/client/v1/companies/research/poll" ,
headers = { "Token" : os.environ[ "SEAMLESS_API_KEY" ]},
params = { "requestIds" : "YOUR_REQUEST_ID" },
)
print (response.json())
const params = new URLSearchParams ({ requestIds: "YOUR_REQUEST_ID" });
const response = await fetch (
`https://api.seamless.ai/api/client/v1/companies/research/poll? ${ params } ` ,
{
headers: {
Token: process . env . SEAMLESS_API_KEY ,
},
}
);
const data = await response . json ();
console . log ( data );
curl -X GET "https://api.seamless.ai/api/client/v1/contacts/research/poll?requestIds=YOUR_REQUEST_ID" \
-H "Token: $SEAMLESS_API_KEY "
import os
import requests
response = requests.get(
"https://api.seamless.ai/api/client/v1/contacts/research/poll" ,
headers = { "Token" : os.environ[ "SEAMLESS_API_KEY" ]},
params = { "requestIds" : "YOUR_REQUEST_ID" },
)
print (response.json())
const params = new URLSearchParams ({ requestIds: "YOUR_REQUEST_ID" });
const response = await fetch (
`https://api.seamless.ai/api/client/v1/contacts/research/poll? ${ params } ` ,
{
headers: {
Token: process . env . SEAMLESS_API_KEY ,
},
}
);
const data = await response . json ();
console . log ( data );
When research is still running, the response looks like this: {
"success" : true ,
"data" : [
{
"requestId" : "YOUR_REQUEST_ID" ,
"status" : "researching" ,
"message" : "" ,
"additionalData" : {}
}
]
}
When research is complete, the status changes to done and the full record appears in the response: {
"success" : true ,
"data" : [
{
"requestId" : "YOUR_REQUEST_ID" ,
"status" : "done" ,
"message" : "" ,
"company" : {
"apiResearchId" : "YOUR_REQUEST_ID" ,
"name" : "Acme Corp" ,
"domain" : "acmecorp.com" ,
"description" : "Acme Corp is a leading provider of innovative business solutions." ,
"foundedOn" : "2015-01-01" ,
"industries" : "Information Technology and Services,Computer Software" ,
"annualRevenue" : "35000000" ,
"revenueRange" : "$20M - $50M" ,
"staffCount" : "125" ,
"staffCountRange" : "51 - 200" ,
"phones" : "+1-555-555-0100" ,
"phonesAiScores" : "98" ,
"linkedInProfileUrl" : "https://www.linkedin.com/company/acme-corp/" ,
"linkedInId" : "9876543" ,
"topTechnologies" : "Salesforce,HubSpot,Marketo" ,
"sicCode" : "7372" ,
"location" : {
"street1" : "100 Main St" ,
"city" : "San Francisco" ,
"state" : "CA" ,
"postCode" : "94105" ,
"country" : "United States" ,
"countryAbbr" : "US" ,
"countryAlpha2" : "US" ,
"countryAlpha3" : "USA" ,
"fullString" : "100 Main St, San Francisco, CA 94105, United States"
},
"createdAt" : "2026-01-15T10:30:00.000Z" ,
"updatedAt" : "2026-01-15T10:30:00.000Z"
},
"additionalData" : {}
}
]
}
Poll status values Status Applies to Meaning researchingBoth Still processing. Poll again in a few seconds. doneBoth Research complete. Full record is available. missingBoth No result found for the record. errorBoth Could not process. Check credits and license. duplicateContacts only Already researched. Existing result returned.
If status is error, verify that your account has sufficient research credits and that your API key has the required license permissions before retrying.
For HTTP errors such as 401, 422, or 429, see API HTTP status codes .
What’s next
Choose a workflow Compare search, research, webhooks, polling, and org data endpoints to find the right path for your use case.
Receive results with webhooks Skip polling entirely — configure a webhook endpoint and let Seamless push completed results to you.
End-to-end company workflow A complete walkthrough of the company search, research, and retrieval flow.
End-to-end contact workflow A complete walkthrough of the contact search, research, and retrieval flow.