GET/v1/persons/search
Natural-language person search
Searches people by a natural-language ICP query. The API interprets the query into constrained role, all-employee company, code, keyword, geo, and employee-count filters before running parameterized ClickHouse SQL.
| Parameter | Required | Description |
|---|
q | Yes | Natural-language search, for example CMOs of SaaS companies with 50+ employees, CEOs in Las Vegas, all employees at SaaS companies with fewer than 50 employees, or give me 1000 decision makers for marketing agencies. A leading requested count is treated as max_records when max_records is not supplied. |
location_city | No | Optional server-side company city filter, for example Las Vegas. Known cities can infer state, but location_state is recommended. |
location_state | No | Optional server-side company state filter. Accepts a two-letter state code such as NV or a full state name such as Nevada. |
limit | No | Page size. Defaults to 100 and is capped at 100. |
max_records | No | Total cap across all pages, for example 2000. This controls total delivery; limit controls only the current page size. Flexible searches may omit uncapped total_matching_records because they do not run exact live counts. |
cursor | No | Opaque cursor from the previous response. |
dedupe_token | No | Optional campaign or workflow token that prevents repeat delivery for the same interpreted criteria and token. |
dedupe_user_id | No | Optional integration end-user ID for customers using a single API key across multiple users. When omitted, dedupe stays scoped to the API key's account. |
Response fields
| Field | Type | Description |
|---|
interpretation | object | The validated interpretation used to run the search, including role, industry, filters, and warnings. |
pagination | object | Page metadata. Includes limit, total_records, total_pages, next_cursor, and cap metadata when max_records is used. Flexible searches include total_records_relation when total_records is a lower bound. |
data | array<Person> | Returned person records for the current page. Optional fields are omitted when unavailable. |
data[].company | object | Company and firmographic context for each returned person. |
billable_records | integer | Number of returned records billed for this response. |
Example response
{
"interpretation": {
"roles": [{ "key": "dynamic_role", "label": "CMO" }],
"industries": [{ "key": "dynamic_industry", "label": "SaaS companies" }],
"filters": {
"company_city": "Las Vegas",
"company_state": "NV",
"employee_count_min": 50,
"employee_count_max": null
},
"warnings": []
},
"pagination": {
"limit": 100,
"total_records": 101,
"total_records_relation": "gte",
"total_pages": 2,
"next_cursor": "opaque-cursor-or-null",
"max_records": 2000
},
"data": [
{
"person_id": "person_123",
"first_name": "Jordan",
"last_name": "Lee",
"job_title": "Chief Marketing Officer",
"business_email": "jordan@example.com",
"linkedin_url": "https://www.linkedin.com/in/jordan-lee",
"company": {
"company_id": "company_123",
"name": "Example SaaS Co",
"domain": "example.com",
"employee_count": 82,
"industry": "Software",
"city": "Boise",
"state": "ID"
}
}
],
"billable_records": 1
}
POST/v1/persons/search/jobs
Create async person search job
Queues an interpreted person search for worker execution. Job creation validates auth, rate limit, max_records, dedupe_token, native geo filters, and the search interpretation, but does not bill or record delivered rows until a worker succeeds. Each job returns one page; submit another job with next_cursor when more pages are available.
| Parameter | Required | Description |
|---|
q | Yes | Natural-language person search. Same semantics as GET /v1/persons/search. |
location_city | No | Optional server-side company city filter. |
location_state | No | Optional server-side company state filter. |
limit | No | Page size for the job result. Defaults to 100 and is capped at 100. |
max_records | No | Total cap carried into the queued search. |
cursor | No | Opaque cursor when queueing a later page of a dynamic search. |
dedupe_token | No | Optional campaign or workflow token that prevents repeat delivery after the worker succeeds for this interpreted criteria and token. |
dedupe_user_id | No | Optional integration end-user ID for customers using a single API key across multiple users. When omitted, dedupe stays scoped to the API key's account. |
Response fields
| Field | Type | Description |
|---|
job_id | string | Opaque async job identifier. |
status | string | Initial job status. New jobs start as queued. |
search_strategy | string | Resolved execution path: taxonomy, dynamic, or indexed_dynamic. |
interpretation | object | The validated search interpretation stored with the job so workers do not reinterpret it. |
created_at | string | ISO timestamp for when the job was queued. |
Example response
{
"job_id": "018f4f8f-1f42-7a8c-8cf2-8a4c2b0d3a4e",
"status": "queued",
"search_strategy": "indexed_dynamic",
"interpretation": {
"roles": [{ "key": "dynamic_role", "label": "CMO" }],
"industries": [{ "key": "dynamic_industry", "label": "SaaS companies" }],
"warnings": []
},
"created_at": "2026-05-17T18:42:10.000Z"
}
GET/v1/persons/search/jobs/{job_id}
Get async person search job
Returns a queued, running, succeeded, or failed async person search job. Poll this endpoint with backoff until the job reaches succeeded or failed. Succeeded jobs return the same interpreted result, pagination, data, and billable_records shape as synchronous person search.
| Parameter | Required | Description |
|---|
job_id | Yes | Job identifier returned by POST /v1/persons/search/jobs. |
Response fields
| Field | Type | Description |
|---|
job_id | string | Opaque async job identifier. |
status | string | Current lifecycle state: queued, running, succeeded, or failed. |
search_strategy | string | Resolved execution path: taxonomy, dynamic, or indexed_dynamic. |
interpretation | object | The validated search interpretation stored with the job. |
pagination | object | Present when the job succeeded. Same shape as synchronous person search pagination. |
data | array<Person> | Present when the job succeeded. Returned person records for the completed job. |
billable_records | integer | Present when the job succeeded. Worker-recorded billable record count. |
error | string | Present when the job failed. |
Example response
{
"job_id": "018f4f8f-1f42-7a8c-8cf2-8a4c2b0d3a4e",
"status": "succeeded",
"search_strategy": "indexed_dynamic",
"interpretation": {
"roles": [{ "key": "dynamic_role", "label": "CMO" }],
"industries": [{ "key": "dynamic_industry", "label": "SaaS companies" }],
"warnings": []
},
"pagination": {
"limit": 100,
"total_records": 101,
"total_records_relation": "gte",
"total_pages": 2,
"next_cursor": "opaque-cursor-or-null",
"max_records": 2000
},
"data": [
{
"person_id": "person_123",
"first_name": "Jordan",
"last_name": "Lee",
"job_title": "Chief Marketing Officer",
"business_email": "jordan@example.com",
"company": {
"company_id": "company_123",
"name": "Example SaaS Co",
"domain": "example.com"
}
}
],
"billable_records": 1,
"timings_ms": {
"interpretation": 0,
"search": 842,
"total": 851,
"search_strategy": "indexed_dynamic"
}
}
GET/v1/persons/search/taxonomy
Person search taxonomy
Returns role and company-search dictionaries for suggestion chips and fast-path routing. Use this to keep user prompts inside precomputed or indexed paths where possible.
Response fields
| Field | Type | Description |
|---|
fast_paths.taxonomy | object | Precomputed role and industry keys with exact count support, plus role/industry compatibility metadata for safe suggestion chips. |
fast_paths.indexed_dynamic | object | Indexed dynamic role buckets and company filters that avoid live title scans. |
native_geo_parameters | array<string> | Geo parameters accepted by /v1/persons/search for server-side company city/state filters. |
Example response
{
"fast_paths": {
"taxonomy": {
"description": "Precomputed person-search serving paths with exact count support.",
"roles": [
{ "key": "chief_executive", "label": "CEO / Chief Executive Officer" },
{ "key": "owner", "label": "Owner" },
{ "key": "partner", "label": "Partner" },
{ "key": "real_estate_agent", "label": "Real estate agent" },
{ "key": "financial_advisor", "label": "Financial advisor" }
],
"industries": [
{ "key": "marketing_agency", "label": "Marketing agencies" },
{ "key": "law_firm", "label": "Law firms" },
{ "key": "real_estate", "label": "Real estate brokerages" },
{ "key": "insurance_agency", "label": "Insurance agencies" },
{ "key": "software", "label": "SaaS and software companies" }
],
"compatibility": {
"law_firm": ["chief_executive", "owner", "partner", "attorney"],
"real_estate": ["chief_executive", "owner", "real_estate_agent", "broker"],
"healthcare_practice": ["chief_executive", "owner", "doctor", "provider"]
},
"example_queries": [
"owners of insurance agencies in Las Vegas",
"real estate agents in Nevada",
"partners at law firms"
]
},
"indexed_dynamic": {
"description": "Indexed dynamic role buckets that avoid bounded live title scans when combined with company filters, employee filters, or native geo filters.",
"roles": [
{ "key": "owner", "label": "Owner", "phrases": ["owner", "owners", "office owner"] }
],
"company_filters": ["location_city", "location_state"]
}
},
"native_geo_parameters": ["location_city", "location_state"]
}
GET/v1/persons/lookup
Exact person lookup
Looks up people by exact identifiers. Provide at least one supported lookup field.
| Parameter | Required | Description |
|---|
email | No | Business email address. |
company_domain | No | Company domain. URLs are normalized to domains. |
linkedin_url | No | LinkedIn profile URL. |
phone | No | Phone number. |
Response fields
| Field | Type | Description |
|---|
data | array<Person> | People matching the supplied exact identifier fields. |
data[].company | object | Company and firmographic context for each matching person. |
billable_records | integer | Number of returned records billed for this response. |
Example response
{
"data": [
{
"person_id": "person_123",
"first_name": "Jordan",
"last_name": "Lee",
"job_title": "Chief Marketing Officer",
"business_email": "jordan@example.com",
"mobile_phone": "+12085550123",
"linkedin_url": "https://www.linkedin.com/in/jordan-lee",
"company": {
"company_id": "company_123",
"name": "Example SaaS Co",
"domain": "example.com",
"phone": "+12085550100",
"employee_count": 82,
"industry": "Software",
"sic": "7372",
"naics": "541511",
"city": "Boise",
"state": "ID"
}
}
],
"billable_records": 1
}
GET/v1/partner-customers/{partner_customer_id}/wallet
Partner customer wallet
Returns the wallet balance, active limits, usage, wallet policy, and limit state for one partner customer. Authenticate with a managed-account API key; ownership is scoped to the authenticated partner account.
| Parameter | Required | Description |
|---|
partner_customer_id | Yes | Partner customer identifier returned by POST /v1/partner-customers. |
Response fields
| Field | Type | Description |
|---|
partner_customer_id | string | Partner customer identifier. |
status | string | Current partner customer status, such as active or suspended. |
wallet.available_credit_units | integer|null | Remaining wallet credit units from active grants. Null means no finite grant-backed wallet is configured. |
wallet.granted_credit_units | integer | Active credit units granted to the customer wallet. |
wallet.applied_credit_units | integer | Credit units applied to the current wallet period: lifetime for rollover wallets, current month for monthly_reset wallets. |
wallet.credit_enforcement_mode | string | enforced hard-stops on customer limits and finite wallet balances; metered keeps usage reporting without customer-level hard stops. |
wallet.credit_reset_policy | string | rollover carries unused wallet credits forward; monthly_reset renews the active grant balance each calendar month. |
wallet.limits | object | Configured monthly and lifetime credit, search-session, and record-reveal limits. |
wallet.usage | object | Monthly and lifetime customer usage counters. |
wallet.limit_state | object | Computed can_search, can_reveal, and block reason flags. |
Example response
{
"partner_customer_id": "customer_123",
"status": "active",
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
},
"wallet": {
"available_credit_units": 75,
"granted_credit_units": 100,
"applied_credit_units": 25,
"monthly_applied_credit_units": 25,
"lifetime_applied_credit_units": 25,
"credit_enforcement_mode": "enforced",
"credit_reset_policy": "monthly_reset",
"active_credit_grants": 1,
"monthly_credit_units_used": 25,
"lifetime_credit_units_used": 25,
"limits": {
"monthly_credit_units": 100,
"monthly_search_sessions": 20,
"monthly_record_reveals": 100
},
"usage": {
"monthly_credit_units": 25,
"lifetime_credit_units": 25,
"monthly_search_sessions": 4,
"lifetime_search_sessions": 4,
"monthly_record_reveals": 21,
"lifetime_record_reveals": 21
},
"limit_state": {
"can_search": true,
"can_reveal": true,
"search_block_reason": null,
"reveal_block_reason": null
},
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
}
}
}
POST/v1/partner-customers/{partner_customer_id}/wallet/credits
Grant partner customer wallet credits
Adds a virtual credit grant to one partner customer wallet and returns the updated wallet summary. Authenticate with a managed-account API key.
| Parameter | Required | Description |
|---|
partner_customer_id | Yes | Partner customer identifier returned by POST /v1/partner-customers. |
credit_units | Yes | Positive number of credit units to grant to this customer wallet. |
credit_type | No | Optional grant type label, for example prepaid or partner. |
starts_at | No | Optional ISO timestamp when the grant becomes active. Defaults to now. |
expires_at | No | Optional ISO timestamp when the grant expires. |
note | No | Optional internal note for the grant. |
Response fields
| Field | Type | Description |
|---|
credit_grant | object | Created credit grant row. |
partner_customer_id | string | Partner customer identifier. |
wallet | object | Updated wallet balance, usage, limits, and limit state. |
Example response
{
"credit_grant": {
"id": "grant_123",
"partner_customer_id": "customer_123",
"credit_units_granted": 50
},
"partner_customer_id": "customer_123",
"status": "active",
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
},
"wallet": {
"available_credit_units": 125,
"granted_credit_units": 150,
"applied_credit_units": 25,
"credit_enforcement_mode": "enforced",
"credit_reset_policy": "monthly_reset",
"limit_state": {
"can_search": true,
"can_reveal": true
},
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
}
}
}
POST/v1/prospecting/embed-keys
Create prospecting public loader key
Creates a browser-safe public loader key for the hosted prospecting widget. The public loader key is restricted by allowed_origins and default customer wallet policy, and the public_key value is returned only on creation.
| Parameter | Required | Description |
|---|
allowed_origins | Yes | HTTPS origins allowed to bootstrap iframe sessions, for example https://partner.example. A full page path is normalized to its origin. |
credit_enforcement_mode | No | Default customer wallet mode for auto-created customers: enforced for hard stops or metered for usage reporting without customer-level blocking. Defaults to metered. |
credit_reset_policy | No | Default wallet reset policy for auto-created customers: monthly_reset or rollover. |
limits | No | Default monthly/lifetime credit, search-session, and record-reveal limits applied to auto-created customers. |
result_delivery_url | No | HTTPS endpoint that receives full purchased records when the iframe user pushes selected, page, or all results. |
result_delivery_cta | No | Button text shown in the iframe for the partner delivery endpoint action. Defaults to Push. |
csv_export_enabled | No | Set true to allow iframe users to export selected, page, or all purchased results as CSV. Defaults to false. |
Response fields
| Field | Type | Description |
|---|
public_key | string | Browser-safe public key to put in data-partner-key. Returned only once. |
embed_key | object | Stored public loader key metadata, including origin allowlist and default customer wallet policy. |
Example response
{
"public_key": "stib_embed_pk_abc123",
"embed_key": {
"id": "embed_key_123",
"key_prefix": "stib_embed_pk_abc",
"label": "Partner app loader",
"status": "active",
"allowed_origins": ["https://partner.example"],
"result_delivery_url": "https://partner.example/api/prospects",
"result_delivery_cta": "Add to HubSpot",
"csv_export_enabled": true,
"default_credit_enforcement_mode": "metered",
"default_credit_reset_policy": "monthly_reset",
"default_limits": {
"monthly_credit_units": null
}
}
}
POST/v1/prospecting/embed-sessions
Bootstrap prospecting embed session
Exchanges a public loader key and partner-owned external customer ID for a short-lived embed token. The API validates the browser Origin, upserts the scoped partner customer on first use, applies the public key defaults, and returns the token used by the hosted iframe.
| Parameter | Required | Description |
|---|
partner_key | Yes | Public loader key from POST /v1/prospecting/embed-keys or the console Prospecting page. |
customer_id | Yes | Partner-owned external customer ID. The first request creates the scoped partner customer; later requests reuse it. |
customer_name | No | Optional display name for a first-time auto-created partner customer. |
user_id | No | Optional partner-owned user ID for usage attribution inside the customer wallet. |
Response fields
| Field | Type | Description |
|---|
token | string | Short-lived signed embed token for the hosted iframe. |
partner_customer_id | string | Internal scoped partner customer identifier. |
external_customer_id | string | Partner-owned customer ID used for the bootstrap request. |
expires_at | string | ISO timestamp when the embed token expires. |
Example response
{
"token": "signed-short-lived-embed-token",
"partner_customer_id": "customer_123",
"external_customer_id": "partner-customer-123",
"expires_at": "2026-05-17T19:42:10.000Z"
}
GET/v1/prospecting/wallet
Prospecting embed wallet
Returns the wallet summary for the scoped customer in a prospecting embed token. Use this from hosted iframes or partner frontends without exposing the partner API key.
| Parameter | Required | Description |
|---|
authorization | Yes | Bearer embed token returned by POST /v1/prospecting/embed-sessions. |
Response fields
| Field | Type | Description |
|---|
partner_customer_id | string | Partner customer identifier from the embed token. |
status | string | Current partner customer status. |
wallet | object | Scoped wallet balance, usage, limits, and limit state for the embed customer only. |
allowed_result_actions | array<string> | Configured result actions available in the iframe, such as push_endpoint and csv_export. |
result_action_labels | object | Display labels for configured iframe actions, including the partner-provided result_delivery_cta for push_endpoint. |
Example response
{
"partner_customer_id": "customer_123",
"status": "active",
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
},
"wallet": {
"available_credit_units": 75,
"granted_credit_units": 100,
"applied_credit_units": 25,
"monthly_applied_credit_units": 25,
"lifetime_applied_credit_units": 25,
"credit_enforcement_mode": "enforced",
"credit_reset_policy": "monthly_reset",
"active_credit_grants": 1,
"monthly_credit_units_used": 25,
"lifetime_credit_units_used": 25,
"limits": {
"monthly_credit_units": 100,
"monthly_search_sessions": 20,
"monthly_record_reveals": 100
},
"usage": {
"monthly_credit_units": 25,
"lifetime_credit_units": 25,
"monthly_search_sessions": 4,
"lifetime_search_sessions": 4,
"monthly_record_reveals": 21,
"lifetime_record_reveals": 21
},
"limit_state": {
"can_search": true,
"can_reveal": true,
"search_block_reason": null,
"reveal_block_reason": null
},
"allowed_result_actions": ["push_endpoint", "csv_export"],
"result_action_labels": {
"push_endpoint": "Add to HubSpot",
"csv_export": "Export CSV"
}
}
}
POST/v1/prospecting/sessions/{search_id}/push
Push prospecting results to partner
Reveals and purchases the selected prospect previews, then posts full records server-side to the result_delivery_url configured on the partner customer or public embed key. The iframe button can use the configured result_delivery_cta. Supports selected prospect_ids, all records on the loaded page, or all filtered session results.
| Parameter | Required | Description |
|---|
authorization | Yes | Bearer embed token for the scoped partner customer. |
search_id | Yes | Prospecting session ID returned by the iframe search endpoint. |
selection_mode | Yes | selected, page, or all_results. |
prospect_ids | No | Preview prospect IDs to deliver when selection_mode is selected or page. |
applied_filters | No | Current refinement filters when pushing all_results. |
Response fields
| Field | Type | Description |
|---|
delivered | boolean | True when the partner endpoint accepted the delivery. |
delivery_status | integer | HTTP status returned by the configured partner result_delivery_url. |
pushed_records | integer | Number of full records posted to the partner endpoint. |
net_new_billable_records | integer | Records newly purchased for this account and partner customer. |
already_purchased_records | integer | Records already owned by this account and partner customer, delivered without rebilling. |
Delivery headers
content-type: application/json
user-agent: stibnite-prospecting/1.0
stibnite-event-type: prospecting.records.pushed
stibnite-search-id: search_123
Partner delivery payload
{
"event": "prospecting.records.pushed",
"search_id": "search_123",
"partner_customer_id": "customer_123",
"partner_user_id": "user_123",
"selection": {
"mode": "selected",
"prospect_ids": ["5x5-person-123"],
"filters": {},
"total_records": 1
},
"pushed_records": 1,
"net_new_billable_records": 1,
"already_purchased_records": 0,
"data": [
{
"prospect_id": "5x5-person-123",
"person_id": "person_123",
"first_name": "Jane",
"last_name": "Doe",
"job_title": "VP Sales",
"business_email": "jane@example.com",
"mobile_phone": "+12085550123",
"linkedin_url": "https://linkedin.com/in/janedoe",
"company": {
"company_id": "company_123",
"name": "Example Inc",
"domain": "example.com",
"phone": "+12085550100",
"linkedin_url": "https://linkedin.com/company/example",
"revenue": 10000000,
"employee_count": 42,
"industry": "Software",
"sic": "7372",
"naics": "541511",
"city": "Austin",
"state": "TX"
},
"reveal_state": "purchased"
}
]
}
Example response
{
"delivered": true,
"delivery_status": 202,
"search_id": "search_123",
"partner_customer_id": "customer_123",
"selection": {
"mode": "selected",
"prospect_ids": ["5x5-person-123"]
},
"pushed_records": 1,
"net_new_billable_records": 1,
"already_purchased_records": 0
}
POST/v1/prospecting/sessions/{search_id}/export
Export prospecting results as CSV
Reveals and purchases the selected prospect previews, then returns full records as a CSV download when csv_export_enabled is true for the scoped partner customer. Supports selected prospect_ids, all records on the loaded page, or all filtered session results. Billing is only for net-new records owned by this account and partner customer.
| Parameter | Required | Description |
|---|
authorization | Yes | Bearer embed token for the scoped partner customer. |
search_id | Yes | Prospecting session ID returned by the iframe search endpoint. |
selection_mode | Yes | selected, page, or all_results. |
prospect_ids | No | Preview prospect IDs to export when selection_mode is selected or page. |
applied_filters | No | Current refinement filters when exporting all_results. |
Response fields
| Field | Type | Description |
|---|
content-type | header | text/csv; charset=utf-8. |
content-disposition | header | Attachment filename for the generated CSV. |
x-exported-records | header | Number of full records included in the CSV. |
x-net-new-billable-records | header | Records newly purchased for this account and partner customer. |
x-already-purchased-records | header | Records already owned by this account and partner customer, exported without rebilling. |
Example response
content-type: text/csv; charset=utf-8
content-disposition: attachment; filename="prospecting-search_123.csv"
x-exported-records: 1
x-net-new-billable-records: 1
x-already-purchased-records: 0
prospect_id,person_id,first_name,last_name,job_title,business_email,mobile_phone,linkedin_url,company_name,company_domain,company_phone,company_linkedin_url,company_revenue,company_employee_count,company_industry,company_sic,company_naics,company_city,company_state
5x5-person-123,person_123,Jane,Doe,VP Sales,jane@example.com,+12085550123,https://linkedin.com/in/janedoe,Example Inc,example.com,+12085550100,https://linkedin.com/company/example,10000000,42,Software,7372,541511,Austin,TX
GET/v1/domains
Company domain inventory
Returns non-billable company-domain metadata for accounts with enough known contacts. Use this first when scoring domain coverage before a follow-up /v1/persons/search request.
| Parameter | Required | Description |
|---|
limit | No | Page size. Defaults to 100 and is capped at 100. |
cursor | No | Opaque cursor from the previous response. Cursors are tied to the same min_contacts, industry, and location_state filters. |
min_contacts | No | Only return domains with at least this many contacts. Defaults to 5. |
industry | No | Case-insensitive contains filter on firmographic primary_industry, for example Software. |
location_state | No | Optional company state filter. Accepts a two-letter state code such as ID or a full state name such as Idaho. |
Response fields
| Field | Type | Description |
|---|
data | array<Domain> | Returned domain metadata for the current page. |
data[].domain | string | Normalized company domain. |
data[].contact_count | integer | Number of known contacts for the domain. |
data[].industry | string | Minimal firmographic industry context when available. |
data[].location | object | Minimal company city/state context when available. |
pagination | object | Page metadata. Includes next_cursor. |
Example response
{
"data": [
{
"domain": "example.com",
"contact_count": 12,
"industry": "Software Development",
"location": {
"city": "Boise",
"state": "ID"
}
}
],
"pagination": {
"next_cursor": null
}
}
GET/v1/companies/search
Natural-language company search
Searches companies by a natural-language ICP query. The API interprets the query into constrained company category, location, code, keyword, and employee-count filters before running parameterized ClickHouse SQL. Totals are bounded by default for speed; pass exact_count=true only when the slower exact count is required.
| Parameter | Required | Description |
|---|
q | Yes | Natural-language company search, for example all SaaS companies in Idaho. |
limit | No | Page size. Defaults to 100 and is capped at 100. |
max_records | No | Total cap across all pages, for example 2000. |
cursor | No | Opaque cursor from the previous response. |
exact_count | No | Set to true to request an exact ClickHouse count. Defaults to bounded totals for lower latency. |
Response fields
| Field | Type | Description |
|---|
interpretation | object | The validated company search interpretation, including company category, location, filters, and warnings. |
pagination | object | Page metadata. Includes limit, total_records, total_pages, next_cursor, and cap metadata when max_records is used. |
data | array<Company> | Returned company records for the current page. Optional fields are omitted when unavailable. |
billable_records | integer | Number of returned company records billed for this response. |
Example response
{
"interpretation": {
"industries": [{ "key": "dynamic_industry", "label": "SaaS companies" }],
"locations": [{ "key": "state:ID", "label": "Idaho", "state": "ID" }],
"filters": { "company_state": "ID" },
"warnings": [
"SaaS company search requires contextual SaaS or software-as-a-service evidence in company fields."
]
},
"pagination": {
"limit": 100,
"total_records": 31,
"total_records_relation": "gte",
"total_pages": 1,
"next_cursor": null,
"max_records": 2000,
"total_matching_records": 31,
"total_matching_records_relation": "gte"
},
"data": [
{
"company_id": "example-company-id",
"name": "Example SaaS Co",
"domain": "example.com",
"website": "https://example.com",
"employee_count": 42,
"industry": "Software",
"city": "Boise",
"state": "ID",
"country": "US"
}
],
"billable_records": 1
}
GET/v1/companies/{domain}/people
Company people
Returns people associated with a normalized company domain.
| Parameter | Required | Description |
|---|
domain | Yes | Company domain path segment, for example example.com. |
limit | No | Page size. Defaults to 100 and is capped at 500. |
max_records | No | Total cap across company people pages. |
cursor | No | Opaque cursor from the previous response. |
Response fields
| Field | Type | Description |
|---|
data | array<Person> | People associated with the normalized company domain. |
pagination | object | Page metadata. Includes limit, next_cursor, and max_records when supplied. |
data[].company | object | Company and firmographic context for each returned person. |
billable_records | integer | Number of returned records billed for this response. |
Example response
{
"data": [
{
"person_id": "person_123",
"first_name": "Jordan",
"last_name": "Lee",
"job_title": "Chief Marketing Officer",
"business_email": "jordan@example.com",
"company": {
"company_id": "company_123",
"name": "Example SaaS Co",
"domain": "example.com",
"employee_count": 82,
"industry": "Software"
}
}
],
"pagination": {
"limit": 100,
"next_cursor": null
},
"billable_records": 1
}
POST/v1/webhooks/endpoints
Create webhook endpoint
Registers an account-scoped HTTPS webhook endpoint for async person-search job events. The signing_secret is returned only once on creation; store it and verify the stibnite-signature HMAC header on every delivery. Webhook management is API-first today; use GET /v1/webhooks/endpoints to list registered endpoints because the console does not expose webhook setup yet.
| Parameter | Required | Description |
|---|
url | Yes | HTTPS endpoint that receives webhook POST requests. |
description | No | Human-readable label for the endpoint. |
events | No | Allowed event types: person_search.job.succeeded and person_search.job.failed. Defaults to both. |
Response fields
| Field | Type | Description |
|---|
id | string | Webhook endpoint identifier. |
url | string | Destination URL. |
events | array<string> | Subscribed event types. |
status | string | Endpoint status. |
signing_secret | string | HMAC signing secret returned only when the endpoint is created. |
Example response
{
"id": "endpoint_123",
"url": "https://customer.example/webhooks/stibnite",
"description": "CRM enrichment workflow",
"events": ["person_search.job.succeeded", "person_search.job.failed"],
"status": "active",
"created_at": "2026-05-17T18:42:10.000Z",
"signing_secret": "whsec_returned_once"
}
DELETE/v1/webhooks/endpoints/{endpoint_id}
Delete webhook endpoint
Deletes an account-scoped webhook endpoint and stops future deliveries to that URL.
| Parameter | Required | Description |
|---|
endpoint_id | Yes | Webhook endpoint identifier returned by POST /v1/webhooks/endpoints. |
Response fields
| Field | Type | Description |
|---|
deleted | boolean | True when the endpoint was deleted. |
Example response
{
"deleted": true
}
GET/v1/usage
Usage summary
Returns usage ledger totals for the calling API key.
Response fields
| Field | Type | Description |
|---|
requests | integer | Count of successful requests recorded for the authenticated API key. |
billable_records | integer | Total records billed to the authenticated API key. |
Example response
{
"requests": 12,
"billable_records": 34
}