Signals
Funding (sync)
DeprecatedSynchronous form of the Funding signal (POST /v1/signals/funding):
creates the signal and blocks until it completes (or the timeout is
reached), returning the result in the same response. Recommended for
interactive and agent workflows. If you supply a webhookUrl, the completed signal is
still delivered to it in addition to this response — omit it unless
you want both.
The completed answer (answer.jsonSchema) conforms to
FundingSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status.
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/sync/funding" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "stripe.com" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "signalType": "COMPANY", "namedSignal": "funding", "status": "completed", "domain": "stripe.com", "answerType": "json_schema", "createdAt": "2026-07-01T10:30:00Z", "completedAt": "2026-07-01T10:31:40Z", "answer": { "type": "json_schema", "jsonSchema": { "hasFundingEvent": true, "isPublic": false, "latestRound": "Series I", "latestEvents": [ { "eventType": "funding_round", "round": "Series I", "amount": 6500000000, "currency": "USD", "investors": [ "Andreessen Horowitz", "Sequoia Capital", "General Catalyst" ], "announcedAt": "2023-03-15", "sourceUrls": [ "https://stripe.com/newsroom/news/series-i" ] } ] } }, "confidence": 0.93, "sources": [ { "url": "https://stripe.com/newsroom/news/series-i", "title": "Stripe raises Series I" } ]}Funding (async)
DeprecatedSummarise a company's most recent funding and public/IPO status from a domain.
The AI confirms sources belong to the company at that domain, reports the
latest primary equity round (never a secondary, tender, or debt
event), and flags a completed IPO / direct listing / SPAC as
isPublic: true with latestRound: "IPO".
This is the async endpoint: it returns 201 immediately with a
processing signal. Poll GET /v1/companies/signals/{signalId} or supply a
webhookUrl to receive the completed result. For a single blocking
request, use POST /v1/signals/sync/funding.
The completed answer (answer.jsonSchema) conforms to
FundingSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/funding" \ -H "Content-Type: application/json" \ -d '{ "domain": "stripe.com" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "signalType": "COMPANY", "namedSignal": "funding", "status": "failed", "domain": "stripe.com", "createdAt": "2026-07-01T10:30:00Z", "error": "Research did not complete because upstream sources were unavailable. Retry later.", "retryable": true}M&A (sync)
DeprecatedSynchronous form of the M&A signal (POST /v1/signals/mna):
creates the signal and blocks until it completes, returning the result in
the same response. If you supply a webhookUrl, the completed signal is still delivered to it in addition to this response — omit it unless you want both.
The completed answer (answer.jsonSchema) conforms to
MAndASignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status.
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/sync/mna" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "figma.com" }'{ "id": "f56d2ec5-e533-4c62-a67c-dc7d4eeaf361", "signalType": "COMPANY", "namedSignal": "mna", "status": "completed", "domain": "figma.com", "answerType": "json_schema", "createdAt": "2026-07-01T10:30:00Z", "completedAt": "2026-07-01T10:31:20Z", "answer": { "type": "json_schema", "jsonSchema": { "detected": true, "latestEvents": [ { "role": "acquiree", "counterparty": "Adobe", "status": "terminated", "amount": 20000000000, "currency": "USD", "announcedAt": "2022-09-15", "sourceUrls": [ "https://news.adobe.com/news/2023/12/adobe-figma-update" ] } ] } }, "confidence": 0.97, "sources": [ { "url": "https://news.adobe.com/news/2023/12/adobe-figma-update", "title": "Adobe and Figma mutually terminate merger agreement" } ]}M&A (async)
DeprecatedDetect whether a company was acquired, or made acquisitions, in the recent window — counterparty, deal status, and value where disclosed.
Counts only true acquisitions (control transfer): minority investments,
funding rounds, and partnerships are excluded. role distinguishes the
queried company being bought (acquiree, reported at any age) from it
buying others (acquirer, last 24 months only). An announced deal that
later collapsed is terminated, never completed. An acquisition backed
only by a data aggregator with no primary corroboration stays
rumored and does not count as detected.
This is the async endpoint. For a single blocking request, use
POST /v1/signals/sync/mna.
The completed answer (answer.jsonSchema) conforms to
MAndASignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/mna" \ -H "Content-Type: application/json" \ -d '{ "domain": "figma.com" }'{ "id": "f56d2ec5-e533-4c62-a67c-dc7d4eeaf361", "signalType": "COMPANY", "namedSignal": "mna", "status": "failed", "domain": "figma.com", "createdAt": "2026-07-01T10:30:00Z", "error": "Research did not complete because upstream sources were unavailable. Retry later.", "retryable": true}Tech (sync)
DeprecatedSynchronous form of the Tech signal (POST /v1/signals/tech):
creates the signal and blocks until it completes, returning the result in
the same response. Supply exactly one of category or technology.
If you supply a webhookUrl, the completed signal is still delivered to it in addition to this response — omit it unless you want both.
The completed answer (answer.jsonSchema) conforms to
TechSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status.
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for the Tech signal. Supply a domain plus exactly one
of category or technology — providing neither or both is a 422.
Request body for the Tech signal. Supply a domain plus exactly one
of category or technology — providing neither or both is a 422.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253A coarse technology category to survey. Mutually exclusive with
technology.
Value in
- "erp"
- "crm"
A specific technology to check for, given as free text (e.g.
"salesforce", "SAP S/4HANA"); Saber resolves it to a canonical
registry slug. An unresolvable value returns 422 with did-you-mean
suggestions. Mutually exclusive with category.
Optional webhook to receive the completed signal. Intended for the async endpoint; if supplied on the synchronous /sync/ endpoint the webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/sync/tech" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "monday.com", "category": "crm" }'{ "id": "a67d3fc6-f644-5d73-b78d-ed8e5ffb0472", "signalType": "COMPANY", "namedSignal": "tech", "status": "completed", "domain": "monday.com", "answerType": "json_schema", "createdAt": "2026-07-01T10:30:00Z", "completedAt": "2026-07-01T10:32:05Z", "answer": { "type": "json_schema", "jsonSchema": { "scope": "category", "category": "crm", "primary": "salesforce", "technologies": [ { "technology": "salesforce", "displayName": "Salesforce", "status": "active", "confidence": 0.9, "lastEvidence": "2026-05", "evidence": [ { "type": "job_posting", "url": "https://monday.com/careers/salesforce-admin", "title": "Salesforce Administrator" } ] } ] } }, "confidence": 0.9, "sources": [ { "url": "https://monday.com/careers/salesforce-admin", "title": "Salesforce Administrator — Careers" } ]}Tech (async)
DeprecatedDetect which system(s) a company currently uses in a technology category, verified with public web evidence.
Supply exactly one typed parameter:
category— a coarse category (erporcrm). Returns every system detected in that category, with the current system of record inprimary.technology— a specific product (free text resolved to a canonical slug, e.g.salesforce,SAP S/4HANA). Returns a one-elementtechnologieslist whosestatuscarries the verdict (active,churned, ornot_found).
Vendor data is a prior, not the answer. Technographics detections
enter the agent loop only as leads to verify; every reported technology
must cite public web evidence — a job posting, engineering blog, docs, a
case study, or a live website fingerprint. A vendor-only hint that can't
be corroborated surfaces as status: not_found, never as a confirmed
finding.
This is the async endpoint. For a single blocking request, use
POST /v1/signals/sync/tech.
The completed answer (answer.jsonSchema) conforms to
TechSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for the Tech signal. Supply a domain plus exactly one
of category or technology — providing neither or both is a 422.
Request body for the Tech signal. Supply a domain plus exactly one
of category or technology — providing neither or both is a 422.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253A coarse technology category to survey. Mutually exclusive with
technology.
Value in
- "erp"
- "crm"
A specific technology to check for, given as free text (e.g.
"salesforce", "SAP S/4HANA"); Saber resolves it to a canonical
registry slug. An unresolvable value returns 422 with did-you-mean
suggestions. Mutually exclusive with category.
Optional webhook to receive the completed signal. Intended for the async endpoint; if supplied on the synchronous /sync/ endpoint the webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/tech" \ -H "Content-Type: application/json" \ -d '{ "domain": "monday.com", "category": "crm" }'{ "id": "a67d3fc6-f644-5d73-b78d-ed8e5ffb0472", "signalType": "COMPANY", "namedSignal": "tech", "status": "failed", "domain": "monday.com", "createdAt": "2026-07-01T10:30:00Z", "error": "Research did not complete because upstream sources were unavailable. Retry later.", "retryable": true}Open Jobs (sync)
DeprecatedSynchronous form of the Open Jobs signal (POST /v1/signals/open-jobs):
creates the signal and blocks until it completes, returning the result in
the same response. If you supply a webhookUrl, the completed signal is still delivered to it in addition to this response — omit it unless you want both.
The completed answer (answer.jsonSchema) conforms to
OpenJobsSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status.
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/sync/open-jobs" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "datadoghq.com" }'{ "id": "b78e4bd7-b755-6e84-c89e-fe9f6bbc0583", "signalType": "COMPANY", "namedSignal": "open-jobs", "status": "completed", "domain": "datadoghq.com", "answerType": "json_schema", "createdAt": "2026-07-01T10:30:00Z", "completedAt": "2026-07-01T10:31:10Z", "answer": { "type": "json_schema", "jsonSchema": { "openings": 876, "topTitles": [ "Senior Software Engineer", "Product Manager", "Enterprise Account Executive" ], "hiringThemes": [ "Engineering", "Product", "Sales/GTM" ], "techHiringFor": [ "Go", "Kubernetes", "React" ], "locations": [ "New York, NY", "Remote", "Paris, France" ], "latestPostingDate": "2026-06-28", "source": "public_job_listings" } }, "confidence": 0.9}Open Jobs (async)
DeprecatedSummarise what a company is hiring for from public job postings: how many roles are open, the function areas and technologies behind them, and where.
openings is the true total matching the trailing 90-day window (the
job search tool's reported match count), not the number of sampled
listings. topTitles, hiringThemes, techHiringFor, and locations
are drawn from a small sample and are examples, not a proportional
breakdown. hiringThemes maps roles onto a fixed function taxonomy so the
field stays filterable and stable.
This is the async endpoint. For a single blocking request, use
POST /v1/signals/sync/open-jobs.
The completed answer (answer.jsonSchema) conforms to
OpenJobsSignalAnswer. Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/open-jobs" \ -H "Content-Type: application/json" \ -d '{ "domain": "datadoghq.com" }'{ "id": "b78e4bd7-b755-6e84-c89e-fe9f6bbc0583", "signalType": "COMPANY", "namedSignal": "open-jobs", "status": "failed", "domain": "datadoghq.com", "createdAt": "2026-07-01T10:30:00Z", "error": "Research did not complete because upstream sources were unavailable. Retry later.", "retryable": true}Firmographics (sync)
DeprecatedSynchronous form of the Firmographics signal (POST /v1/signals/firmographics):
creates the signal and blocks until it completes, returning the result in
the same response. If you supply a webhookUrl, the completed signal is still delivered to it in addition to this response — omit it unless you want both.
The completed answer (answer.jsonSchema) conforms to
FirmographicsSignalAnswer.
Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status.
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/sync/firmographics" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "procore.com" }'{ "id": "c89f5ae8-c866-7f95-d9af-0f0a70cd0694", "signalType": "COMPANY", "namedSignal": "firmographics", "status": "completed", "domain": "procore.com", "answerType": "json_schema", "createdAt": "2026-07-01T10:30:00Z", "completedAt": "2026-07-01T10:31:55Z", "answer": { "type": "json_schema", "jsonSchema": { "name": "Procore Technologies", "domain": "procore.com", "website": "https://www.procore.com", "employeeCount": 3500, "sizeRange": "1001-5000", "type": "Public", "foundedYear": 2002, "headquarters": { "city": "Carpinteria", "state": "CA", "countryCode": "US" }, "linkedInFollowers": 320000, "linkedinIndustry": "Software Development", "saberCategory": { "primary": "Construction Software", "niche": "Construction ERP / project-cost management", "confidence": 0.92, "rationale": "Positions itself as a construction management platform for owners, GCs, and specialty contractors.", "evidence": [ { "type": "company_site", "url": "https://www.procore.com/platform", "title": "Procore Platform Overview" } ] }, "segments": [ "B2B" ], "segmentRationale": "Sells to construction firms (owners, general and specialty contractors)." } }, "confidence": 0.92, "sources": [ { "url": "https://www.procore.com/platform", "title": "Procore Platform Overview" } ]}Firmographics (async)
DeprecatedReturn a company's base profile — headcount, size band, entity type, founded year, HQ location — plus a Saber-derived category that refines the coarse public industry tag, with cited web evidence.
The differentiator is saberCategory: a generalized→niche classification
that corrects the over-broad public industry label (which tags many
firms simply as "Software") using the company's own site and product
pages. segments captures who the company sells to (B2B, B2C,
B2B2C, B2G, C2C). Authoritative enrichment priors (headcount,
LinkedIn followers, type, founded year, website) are copied verbatim when
known and researched only when absent — never guessed.
This is the async endpoint. For a single blocking request, use
POST /v1/signals/sync/firmographics.
The completed answer (answer.jsonSchema) conforms to
FirmographicsSignalAnswer.
Cost: 2 credits, charged once per result delivered to your organization — your own repeat calls served from cache are free, and failed runs are never charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request body for a prebuilt signal. You supply the company
domain (plus optional delivery and refresh controls); the signal
returns its own documented, structured answer.
The company domain to research (e.g., "acme.com").
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253Optional webhook to receive the completed signal. Intended for the
async endpoints; if supplied on a synchronous /sync/ endpoint the
webhook is still delivered, in addition to the blocking response.
urilength <= 2048Force a fresh run. By default an identical request (same domain and
parameters) returns the existing result instead of re-running; set
this to true to bypass that and research again.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/signals/firmographics" \ -H "Content-Type: application/json" \ -d '{ "domain": "procore.com" }'{ "id": "c89f5ae8-c866-7f95-d9af-0f0a70cd0694", "signalType": "COMPANY", "namedSignal": "firmographics", "status": "failed", "domain": "procore.com", "createdAt": "2026-07-01T10:30:00Z", "error": "Research did not complete because upstream sources were unavailable. Retry later.", "retryable": true}Create a company signal synchronously
Deprecated⭐ This is the recommended way to create signals and get results instead of async + webhooks.
Creates a signal and waits synchronously for it to complete, returning the result in the same request. This endpoint blocks until the signal processing finishes or a timeout is reached.
Why Use the Sync Endpoint?
Advantages over async + webhooks:
- ✅ Get results immediately in one request
- ✅ No webhook hosting required
- ✅ No polling implementation needed
- ✅ Simpler integration
- ✅ Better for synchronous workflows
How It Works
- Send your signal creation request (same payload as regular POST /v1/companies/signals)
- The endpoint creates the signal and polls for completion
- Returns the completed signal with results when processing finishes
- If timeout is reached, returns the latest status (processing)
Timeout Configuration
- Default timeout: 870 seconds (server-configured, applies when the header is absent)
- Max timeout: 870 seconds — higher values are clamped
- Custom timeout: Use
X-Sbr-Timeout-Secheader to set custom timeout (up to max) - Error on timeout: Use
X-Sbr-Timeout-Error: trueheader to return 408 on timeout instead of latest status
Response Codes
200 OK- Signal completed, or timeout reached with the still-processingsignal in the body (checkstatus)408 Request Timeout- Timeout reached (when X-Sbr-Timeout-Error: true)
Using with Templates
Use signalTemplateId instead of defining questions inline for standardized research:
{ "domain": "acme.com", "signalTemplateId": "a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"}Templates let you reuse research questions, qualification criteria, and answer types across multiple companies. Create templates via POST /v1/companies/signals/templates.
Credits
Each signal charges 2 credits. Repeat calls served from the 12-hour cache (see Caching Behavior on POST /v1/companies/signals) do not consume additional credits, and failed runs are never charged — reserved credits are released.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
The company domain to research (e.g., "acme.com")
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253The research question to ask about the company
1 <= length <= 2000The expected format of the answer
"open_text"Value in
- "open_text"
- "number"
- "boolean"
- "list"
- "percentage"
- "currency"
- "url"
- "contacts"
- "contacts_generation"
- "contact_posts"
- "contact_engagements"
- "json_schema"
JSON Schema defining the expected output structure. Required when answerType is "json_schema". The AI will generate data conforming to this schema.
Supported JSON Schema features:
type: object, array, string, number, integer, boolean, nullproperties: Define object propertiesrequired: List of required property namesitems: Schema for array itemsenum: Enumeration of allowed valuesdescription: Property descriptions (helps AI generate better data)
Limitations:
- Maximum 100 total properties
- Maximum 5 levels of nesting
anyOf,oneOf,allOfare not supported$refonly supports self-references for recursive schemas
Optional webhook URL to receive notifications when processing completes.
Webhooks are only sent for freshly processed signals — cached results do not trigger webhooks.
Set forceRefresh: true to bypass the cache and ensure webhook delivery.
urilength <= 2048The importance/weight of the signal
Value in
- "important"
- "nice_to_have"
- "not_important"
Qualification criteria mapping answer values based on answerType. The structure must match the answerType specified.
For boolean answerType:
{ "yes": "good", "no": "disqualified"}For number, percentage, or currency answerType:
{ "ranges": [ { "rangeStart": 0, "rangeEnd": 100, "answerValue": "neutral" }, { "rangeStart": 101, "rangeEnd": 1000, "answerValue": "good" } ]}For list answerType:
{ "choices": { "salesforce": { "answerValue": "good", "label": "Salesforce" }, "hubspot": { "answerValue": "neutral", "label": "HubSpot" }, "none": { "answerValue": "disqualified", "label": "No CRM" } }}Valid answerValue options (from worst to best):
- disqualified: Answer indicates a deal-breaker or disqualifying factor
- poor: Answer indicates a weak fit
- neutral: Answer is acceptable but not ideal
- good: Answer indicates a strong fit
- excellent: Answer indicates an exceptional fit
Optional signal template ID to use. When provided, the template configuration (question, answerType, weight, qualificationCriteria) will be used. The system always resolves to the latest active version of the template. Only the domain parameter is required when using a template.
uuidForce re-run of the signal analysis, skipping the cache. When set to true, a new signal will be created even if a cached result exists.
falseConnector configuration for signal generation
Controls how strictly Saber verifies answers before responding.
- strict: Only returns answers backed by verified sources (primary or trusted secondary sources). Returns null when information is unavailable.
- lenient: Allows logical inference and best-effort estimates when direct evidence is missing. Uses industry benchmarks, logical correlates, and quantitative metrics.
"strict"Value in
- "strict"
- "lenient"
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/companies/signals/sync" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "domain": "clay.com", "question": "Does this company have open roles in operations?", "answerType": "boolean" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "completed", "domain": "clay.com", "question": "Does this company have open roles in operations?", "createdAt": "2024-01-15T10:30:00Z", "completedAt": "2024-01-15T10:32:15Z", "answer": { "type": "boolean", "boolean": { "value": true } }, "reasoning": "Based on their careers page, Clay has multiple open positions in Operations including Operations Manager and Operations Coordinator roles", "confidence": 0.95, "sources": [ { "url": "https://clay.com/careers", "title": "Careers at Clay", "snippet": "We're hiring for Operations Manager and Operations Coordinator roles..." } ]}Retrieve all signals with optional filtering by domain or companyId, pagination and filtering. Results are sorted by creation date (latest first).
Note: For creating signals and getting results in one step, we recommend using the
/v1/companies/signals/sync endpoint instead, which returns the result directly.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Query Parameters
Filter signals by company domain (e.g., "acme.com")
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$Filter signals by company ID
Maximum number of results per page
1 <= value <= 2525Number of results to skip for pagination
0 <= value0Filter signals completed on or after this date (RFC3339 format)
date-timeFilter signals completed on or before this date (RFC3339 format)
date-timeFilter by signal status (can be specified multiple times for multiple statuses)
Filter signals by subscription ID (UUID of the signal subscription that triggered execution)
uuidResponse Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/companies/signals?domain=acme.com&companyId=comp_abc123&limit=25&offset=0&fromDate=2024-01-01T00%3A00%3A00Z&toDate=2024-12-31T23%3A59%3A59Z&status=completed&subscriptionId=a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"{ "results": [ { "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "completed", "domain": "acme.com", "question": "What is their main product?", "createdAt": "2024-01-15T10:30:00Z", "completedAt": "2024-01-15T10:32:00Z", "answer": { "type": "open_text", "openText": { "value": "Enterprise CRM software" } }, "confidence": 0.95 }, { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "processing", "domain": "acme.com", "question": "How many employees?", "createdAt": "2024-01-15T09:00:00Z" } ], "total": 42, "limit": 25, "offset": 0, "count": 2}Create a company signal asynchronously
DeprecatedSubmit a domain and question to create a new research signal. The AI will analyze the domain and provide a structured answer based on the specified answer type.
When to Use This Endpoint
Use this endpoint for event-driven architectures where you need webhook notifications.
For simpler integrations, use the /v1/companies/signals/sync endpoint (recommended) which returns results immediately.
Webhooks
Configure webhooks by including a webhookUrl parameter in your request.
What we deliver:
One logical delivery per signal, once it reaches a terminal state — retries
(below) mean your endpoint may see it as more than one HTTP request, all
carrying the same X-Idempotency-Key. The body is the signal object itself —
there is no event envelope and no event-type header, so read the body's
status (completed or failed) to tell the outcome. One exception: a
Slack webhook URL (https://hooks.slack.com/services/…) receives a formatted
Slack message instead of the raw signal object.
Webhook security:
Deliveries are not signed. Treat the payload as untrusted: use an unguessable
webhookUrl, and re-read the signal via GET /v1/companies/signals/{signalId}
before acting on it. Each delivery carries an X-Idempotency-Key header you can
use to discard duplicates.
Webhook reliability:
- Deliveries that fail to connect, time out, or return 5xx are attempted up to 5 times in total with exponential backoff
- A 4xx response is treated as a permanent rejection and is not retried
- A
webhookUrlwhose host does not resolve in DNS is rejected without retry, so point it at a hostname that already resolves - Webhook requests timeout after 25 seconds
- Your endpoint should respond with 2xx status code
- A failed delivery never fails the signal: the answer is still produced, billed, and readable via the API
Caching Behavior
Your response will be cached for up to 12 hours by default, unless you set the forceRefresh flag to true.
Cache is based on a hash of the following fields: domain (or contactProfileUrl for contact signals), question, answer type, verification mode, and output schema (if provided). Changing any of these fields will create a new signal. We will not send you the webhook if you hit the cache, even if the webhook URL in the payload is different from the original request.
Instead you will receive the latest status of the signal immediately in the response.
Using with Templates
Use signalTemplateId instead of defining questions inline for standardized research:
{ "domain": "acme.com", "signalTemplateId": "a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "webhookUrl": "https://myapp.com/webhooks/signals"}Templates let you reuse research questions, qualification criteria, and answer types across multiple companies. Create templates via POST /v1/companies/signals/templates.
Credits
Each signal charges 2 credits. Repeat calls served from the cache (see Caching Behavior above) do not consume additional credits, and failed runs are never charged — reserved credits are released.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
The company domain to research (e.g., "acme.com")
^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$1 <= length <= 253The research question to ask about the company
1 <= length <= 2000The expected format of the answer
"open_text"Value in
- "open_text"
- "number"
- "boolean"
- "list"
- "percentage"
- "currency"
- "url"
- "contacts"
- "contacts_generation"
- "contact_posts"
- "contact_engagements"
- "json_schema"
JSON Schema defining the expected output structure. Required when answerType is "json_schema". The AI will generate data conforming to this schema.
Supported JSON Schema features:
type: object, array, string, number, integer, boolean, nullproperties: Define object propertiesrequired: List of required property namesitems: Schema for array itemsenum: Enumeration of allowed valuesdescription: Property descriptions (helps AI generate better data)
Limitations:
- Maximum 100 total properties
- Maximum 5 levels of nesting
anyOf,oneOf,allOfare not supported$refonly supports self-references for recursive schemas
Optional webhook URL to receive notifications when processing completes.
Webhooks are only sent for freshly processed signals — cached results do not trigger webhooks.
Set forceRefresh: true to bypass the cache and ensure webhook delivery.
urilength <= 2048The importance/weight of the signal
Value in
- "important"
- "nice_to_have"
- "not_important"
Qualification criteria mapping answer values based on answerType. The structure must match the answerType specified.
For boolean answerType:
{ "yes": "good", "no": "disqualified"}For number, percentage, or currency answerType:
{ "ranges": [ { "rangeStart": 0, "rangeEnd": 100, "answerValue": "neutral" }, { "rangeStart": 101, "rangeEnd": 1000, "answerValue": "good" } ]}For list answerType:
{ "choices": { "salesforce": { "answerValue": "good", "label": "Salesforce" }, "hubspot": { "answerValue": "neutral", "label": "HubSpot" }, "none": { "answerValue": "disqualified", "label": "No CRM" } }}Valid answerValue options (from worst to best):
- disqualified: Answer indicates a deal-breaker or disqualifying factor
- poor: Answer indicates a weak fit
- neutral: Answer is acceptable but not ideal
- good: Answer indicates a strong fit
- excellent: Answer indicates an exceptional fit
Optional signal template ID to use. When provided, the template configuration (question, answerType, weight, qualificationCriteria) will be used. The system always resolves to the latest active version of the template. Only the domain parameter is required when using a template.
uuidForce re-run of the signal analysis, skipping the cache. When set to true, a new signal will be created even if a cached result exists.
falseConnector configuration for signal generation
Controls how strictly Saber verifies answers before responding.
- strict: Only returns answers backed by verified sources (primary or trusted secondary sources). Returns null when information is unavailable.
- lenient: Allows logical inference and best-effort estimates when direct evidence is missing. Uses industry benchmarks, logical correlates, and quantitative metrics.
"strict"Value in
- "strict"
- "lenient"
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/companies/signals" \ -H "Content-Type: application/json" \ -d '{ "domain": "clay.com", "question": "What is Clay\'s main product offering?", "answerType": "open_text", "webhookUrl": "https://myapp.com/webhooks/signals" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "processing", "domain": "clay.com", "question": "What is Clay's main product offering?", "createdAt": "2024-01-15T10:30:00Z"}Create company signals in batch
DeprecatedSubmit multiple signals and domains to create signals using a Cartesian product pattern. Each signal is combined with each domain to create individual signals.
Two ways to create batch signals:
- Inline Questions: Define questions directly in the request for ad-hoc research without creating templates
- Using Templates (recommended for reusability): Reference pre-created templates by ID for consistent, reusable questions
Cartesian Product Logic:
- If you submit 2 templates and 3 domains, the system creates 6 signals (2 × 3)
- Sync mode (default): Maximum 100 resulting signals (templates × domains ≤ 100)
- Async mode (
async: true): Maximum 20,000 resulting signals (templates × domains ≤ 20,000)
Sync Mode (default):
- Returns inline results with individual signal statuses
- Maximum 100 signals per batch
- Returns 202 with
results[]array
Async Mode (async: true):
- For large batches up to 20,000 signals
- Returns immediately with a
batchIdfor tracking - Signals are processed in background chunks
- Returns 202 with
batchId,totalSignals,status: "accepted" - Poll
/v1/companies/signals/batches/status?domain=...for progress
Partial Failure Handling (sync mode):
- Individual signal failures don't block other signals from processing
- Each signal in the response includes its own status (accepted or failed)
- Returns 202 if at least one signal is scheduled successfully
- Returns 422 if all signals failed to be scheduled
Processing:
- All signals are processed asynchronously
- No guarantee of processing order
- Use the
/v1/companies/signals/syncendpoint (recommended) to retrieve results as they complete
Webhooks:
- Each signal in the batch can include a
webhookUrlto receive notifications on completion - Webhooks fire individually per signal as each one completes processing
- Each signal gets one logical delivery, retried on failure — dedupe HTTP requests on the
X-Idempotency-Keyheader - The delivery body is the signal object itself, with no event envelope — read its
status(completedorfailed) for the outcome. A Slack webhook URL receives a formatted Slack message instead - Deliveries are not signed
Caching Behavior:
- Signals are cached based on a hash of domain, question, answer type, verification mode, and output schema (if provided)
- If a matching cached result exists, the cached response is returned immediately and no webhook is sent
- To force fresh processing (and webhook delivery), set
forceRefresh: trueon individual signals
Automatic Summary Generation:
- Set
generateSummaryOnCompletetotrueto automatically generate summaries when all signals in the batch complete - Summaries are generated per domain (one summary per unique domain in the batch)
- Summary generation is triggered automatically once all signals for a domain have completed
- Use the
/v1/companies/signals/summariesendpoint to retrieve generated summaries
Credits: 2 credits per signal created. The batch expands every question across every company — 2 questions × 3 companies creates 6 signals and charges 12 credits. Cached results and failed runs are not charged.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Array of signals to create. Each signal will be combined with each domain using Cartesian product logic. You can either:
- Provide inline signal configuration with
questionand optional fields (quick ad-hoc research) - Use
templateIdto reference a pre-created template (recommended for reusability)
1 <= itemsArray of company domains to research. Each domain will be combined with each signal template using Cartesian product logic. The total resulting signals (len(signals) × len(domains)) must not exceed 100.
1 <= items <= 100Whether to automatically generate a summary when all signals in the batch are completed.
When set to true, a summary will be automatically generated for each unique domain in the batch
once all signals for that domain have completed processing.
falseWhen true, enables async processing with a higher limit of 20,000 signals.
Returns a batchId for tracking instead of inline results.
The response shape differs from sync mode — returns { batchId, submittedAt, totalSignals, status, async }.
Use /v1/companies/signals/batches/status?domain=... to poll for progress.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/companies/signals/batch" \ -H "Content-Type: application/json" \ -d '{ "signals": [ { "question": "What is their main product offering?", "answerType": "open_text", "weight": "important" }, { "question": "How many employees do they have?", "answerType": "number", "weight": "nice_to_have" }, { "question": "Are they venture-backed?", "answerType": "boolean", "weight": "important" } ], "domains": [ "acme.com", "techcorp.io" ], "generateSummaryOnComplete": false }'{ "batchId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "submittedAt": "2024-01-15T10:30:00Z", "totalSignals": 15000, "status": "accepted", "async": true}Create a contact signal synchronously
Deprecated⭐ This is the recommended way to create contact signals and get results instead of async + webhooks.
Creates a contact signal and waits synchronously for it to complete, returning the result in the same request. Works identically to the company signals sync endpoint but for contact-based signals.
Why Use the Sync Endpoint?
Advantages over async + webhooks:
- ✅ Get results immediately in one request
- ✅ No webhook hosting required
- ✅ No polling implementation needed
- ✅ Simpler integration
- ✅ Better for synchronous workflows
How It Works
- Send your signal creation request (same payload as regular POST /v1/contacts/signals)
- The endpoint creates the signal and polls for completion
- Returns the completed signal with results when processing finishes
- If timeout is reached, returns the latest status (processing)
Timeout Configuration
- Default timeout: 870 seconds (server-configured, applies when the header is absent)
- Max timeout: 870 seconds — higher values are clamped
- Custom timeout: Use
X-Sbr-Timeout-Secheader to set custom timeout (up to max) - Error on timeout: Use
X-Sbr-Timeout-Error: trueheader to return 408 on timeout instead of latest status
Response Codes
200 OK- Signal completed, or timeout reached with the still-processingsignal in the body (checkstatus)408 Request Timeout- Timeout reached (when X-Sbr-Timeout-Error: true)
Using with Templates
Use signalTemplateId instead of defining questions inline for standardized research:
{ "contactProfileUrl": "https://linkedin.com/in/johndoe", "signalTemplateId": "a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"}Templates let you reuse research questions, qualification criteria, and answer types across multiple contacts. Create templates via POST /v1/companies/signals/templates.
Credits
Each signal charges 2 credits. Repeat calls served from the cache do not consume additional credits, and failed runs are never charged — reserved credits are released.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Header Parameters
Custom timeout in seconds (max 870 — higher values are clamped). When absent, the server-configured default (870s) applies.
1 <= value <= 870If "true", returns 408 Request Timeout on timeout instead of 200 with the latest (still-processing) status
Value in
- "true"
- "false"
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
The contact profile URL to research (e.g., "https://linkedin.com/in/johndoe")
uri1 <= length <= 500The research question to ask about the contact
1 <= length <= 2000The expected format of the answer
"open_text"Value in
- "open_text"
- "number"
- "boolean"
- "list"
- "percentage"
- "currency"
- "url"
- "contacts"
- "contacts_generation"
- "contact_posts"
- "contact_engagements"
- "json_schema"
JSON Schema defining the expected output structure. Required when answerType is "json_schema". See CreateSignalRequest.outputSchema for full documentation.
Optional webhook URL to receive notifications when processing completes.
Webhooks are only sent for freshly processed signals — cached results do not trigger webhooks.
Set forceRefresh: true to bypass the cache and ensure webhook delivery.
urilength <= 2048The importance/weight of the signal
Value in
- "important"
- "nice_to_have"
- "not_important"
Qualification criteria mapping answer values based on answerType (same structure as company signals)
Optional signal template ID to use
uuidConnector configuration for signal generation
Controls how strictly Saber verifies answers before responding.
- strict: Only returns answers backed by verified sources (primary or trusted secondary sources). Returns null when information is unavailable.
- lenient: Allows logical inference and best-effort estimates when direct evidence is missing. Uses industry benchmarks, logical correlates, and quantitative metrics.
"strict"Value in
- "strict"
- "lenient"
Force re-run of the signal analysis, skipping the cache. When set to true, a new signal will be created even if a cached result exists.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/contacts/signals/sync" \ -H "X-Sbr-Timeout-Sec: 120" \ -H "X-Sbr-Timeout-Error: false" \ -H "Content-Type: application/json" \ -d '{ "contactProfileUrl": "https://linkedin.com/in/johndoe", "question": "What are this person\'s main professional interests?", "answerType": "open_text" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "completed", "contactProfileUrl": "https://linkedin.com/in/johndoe", "question": "What are this person's main professional interests?", "createdAt": "2024-01-15T10:30:00Z", "completedAt": "2024-01-15T10:32:15Z", "answer": { "type": "open_text", "openText": { "value": "Software engineering, AI/ML, and developer tools" } }, "confidence": 0.9}Retrieve all contact signals with optional filtering by LinkedIn URL, pagination and filtering. Results are sorted by creation date (latest first).
Note: For creating contact signals and getting results in one step, we recommend using the
/v1/contacts/signals/sync endpoint instead, which returns the result directly.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Query Parameters
Filter signals by contact profile URL (LinkedIn or other professional profile)
uriMaximum number of results per page
1 <= value <= 2525Number of results to skip for pagination
0 <= value0Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/contacts/signals?contactProfileUrl=https%3A%2F%2Flinkedin.com%2Fin%2Fjohndoe&limit=25&offset=0"{ "results": [ { "id": "string", "status": "processing", "companyId": "string", "question": "string", "answerType": "boolean", "createdAt": "2019-08-24T14:15:22Z", "signalType": "COMPANY", "domain": "string", "completedAt": "2019-08-24T14:15:22Z", "answer": { "type": "open_text", "openText": { "value": "string" } }, "answerStatus": "answered", "reasoning": "string", "confidence": 0, "sources": [ { "url": "http://example.com", "title": "string", "snippet": "string" } ], "metadata": { "companyName": "string", "processingTimeMs": 0, "connectors": { "salesNavigator": { "status": "ok", "reason": "rate_limited" } }, "linkedInContext": { "linkedInToolsUsed": true, "mode": "required", "capabilities": [ { "capability": "contact_search", "used": true, "rateLimited": true } ], "degraded": true } }, "error": "string", "errorCode": "LINKEDIN_RATE_LIMIT_EXCEEDED", "errorAction": "string", "retryable": true, "changeContext": { "changeType": "INITIAL", "changeDelta": {}, "previousSignalId": "string", "changedFields": [ "string" ], "addedFields": [ "string" ], "updatedFields": [ "string" ], "removedFields": [ "string" ] }, "verificationMode": "strict", "company": { "id": "string", "name": "string", "domain": "string", "industry": "string", "website": "string", "size": "string", "type": "string", "founded": 0, "city": "string", "state": "string", "countryCode": "string", "handle": "string", "linkedInId": 0, "linkedInUrl": "http://example.com", "linkedInFollowers": 0, "employeeCount": 0, "description": "string", "logoUrl": "http://example.com" } } ], "total": 0, "limit": 0, "offset": 0, "count": 0}Create a contact signal asynchronously
DeprecatedSubmit a LinkedIn URL and question to create a new research signal for an individual contact. The AI will analyze the contact's profile and provide a structured answer based on the specified answer type.
Contact signals work similarly to company signals but focus on individual contacts using their LinkedIn profile URLs.
When to Use This Endpoint
Use this endpoint for event-driven architectures where you need webhook notifications.
For simpler integrations, use the /v1/contacts/signals/sync endpoint (recommended) which returns results immediately.
Webhooks
Configure webhooks by including a webhookUrl parameter in your request.
What we deliver:
One logical delivery per signal, once it reaches a terminal state — retries
(below) mean your endpoint may see it as more than one HTTP request, all
carrying the same X-Idempotency-Key. The body is the signal object itself —
there is no event envelope and no event-type header, so read the body's
status (completed or failed) to tell the outcome. One exception: a
Slack webhook URL (https://hooks.slack.com/services/…) receives a formatted
Slack message instead of the raw signal object.
Webhook security:
Deliveries are not signed. Treat the payload as untrusted: use an unguessable
webhookUrl, and re-read the signal via GET /v1/contacts/signals/{signalId}
before acting on it. Each delivery carries an X-Idempotency-Key header you can
use to discard duplicates.
Webhook reliability:
- Deliveries that fail to connect, time out, or return 5xx are attempted up to 5 times in total with exponential backoff
- A 4xx response is treated as a permanent rejection and is not retried
- A
webhookUrlwhose host does not resolve in DNS is rejected without retry, so point it at a hostname that already resolves - Webhook requests timeout after 25 seconds
- Your endpoint should respond with 2xx status code
- A failed delivery never fails the signal: the answer is still produced, billed, and readable via the API
Using with Templates
Use signalTemplateId instead of defining questions inline for standardized research:
{ "contactProfileUrl": "https://linkedin.com/in/johndoe", "signalTemplateId": "a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "webhookUrl": "https://myapp.com/webhooks/signals"}Templates let you reuse research questions, qualification criteria, and answer types across multiple contacts. Create templates via POST /v1/companies/signals/templates.
Contact signals work similarly to company signals but focus on individual contacts using their LinkedIn profile URLs.
Credits
Each signal charges 2 credits. Repeat calls served from the cache do not consume additional credits, and failed runs are never charged — reserved credits are released.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
The contact profile URL to research (e.g., "https://linkedin.com/in/johndoe")
uri1 <= length <= 500The research question to ask about the contact
1 <= length <= 2000The expected format of the answer
"open_text"Value in
- "open_text"
- "number"
- "boolean"
- "list"
- "percentage"
- "currency"
- "url"
- "contacts"
- "contacts_generation"
- "contact_posts"
- "contact_engagements"
- "json_schema"
JSON Schema defining the expected output structure. Required when answerType is "json_schema". See CreateSignalRequest.outputSchema for full documentation.
Optional webhook URL to receive notifications when processing completes.
Webhooks are only sent for freshly processed signals — cached results do not trigger webhooks.
Set forceRefresh: true to bypass the cache and ensure webhook delivery.
urilength <= 2048The importance/weight of the signal
Value in
- "important"
- "nice_to_have"
- "not_important"
Qualification criteria mapping answer values based on answerType (same structure as company signals)
Optional signal template ID to use
uuidConnector configuration for signal generation
Controls how strictly Saber verifies answers before responding.
- strict: Only returns answers backed by verified sources (primary or trusted secondary sources). Returns null when information is unavailable.
- lenient: Allows logical inference and best-effort estimates when direct evidence is missing. Uses industry benchmarks, logical correlates, and quantitative metrics.
"strict"Value in
- "strict"
- "lenient"
Force re-run of the signal analysis, skipping the cache. When set to true, a new signal will be created even if a cached result exists.
falseResponse Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/contacts/signals" \ -H "Content-Type: application/json" \ -d '{ "contactProfileUrl": "https://linkedin.com/in/johndoe", "question": "What are this person\'s main professional interests?", "answerType": "open_text", "webhookUrl": "https://myapp.com/webhooks/signals" }'{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "processing", "contactProfileUrl": "https://linkedin.com/in/johndoe", "question": "What are this person's main professional interests?", "createdAt": "2024-01-15T10:30:00Z"}Retrieve the current status and results of a signal. If the signal is completed, the response will include the AI-generated answer, confidence score, and sources.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Path Parameters
The unique identifier of the signal (UUID format)
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/companies/signals/e45c1dc4-d422-4b51-956b-cb6d3ddaf250"{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "processing", "domain": "acme.com", "question": "What is Acme Corp's main business focus?", "createdAt": "2024-01-15T10:30:00Z"}Retrieve all signal executions that were triggered by a specific signal subscription.
Returns the same paginated response as GET /v1/companies/signals but filtered to a single subscription.
Results are sorted by creation date (latest first).
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Path Parameters
The UUID of the signal subscription
uuidQuery Parameters
Filter signals by company domain
Filter signals by company ID
Maximum number of results per page
1 <= value <= 2525Number of results to skip for pagination
0 <= value0Filter signals completed on or after this date (RFC3339 format)
date-timeFilter signals completed on or before this date (RFC3339 format)
date-timeFilter by signal status (can be specified multiple times)
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/companies/signals/subscriptions/a12b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d/logs?domain=acme.com&companyId=b23c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e&limit=25&offset=0&fromDate=2024-01-01T00%3A00%3A00Z&toDate=2024-12-31T23%3A59%3A59Z&status=completed"{ "results": [ { "id": "string", "status": "processing", "companyId": "string", "question": "string", "answerType": "boolean", "createdAt": "2019-08-24T14:15:22Z", "signalType": "COMPANY", "domain": "string", "completedAt": "2019-08-24T14:15:22Z", "answer": { "type": "open_text", "openText": { "value": "string" } }, "answerStatus": "answered", "reasoning": "string", "confidence": 0, "sources": [ { "url": "http://example.com", "title": "string", "snippet": "string" } ], "metadata": { "companyName": "string", "processingTimeMs": 0, "connectors": { "salesNavigator": { "status": "ok", "reason": "rate_limited" } }, "linkedInContext": { "linkedInToolsUsed": true, "mode": "required", "capabilities": [ { "capability": "contact_search", "used": true, "rateLimited": true } ], "degraded": true } }, "error": "string", "errorCode": "LINKEDIN_RATE_LIMIT_EXCEEDED", "errorAction": "string", "retryable": true, "changeContext": { "changeType": "INITIAL", "changeDelta": {}, "previousSignalId": "string", "changedFields": [ "string" ], "addedFields": [ "string" ], "updatedFields": [ "string" ], "removedFields": [ "string" ] }, "verificationMode": "strict", "company": { "id": "string", "name": "string", "domain": "string", "industry": "string", "website": "string", "size": "string", "type": "string", "founded": 0, "city": "string", "state": "string", "countryCode": "string", "handle": "string", "linkedInId": 0, "linkedInUrl": "http://example.com", "linkedInFollowers": 0, "employeeCount": 0, "description": "string", "logoUrl": "http://example.com" } } ], "total": 0, "limit": 0, "offset": 0, "count": 0}Retrieve the current status and results of a contact signal. If the signal is completed, the response will include the AI-generated answer, confidence score, and sources.
Authorization
ApiKeyAuth API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.
In: header
Path Parameters
The unique identifier of the contact signal (UUID format)
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/contacts/signals/e45c1dc4-d422-4b51-956b-cb6d3ddaf250"{ "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250", "status": "completed", "contactProfileUrl": "https://linkedin.com/in/johndoe", "question": "What are this person's main professional interests?", "createdAt": "2024-01-15T10:30:00Z", "completedAt": "2024-01-15T10:32:15Z", "answer": { "type": "open_text", "openText": { "value": "Software engineering, AI/ML, and developer tools" } }, "reasoning": "Based on LinkedIn profile analysis, this person regularly engages with content about software engineering and AI/ML topics.", "confidence": 0.9, "sources": [ { "url": "https://linkedin.com/in/johndoe", "title": "John Doe - LinkedIn", "snippet": "Passionate about building AI-powered developer tools..." } ]}