Get Search Status
Poll a people search, track each phase, and use results as they become ready.
curl --request GET \
--url https://api.orbitsearch.com/v3/search/{search_id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.orbitsearch.com/v3/search/{search_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.orbitsearch.com/v3/search/{search_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"search_id": "<string>",
"request_id": "<string>",
"status": "running",
"candidate_discovery": true,
"profile_depth": "partial",
"include_profile": true,
"profile_upgrades_completed": true,
"results": [
{
"profile_id": "<string>",
"status": "generating",
"generation_level": 2,
"sources": [
"search"
],
"candidate_sources": [
{
"link": "<string>",
"title": "<string>",
"sourceImage": "<string>",
"face_match": {
"score": 0.5,
"confirmed": true,
"kept": true,
"thumbnail": "<string>"
}
}
],
"preview": {},
"profile": {
"id": "<unknown>",
"generationLevel": "<unknown>",
"avatarUrl": "<unknown>",
"verified": "<unknown>",
"sections": {
"socials": {
"items": [
{}
]
},
"bio": {
"bio": "<string>"
},
"basic": {
"items": [
{}
]
},
"personalLife": {
"items": [
{}
]
},
"jobs": {
"items": [
{}
]
},
"education": {
"items": [
{}
]
},
"passions": {
"items": [
{}
]
},
"worldview": {
"items": [
{}
]
},
"accomplishments": {
"items": [
{}
]
},
"controversies": {
"items": [
{}
]
},
"bestQualities": {
"items": [
{}
]
},
"netWorth": {
"items": [
{}
]
},
"eventsTimeline": {
"items": [
{}
]
},
"portfolio": {
"items": [
{}
]
},
"families": {
"items": [
{}
]
},
"researchPapers": {
"items": [
{}
]
},
"githubRepos": {
"items": [
{}
]
},
"mediaCredits": {
"items": [
{}
]
},
"musicCredits": {
"items": [
{}
]
},
"books": {
"items": [
{}
]
}
},
"displayName": "<unknown>",
"personName": "<unknown>",
"aliases": "<unknown>",
"profileUrl": "<unknown>",
"slug": "<unknown>",
"category": "<unknown>",
"location": "<unknown>",
"headline": "<unknown>",
"emails": "<unknown>",
"emailDetails": [
{
"email": "jsmith@example.com",
"type": "personal",
"typeBasis": "consumer_domain",
"verification": {
"status": "deliverable",
"verifiedAt": "2023-11-07T05:31:56Z",
"catchAllDomain": true
},
"employer": {
"association": "current",
"companyName": "<string>",
"companyDomain": "<string>"
}
}
],
"employmentDomains": [
{
"isCurrent": true,
"companyName": "<string>",
"domain": "<string>"
}
],
"phoneNumbers": "<unknown>",
"phoneDetails": [
{
"phoneNumber": "<string>",
"type": "mobile",
"isConnected": true,
"firstReported": 123,
"lastReported": 123
}
],
"addresses": "<unknown>"
},
"confidence": 0.5,
"confidence_level": "low",
"confidence_status": "provisional",
"match_summary": {
"matches": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"partial_matches": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"apparent_conflicts": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"unknown": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
]
},
"failure": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"reason": "<string>",
"suggested_inputs": [
"<string>"
]
}
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"links": {
"status": "<string>"
},
"candidate_discovery_completed": true,
"provider_results_final": true,
"confidence_kind": "identity",
"none_of_above_confidence": 0.5,
"discovered_sources": [
{
"link": "<string>",
"title": "<string>",
"sourceImage": "<string>",
"face_match": {
"score": 0.5,
"confirmed": true,
"kept": true,
"thumbnail": "<string>"
}
}
],
"candidate_discovery_failure": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"reason": "<string>",
"suggested_inputs": [
"<string>"
]
},
"population": {
"kind": "company",
"id": "<string>",
"name": "<string>",
"size": 123,
"profile_depth": "partial",
"credits_quoted": 123,
"status": "running"
},
"query_intent": {
"organizations": [
"<string>"
],
"schools": [
"<string>"
],
"person_named": true
},
"billing": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pricingVersion": "<string>",
"reservedCredits": 1,
"consumedCredits": 1,
"releasedCredits": 1,
"heldCredits": 1,
"status": "open"
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}"webhooks": true and Orbit delivers
each result’s whole profile as it is built. See
Push search results.curl "https://api.orbitsearch.com/v3/search/$SEARCH_ID" \
-H "Authorization: Bearer $ORBIT_API_KEY"
| Parameter | Location | Required | Description |
|---|---|---|---|
search_id | path | Yes | The search_id returned by POST /v3/search. |
sources containing search, candidate_discovery, or both. Known-search results retain their lightweight preview on every poll, regardless of include_profile. When include_profile is true, every poll also embeds the latest profile for each readable result, with its identity fields, contact fields, and generated sections. That includes a level 1 profile while its result is still enriching. For the image gallery and source links, call Read a profile.
Know When a Search Is Done
status answers one question: is the whole search done, and how did it go? Continue polling while it is running. Stop when it becomes:
completed: every result reached the requestedprofile_depth. A search can also complete with an emptyresultslist when nothing matched.completed_with_errors: ready results are available, but at least one result or candidate discovery failed.failed: work failed and the search has no ready results.
Track Each Phase
Two snapshot fields report the search’s phases independently:candidate_discovery_completedanswers: is the result list final? Whentrue, discovery adds no more results to this search. For discovery searches it becomestrueas soon as clustering fixes the candidate set and every discovered person appears inresults— usually while those results are stillgenerating. Present only when the search ran withcandidate_discovery: true. If discovery failed,candidate_discovery_failureexplains why.profile_upgrades_completedanswers: are the current profiles final? Whentrue, every result currently inresultsreached the requestedprofile_depthor failed. Whilecandidate_discovery_completedisfalse, discovery can still add results that bring new profile work.provider_results_finalanswers: is the owner set for the supplied contact final? When the request carried aphone,email, oraddresssignal, Orbit asks its people-data provider for every owner of that contact inside the first response and saves each owner with the provider’s contacts at Level 1. Whentrue, all of those owners are inresultsand their emails and phone numbers are readable through Read a profile while biographies are still building. Discovery by name can still add results untilcandidate_discovery_completedistrue. Present only when the search ran withcandidate_discovery: trueand a contact signal.
status alone — it is the only signal that the search is finished. Use these fields to show progress. For a discovery search, candidate_discovery_completed: true with profile_upgrades_completed: false is the normal mid-run state: all people are found and their profiles are still building, so you can render the final list of people while their profiles fill in.
Result Statuses
Each entry inresults moves through its own lifecycle, separate from the search status:
| Status | Meaning |
|---|---|
generating | Candidate discovery found this person and is building their first profile. No readable profile exists yet and generation_level is null. The result can already carry preview and candidate_sources. This status appears only on candidate discovery results, so searches without candidate_discovery: true never produce it. |
enriching | A profile exists and can be read at its current depth, but it is below the requested profile_depth. Orbit is building it up. |
ready | The profile reached the requested profile_depth. With include_profile: true, the result embeds its profile with identity fields, contact fields, and generated sections. |
failed | This result cannot reach the requested depth. failure contains a machine-readable reason. A failed result does not block other results. |
generating becomes enriching, enriching becomes ready or failed, and ready never regresses.
Result Stability
Snapshots are stable between polls:- A result never disappears from a later response. New candidate results append after the existing rows.
limitcaps only the initial matches from the existing Orbit index. Candidate Discovery results append outside that quota, and profile upgrades update rows in place. The finalresultscount can therefore exceedlimitand has no fixed multiple of it.
profile_id and update rows in place. You can render ready results while the rest of the search is still running.
async function waitForSearch(searchId) {
while (true) {
const response = await fetch(
`https://api.orbitsearch.com/v3/search/${searchId}`,
{ headers: { Authorization: `Bearer ${process.env.ORBIT_API_KEY}` } }
);
const search = await response.json();
if (search.status !== "running") return search;
await new Promise((resolve) => setTimeout(resolve, 1500));
}
}
{
"discovered_sources": [
{
"link": "https://example.org/ml-engineers",
"title": "Machine learning engineers",
"sourceImage": "https://example.org/favicon.ico"
}
],
"results": [
{
"profile_id": "profile_456",
"status": "enriching",
"generation_level": 1,
"sources": ["candidate_discovery"],
"candidate_sources": [
{
"link": "https://example.com/team",
"title": "Example team",
"sourceImage": "https://example.com/favicon.ico"
}
]
},
{
"profile_id": "profile_789",
"status": "generating",
"generation_level": null,
"sources": ["candidate_discovery"],
"preview": {
"id": "profile_789",
"displayName": "Example Candidate",
"city": "San Francisco"
}
}
]
}
discovered_sources starts filling within seconds of the search starting, while Orbit is still gathering, and grows as the search finds more pages. It lists every page the search has found, in the order the search first found each one, up to 200 pages. A page stays in the list through later polls and after the search ends. When Orbit assigns a page to a candidate, the receipt also appears in results[].candidate_sources and remains there when the result becomes ready. Every receipt contains link, title, and sourceImage. results[].sources is the existing result-origin list and does not contain source receipts.
In both receipt arrays, link is the URL of the discovered source page, title is the display title of the source page or site, and sourceImage is the URL of the favicon for the site that hosts the source page.
This endpoint requires search:read. If the original search used include_profile: true, the caller also needs profile:read. A search is only visible to the API key that created it.Authorizations
Use an Orbit API key from the Developer Dashboard.
Path Parameters
The search ID returned by POST /v3/search.
1Response
The current search snapshot.
Server-generated identifier for this search. Use it to poll the status endpoint.
The idempotency key from the original request, or a generated value when the request omitted it.
Overall search lifecycle. running means work is still in progress; poll until the status is terminal. completed means every result reached the requested profile depth; a search can complete with an empty results list when nothing matched. completed_with_errors means ready results are available but some work failed. failed means work failed and no ready results are available.
running, completed, completed_with_errors, failed Whether this search runs candidate discovery, as resolved from the request.
The minimum profile depth requested for each ready result.
partial, full Whether readable results embed their Search profile.
Whether every result in results has reached the requested profile_depth or failed. While candidate_discovery_completed is false, discovery can still add results with new profile work.
The people this search has found so far. Results are append-only: a reported result is never removed, and a ready result never regresses.
Show child attributes
Show child attributes
When the search was created.
When the snapshot last changed.
Show child attributes
Show child attributes
Whether the result list is final. Once true, discovery adds no more results to this search; the results themselves can still be generating or enriching toward the requested depth. For discovery searches this becomes true when clustering completes and every discovered person appears in results. If discovery failed, candidate_discovery_failure explains why. Present only when candidate_discovery is true.
Whether the people-data provider lookup for a supplied phone, email, or address returned its complete owner set. Once true, every owner of that contact is in results with the contacts the provider reported, usually within the first response and before biography work. Discovery by name can still add results until candidate_discovery_completed is true. Present only when candidate_discovery is true and the request carried a phone, email, or address signal.
identity when the search looks for one person, such as by name, contact, or face, and criteria when it looks for everyone who fits a description.
identity, criteria One minus the best result's confidence. It is high when no result matches well. Present on identity searches.
0 <= x <= 1Every page the search has found, in the order the search first found each one. The list starts filling within seconds and holds up to 200 pages. A page stays listed through later polls and after the search ends, including a page that is also in a result's candidate_sources. Present when candidate_discovery is true.
Show child attributes
Show child attributes
Why candidate discovery failed. Present only when discovery failed.
Show child attributes
Show child attributes
Present on population searches: the subject, the depth, the reserved credits and where the search is.
Show child attributes
Show child attributes
Present when the search parsed a plain-English query.
Show child attributes
Show child attributes
Credits held and spent for this search. The final consumedCredits is the full charge once status is settled.
Show child attributes
Show child attributes
curl --request GET \
--url https://api.orbitsearch.com/v3/search/{search_id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.orbitsearch.com/v3/search/{search_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.orbitsearch.com/v3/search/{search_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"search_id": "<string>",
"request_id": "<string>",
"status": "running",
"candidate_discovery": true,
"profile_depth": "partial",
"include_profile": true,
"profile_upgrades_completed": true,
"results": [
{
"profile_id": "<string>",
"status": "generating",
"generation_level": 2,
"sources": [
"search"
],
"candidate_sources": [
{
"link": "<string>",
"title": "<string>",
"sourceImage": "<string>",
"face_match": {
"score": 0.5,
"confirmed": true,
"kept": true,
"thumbnail": "<string>"
}
}
],
"preview": {},
"profile": {
"id": "<unknown>",
"generationLevel": "<unknown>",
"avatarUrl": "<unknown>",
"verified": "<unknown>",
"sections": {
"socials": {
"items": [
{}
]
},
"bio": {
"bio": "<string>"
},
"basic": {
"items": [
{}
]
},
"personalLife": {
"items": [
{}
]
},
"jobs": {
"items": [
{}
]
},
"education": {
"items": [
{}
]
},
"passions": {
"items": [
{}
]
},
"worldview": {
"items": [
{}
]
},
"accomplishments": {
"items": [
{}
]
},
"controversies": {
"items": [
{}
]
},
"bestQualities": {
"items": [
{}
]
},
"netWorth": {
"items": [
{}
]
},
"eventsTimeline": {
"items": [
{}
]
},
"portfolio": {
"items": [
{}
]
},
"families": {
"items": [
{}
]
},
"researchPapers": {
"items": [
{}
]
},
"githubRepos": {
"items": [
{}
]
},
"mediaCredits": {
"items": [
{}
]
},
"musicCredits": {
"items": [
{}
]
},
"books": {
"items": [
{}
]
}
},
"displayName": "<unknown>",
"personName": "<unknown>",
"aliases": "<unknown>",
"profileUrl": "<unknown>",
"slug": "<unknown>",
"category": "<unknown>",
"location": "<unknown>",
"headline": "<unknown>",
"emails": "<unknown>",
"emailDetails": [
{
"email": "jsmith@example.com",
"type": "personal",
"typeBasis": "consumer_domain",
"verification": {
"status": "deliverable",
"verifiedAt": "2023-11-07T05:31:56Z",
"catchAllDomain": true
},
"employer": {
"association": "current",
"companyName": "<string>",
"companyDomain": "<string>"
}
}
],
"employmentDomains": [
{
"isCurrent": true,
"companyName": "<string>",
"domain": "<string>"
}
],
"phoneNumbers": "<unknown>",
"phoneDetails": [
{
"phoneNumber": "<string>",
"type": "mobile",
"isConnected": true,
"firstReported": 123,
"lastReported": 123
}
],
"addresses": "<unknown>"
},
"confidence": 0.5,
"confidence_level": "low",
"confidence_status": "provisional",
"match_summary": {
"matches": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"partial_matches": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"apparent_conflicts": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
],
"unknown": [
{
"field": "<string>",
"query": "<string>",
"candidate": "<string>",
"outcome": "exact",
"evidence_level": "weak"
}
]
},
"failure": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"reason": "<string>",
"suggested_inputs": [
"<string>"
]
}
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"links": {
"status": "<string>"
},
"candidate_discovery_completed": true,
"provider_results_final": true,
"confidence_kind": "identity",
"none_of_above_confidence": 0.5,
"discovered_sources": [
{
"link": "<string>",
"title": "<string>",
"sourceImage": "<string>",
"face_match": {
"score": 0.5,
"confirmed": true,
"kept": true,
"thumbnail": "<string>"
}
}
],
"candidate_discovery_failure": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"reason": "<string>",
"suggested_inputs": [
"<string>"
]
},
"population": {
"kind": "company",
"id": "<string>",
"name": "<string>",
"size": 123,
"profile_depth": "partial",
"credits_quoted": 123,
"status": "running"
},
"query_intent": {
"organizations": [
"<string>"
],
"schools": [
"<string>"
],
"person_named": true
},
"billing": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pricingVersion": "<string>",
"reservedCredits": 1,
"consumedCredits": 1,
"releasedCredits": 1,
"heldCredits": 1,
"status": "open"
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}{
"status": "failed",
"error": {
"code": "<string>",
"message": "<string>",
"requiredCredits": 1,
"remainingCredits": 1
}
}