# Using Signals API

### Using the Signals API

Operations for managing and retrieving signals:

* **List signals** - Get all signals with filtering options
* **Get signal by ID** - Retrieve a specific signal's details
* **Contact research** - Deep-dive analysis of individual contacts
* **Contact search** - Find contacts at companies using LinkedIn Sales Navigator

For creating signals, see the **"Creating a Signal"** section which includes the recommended synchronous endpoints.

## List company signals

> 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.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"SignalDetailResponse":{"allOf":[{"$ref":"#/components/schemas/SignalResponse"},{"type":"object","properties":{"completedAt":{"type":"string","format":"date-time","description":"When the signal processing completed (only present when status is completed)"},"answer":{"oneOf":[{"$ref":"#/components/schemas/Answer"},{"type":"null"}],"description":"The AI-generated answer (null when status is not completed)"},"reasoning":{"type":"string","description":"Detailed reasoning for the answer (only present when status is completed)"},"confidence":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Confidence score for the answer (0-1, only present when status is completed)"},"sources":{"type":"array","description":"Sources used to generate the answer (only present when status is completed, maximum 20 sources)","maxItems":20,"items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"snippet":{"type":"string"}}}},"metadata":{"type":"object","description":"Additional metadata about the processing (only present when status is completed)","additionalProperties":true,"properties":{"companyName":{"type":"string","description":"Company name (for company signals)"},"processingTimeMs":{"type":"number","description":"Processing time in milliseconds"},"connectors":{"type":"object","description":"Connector status information","properties":{"salesNavigator":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"Connector status for this request"},"reason":{"type":"string","enum":["rate_limited","disconnected"],"description":"Reason for degraded status (only present when status is degraded)"}}}}},"linkedInContext":{"$ref":"#/components/schemas/LinkedInContext"}}},"error":{"type":"string","description":"Error message (only present when status is failed)"},"errorCode":{"type":"string","description":"Machine-readable error code (only present when status is failed)","enum":["LINKEDIN_RATE_LIMIT_EXCEEDED","LINKEDIN_CONNECTOR_REQUIRED","CONNECTOR_UNAVAILABLE","VALIDATION_ERROR"]},"errorAction":{"type":"string","description":"Suggested action to resolve the error (only present when status is failed)"},"changeContext":{"$ref":"#/components/schemas/ChangeContext","description":"Information about changes between signal versions (only present when status is completed and a previous version exists)"},"verificationMode":{"type":"string","description":"Verification mode used for signal generation","enum":["strict","lenient"]},"company":{"$ref":"#/components/schemas/CompanyFirmographics","description":"Company firmographic data (only present in webhook payloads for company signals)"}}}]},"SignalResponse":{"description":"Polymorphic signal response (company or contact)","oneOf":[{"$ref":"#/components/schemas/CompanySignalResponse"},{"$ref":"#/components/schemas/ContactSignalResponse"}],"discriminator":{"propertyName":"signalType","mapping":{"COMPANY":"#/components/schemas/CompanySignalResponse","CONTACT":"#/components/schemas/ContactSignalResponse"}}},"CompanySignalResponse":{"description":"Response for company signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["COMPANY"]},"domain":{"type":"string","description":"The domain that was researched"}},"required":["domain"]}]},"BaseSignalResponse":{"type":"object","description":"Base schema containing fields common to all signal types","properties":{"id":{"type":"string","description":"Unique identifier for the signal (UUID format)","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"signalType":{"type":"string","description":"Type of signal (company or contact)","enum":["COMPANY","CONTACT"]},"status":{"type":"string","description":"Current processing status of the signal","enum":["processing","completed","failed"]},"question":{"type":"string","description":"The research question"},"answerType":{"type":"string","description":"Answer type for this signal","enum":["boolean","number","percentage","currency","open_text","url","list","json_schema","contacts","contact_posts"]},"createdAt":{"type":"string","format":"date-time","description":"When the signal was created"}},"required":["id","signalType","status","question","createdAt"]},"ContactSignalResponse":{"description":"Response for contact signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["CONTACT"]},"contactProfileUrl":{"type":"string","description":"LinkedIn profile URL"}},"required":["contactProfileUrl"]}]},"Answer":{"description":"Discriminated union representing different answer types.\nThe 'type' field indicates which specific answer format is used.\n","oneOf":[{"type":"object","required":["type","open_text"],"properties":{"type":{"type":"string","enum":["open_text"],"description":"The answer type discriminator"},"open_text":{"$ref":"#/components/schemas/OpenTextAnswer"}}},{"type":"object","required":["type","number"],"properties":{"type":{"type":"string","enum":["number"],"description":"The answer type discriminator"},"number":{"$ref":"#/components/schemas/NumberAnswer"}}},{"type":"object","required":["type","boolean"],"properties":{"type":{"type":"string","enum":["boolean"],"description":"The answer type discriminator"},"boolean":{"$ref":"#/components/schemas/BooleanAnswer"}}},{"type":"object","required":["type","list"],"properties":{"type":{"type":"string","enum":["list"],"description":"The answer type discriminator"},"list":{"$ref":"#/components/schemas/ListAnswer"}}},{"type":"object","required":["type","percentage"],"properties":{"type":{"type":"string","enum":["percentage"],"description":"The answer type discriminator"},"percentage":{"$ref":"#/components/schemas/PercentageAnswer"}}},{"type":"object","required":["type","currency"],"properties":{"type":{"type":"string","enum":["currency"],"description":"The answer type discriminator"},"currency":{"$ref":"#/components/schemas/CurrencyAnswer"}}},{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["url"],"description":"The answer type discriminator"},"url":{"$ref":"#/components/schemas/URLAnswer"}}},{"type":"object","required":["type","contacts"],"properties":{"type":{"type":"string","enum":["contacts"],"description":"The answer type discriminator"},"contacts":{"$ref":"#/components/schemas/ContactsAnswer"}}},{"type":"object","required":["type","contactPosts"],"properties":{"type":{"type":"string","enum":["contact_posts"],"description":"The answer type discriminator"},"contactPosts":{"$ref":"#/components/schemas/ContactPostsAnswer"}}},{"type":"object","required":["type","contactEngagements"],"properties":{"type":{"type":"string","enum":["contact_engagements"],"description":"The answer type discriminator"},"contactEngagements":{"$ref":"#/components/schemas/ContactEngagementsAnswer"}}},{"type":"object","required":["type","jsonSchema"],"properties":{"type":{"type":"string","enum":["json_schema"],"description":"The answer type discriminator"},"jsonSchema":{"$ref":"#/components/schemas/JSONSchemaAnswer"}}}],"discriminator":{"propertyName":"type","mapping":{"open_text":"#/components/schemas/OpenTextAnswer","number":"#/components/schemas/NumberAnswer","boolean":"#/components/schemas/BooleanAnswer","list":"#/components/schemas/ListAnswer","percentage":"#/components/schemas/PercentageAnswer","currency":"#/components/schemas/CurrencyAnswer","url":"#/components/schemas/URLAnswer","contacts":"#/components/schemas/ContactsAnswer","contact_posts":"#/components/schemas/ContactPostsAnswer","contact_engagements":"#/components/schemas/ContactEngagementsAnswer","json_schema":"#/components/schemas/JSONSchemaAnswer"}}},"OpenTextAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","description":"Free-form text response"}}},"NumberAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"number","description":"Numeric value"}}},"BooleanAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"boolean","description":"True or false value"}}},"ListAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of string items (maximum 500 items)","maxItems":500,"items":{"type":"string"}}}},"PercentageAnswer":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number","description":"Percentage value"},"unit":{"type":"string","description":"Unit symbol (typically \"%\")"}}},"CurrencyAnswer":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"number","description":"Monetary amount"},"currency":{"type":"string","description":"ISO 4217 currency code"}}},"URLAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","format":"uri","description":"Valid URL string"}}},"ContactsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of contact objects with detailed information (maximum 100 contacts)","maxItems":100,"items":{"$ref":"#/components/schemas/Contact"}}}},"Contact":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Professional headline"},"summary":{"type":"string","description":"Professional summary"},"positions":{"type":"array","description":"Array of current and past positions","items":{"$ref":"#/components/schemas/ContactPosition"}},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Avatar/profile picture URL"},"location":{"type":"string","description":"Location of the contact"},"followerCount":{"type":"integer","description":"Number of followers on LinkedIn"},"education":{"type":"array","description":"Array of education entries","items":{"$ref":"#/components/schemas/Education"}}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Education":{"type":"object","required":["schoolName"],"properties":{"schoolName":{"type":"string","description":"Name of the educational institution"},"schoolUrl":{"type":"string","format":"uri","description":"LinkedIn URL of the school"},"degree":{"type":"string","description":"Degree obtained (e.g., \"Bachelor of Science\")"},"fieldOfStudy":{"type":"string","description":"Field of study (e.g., \"Computer Science\")"},"startDate":{"$ref":"#/components/schemas/ContactDate"},"endDate":{"description":"End date of education (null if currently enrolled)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactPostsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of post objects with detailed information","items":{"$ref":"#/components/schemas/Post"}}}},"Post":{"type":"object","required":["postUrl"],"properties":{"postUrl":{"type":"string","format":"uri","description":"LinkedIn post URL (identity key for tracking changes)"},"postText":{"type":"string","description":"Text content of the post"},"activityUrn":{"type":"string","description":"LinkedIn activity URN"},"publishedAt":{"type":"string","description":"Publication date"},"postType":{"type":"string","enum":["original","shared","repost"],"description":"Type of post"},"author":{"$ref":"#/components/schemas/PostAuthor"},"engagement":{"$ref":"#/components/schemas/PostEngagement"},"subject":{"type":"string","description":"AI-generated one-sentence summary of the post"}}},"PostAuthor":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Author's name"},"headline":{"type":"string","description":"Author's professional headline"},"profileUrl":{"type":"string","format":"uri","description":"Author's LinkedIn profile URL"}}},"PostEngagement":{"type":"object","properties":{"reactionCount":{"type":"integer","description":"Number of reactions"},"commentCount":{"type":"integer","description":"Number of comments"},"viewCount":{"type":"integer","description":"Number of views"},"topReactionTypes":{"type":"array","items":{"type":"string"},"description":"Most common reaction types"}}},"ContactEngagementsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of engagement objects (maximum 100 engagements)","maxItems":100,"items":{"$ref":"#/components/schemas/ContactEngagement"}}}},"ContactEngagement":{"type":"object","required":["postUrl","engagementType"],"properties":{"postUrl":{"type":"string","format":"uri","description":"URL of the LinkedIn post where the engagement occurred"},"postAuthor":{"$ref":"#/components/schemas/PostAuthor","description":"Author of the original post"},"postText":{"type":"string","description":"Snippet of post content"},"publishedAt":{"type":"string","format":"date-time","description":"ISO 8601 post publication timestamp"},"engagementType":{"type":"string","enum":["comment","reaction"],"description":"Type of engagement"},"engagementDate":{"type":"string","format":"date-time","description":"ISO 8601 engagement timestamp"},"commentText":{"type":"string","description":"Text of comment (if engagementType is comment)"},"reactionText":{"type":"string","description":"Reaction text extracted from LinkedIn header (e.g., \"John celebrates this\", \"John likes this\", \"John finds this insightful\")"}}},"JSONSchemaAnswer":{"type":"object","description":"The generated data conforming to the user-provided JSON Schema (payload at answer.jsonSchema directly)","additionalProperties":true},"LinkedInContext":{"type":"object","description":"LinkedIn capability usage context for a signal (only present when LinkedIn tools were involved)","required":["linkedInToolsUsed","mode","capabilities"],"properties":{"linkedInToolsUsed":{"type":"boolean","description":"Whether any LinkedIn tools were used"},"mode":{"type":"string","enum":["required","preferred","off"],"description":"LinkedIn connector mode used"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedInCapabilityStatus"},"description":"Per-capability status"},"degraded":{"type":"boolean","description":"Whether the signal was degraded due to LinkedIn limitations"}}},"LinkedInCapabilityStatus":{"type":"object","description":"Status of a single LinkedIn capability during signal generation","required":["capability","used"],"properties":{"capability":{"type":"string","enum":["contact_search","profile_enrichment","company_data","company_search","activity_tracking","post_search"],"description":"LinkedIn capability name"},"used":{"type":"boolean","description":"Whether this capability was used during signal generation"},"rateLimited":{"type":"boolean","description":"Whether this capability was rate-limited"}}},"ChangeContext":{"type":"object","description":"Information about changes between signal versions. The changeType field uses graduated change types: INITIAL for first versions, NO_CHANGE for identical or semantically equivalent results, and MINOR_CHANGE/MAJOR_CHANGE for graduated severity (replacing the legacy binary CHANGED type). Subscribers can filter broadly on changedFields (any event on a field) or precisely on addedFields/updatedFields/removedFields without inspecting the delta structure.\n","required":["changeType","changedFields","addedFields","updatedFields","removedFields"],"properties":{"changeType":{"$ref":"#/components/schemas/ChangeType"},"changeDelta":{"oneOf":[{"$ref":"#/components/schemas/ChangeDelta"},{"type":"null"}],"description":"Structured delta of the change (structure varies by answer type)"},"previousSignalId":{"type":["string","null"],"description":"ID of the previous signal version","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"changedFields":{"type":"array","items":{"type":"string"},"description":"Union of addedFields + updatedFields + removedFields. Use this to subscribe to any event on a field regardless of change type (e.g. changedFields.includes(\"headline\")). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"addedFields":{"type":"array","items":{"type":"string"},"description":"Fields where new values appeared (new contacts/posts, new certifications, etc.). Entity-level additions use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields where existing values were modified (headline changed, engagement updated, etc.). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"removedFields":{"type":"array","items":{"type":"string"},"description":"Fields where values were removed (contacts left, skills removed, etc.). Entity-level removals use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"}}},"ChangeType":{"type":"string","description":"Type of change detected between signal versions. INITIAL = first signal version, NO_CHANGE = identical or semantically equivalent to previous, MINOR_CHANGE = low-impact semantic change, CHANGED = significant change (legacy, pre-graduated), MAJOR_CHANGE = high-impact semantic change.\n","enum":["INITIAL","NO_CHANGE","CHANGED","MINOR_CHANGE","MAJOR_CHANGE"]},"ChangeDelta":{"type":"object","description":"Structured delta of the change between signal versions.\nThe structure varies based on the answer type:\n- LIST: {type: \"LIST\", added: string[], removed: string[]}\n- NUMBER: {type: \"NUMBER\", previous: number, current: number, change: number}\n- CURRENCY: {type: \"CURRENCY\", previous: number | object, current: number | object, currency?: string, change: number | string}\n- PERCENTAGE: {type: \"PERCENTAGE\", previous: number, current: number, unit: string, change: number}\n- BOOLEAN: {type: \"BOOLEAN\", previous: boolean, current: boolean}\n- GENERIC: {type: \"GENERIC\", previous: Answer | null, current: Answer | null}\n- SEMANTIC: {type: \"SEMANTIC\", previous: Answer | null, current: Answer | null, similarityScore: number}\n- SEMANTIC_LIST: {type: \"SEMANTIC_LIST\", added: string[], removed: string[], matched: [{previous: string, current: string, similarityScore: number}], similarityScore: number}\n- CONTACTS: {type: \"CONTACTS\", added: Contact[], removed: Contact[], updated: [{previous: Contact, current: Contact, fieldChanges: [...]}]}\n- CONTACT_POSTS: {type: \"CONTACT_POSTS\", added: Post[], removed: Post[], updated: [{previous: Post, current: Post, fieldChanges: [...], engagementGrowth?: EngagementGrowth}]}\n","additionalProperties":true},"CompanyFirmographics":{"type":"object","description":"Company firmographic and LinkedIn enrichment data included in webhook payloads","properties":{"id":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company domain"},"industry":{"type":"string","description":"Industry classification"},"website":{"type":"string","description":"Company website URL"},"size":{"type":"string","description":"Company size range"},"type":{"type":"string","description":"Company type (e.g. private, public)"},"founded":{"type":"integer","description":"Year the company was founded"},"city":{"type":"string","description":"City of headquarters"},"state":{"type":"string","description":"State or region of headquarters"},"countryCode":{"type":"string","description":"ISO country code"},"handle":{"type":"string","description":"Company handle/slug"},"linkedInId":{"type":"integer","description":"LinkedIn numeric company ID"},"linkedInUrl":{"type":"string","format":"uri","description":"LinkedIn company page URL"},"linkedInFollowers":{"type":"integer","description":"Number of LinkedIn followers"},"employeeCount":{"type":"integer","description":"Approximate employee count from LinkedIn"},"description":{"type":"string","description":"Company description"},"logoUrl":{"type":"string","format":"uri","description":"Company logo URL"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/companies/signals":{"get":{"summary":"List company signals","description":"Retrieve all signals with optional filtering by domain or companyId, pagination and filtering.\nResults are sorted by creation date (latest first).\n\n**Note:** For creating signals and getting results in one step, we recommend using the\n`/v1/companies/signals/sync` endpoint instead, which returns the result directly.\n","operationId":"listSignals","tags":["Using Signals API"],"parameters":[{"name":"domain","in":"query","required":false,"description":"Filter signals by company domain (e.g., \"acme.com\")","schema":{"type":"string","pattern":"^[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])?)*$"}},{"name":"companyId","in":"query","required":false,"description":"Filter signals by company ID","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum number of results per page","schema":{"type":"integer","minimum":1,"maximum":25,"default":25}},{"name":"offset","in":"query","description":"Number of results to skip for pagination","schema":{"type":"integer","minimum":0,"default":0}},{"name":"fromDate","in":"query","description":"Filter signals completed on or after this date (RFC3339 format)","schema":{"type":"string","format":"date-time"}},{"name":"toDate","in":"query","description":"Filter signals completed on or before this date (RFC3339 format)","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","description":"Filter by signal status (can be specified multiple times for multiple statuses)","schema":{"type":"array","items":{"type":"string","enum":["processing","completed","failed"]}},"style":"form","explode":true},{"name":"subscriptionId","in":"query","required":false,"description":"Filter signals by subscription ID (UUID of the signal subscription that triggered execution)","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Signals retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","description":"Array of signal detail responses","items":{"$ref":"#/components/schemas/SignalDetailResponse"}},"total":{"type":"integer","description":"Total number of signals matching the filters"},"limit":{"type":"integer","description":"Maximum results per page"},"offset":{"type":"integer","description":"Number of results skipped"},"count":{"type":"integer","description":"Number of results in this response"}},"required":["results","total","limit","offset","count"]}}}},"400":{"description":"Bad Request - Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## List signal executions for a subscription

> 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).<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"SignalDetailResponse":{"allOf":[{"$ref":"#/components/schemas/SignalResponse"},{"type":"object","properties":{"completedAt":{"type":"string","format":"date-time","description":"When the signal processing completed (only present when status is completed)"},"answer":{"oneOf":[{"$ref":"#/components/schemas/Answer"},{"type":"null"}],"description":"The AI-generated answer (null when status is not completed)"},"reasoning":{"type":"string","description":"Detailed reasoning for the answer (only present when status is completed)"},"confidence":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Confidence score for the answer (0-1, only present when status is completed)"},"sources":{"type":"array","description":"Sources used to generate the answer (only present when status is completed, maximum 20 sources)","maxItems":20,"items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"snippet":{"type":"string"}}}},"metadata":{"type":"object","description":"Additional metadata about the processing (only present when status is completed)","additionalProperties":true,"properties":{"companyName":{"type":"string","description":"Company name (for company signals)"},"processingTimeMs":{"type":"number","description":"Processing time in milliseconds"},"connectors":{"type":"object","description":"Connector status information","properties":{"salesNavigator":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"Connector status for this request"},"reason":{"type":"string","enum":["rate_limited","disconnected"],"description":"Reason for degraded status (only present when status is degraded)"}}}}},"linkedInContext":{"$ref":"#/components/schemas/LinkedInContext"}}},"error":{"type":"string","description":"Error message (only present when status is failed)"},"errorCode":{"type":"string","description":"Machine-readable error code (only present when status is failed)","enum":["LINKEDIN_RATE_LIMIT_EXCEEDED","LINKEDIN_CONNECTOR_REQUIRED","CONNECTOR_UNAVAILABLE","VALIDATION_ERROR"]},"errorAction":{"type":"string","description":"Suggested action to resolve the error (only present when status is failed)"},"changeContext":{"$ref":"#/components/schemas/ChangeContext","description":"Information about changes between signal versions (only present when status is completed and a previous version exists)"},"verificationMode":{"type":"string","description":"Verification mode used for signal generation","enum":["strict","lenient"]},"company":{"$ref":"#/components/schemas/CompanyFirmographics","description":"Company firmographic data (only present in webhook payloads for company signals)"}}}]},"SignalResponse":{"description":"Polymorphic signal response (company or contact)","oneOf":[{"$ref":"#/components/schemas/CompanySignalResponse"},{"$ref":"#/components/schemas/ContactSignalResponse"}],"discriminator":{"propertyName":"signalType","mapping":{"COMPANY":"#/components/schemas/CompanySignalResponse","CONTACT":"#/components/schemas/ContactSignalResponse"}}},"CompanySignalResponse":{"description":"Response for company signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["COMPANY"]},"domain":{"type":"string","description":"The domain that was researched"}},"required":["domain"]}]},"BaseSignalResponse":{"type":"object","description":"Base schema containing fields common to all signal types","properties":{"id":{"type":"string","description":"Unique identifier for the signal (UUID format)","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"signalType":{"type":"string","description":"Type of signal (company or contact)","enum":["COMPANY","CONTACT"]},"status":{"type":"string","description":"Current processing status of the signal","enum":["processing","completed","failed"]},"question":{"type":"string","description":"The research question"},"answerType":{"type":"string","description":"Answer type for this signal","enum":["boolean","number","percentage","currency","open_text","url","list","json_schema","contacts","contact_posts"]},"createdAt":{"type":"string","format":"date-time","description":"When the signal was created"}},"required":["id","signalType","status","question","createdAt"]},"ContactSignalResponse":{"description":"Response for contact signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["CONTACT"]},"contactProfileUrl":{"type":"string","description":"LinkedIn profile URL"}},"required":["contactProfileUrl"]}]},"Answer":{"description":"Discriminated union representing different answer types.\nThe 'type' field indicates which specific answer format is used.\n","oneOf":[{"type":"object","required":["type","open_text"],"properties":{"type":{"type":"string","enum":["open_text"],"description":"The answer type discriminator"},"open_text":{"$ref":"#/components/schemas/OpenTextAnswer"}}},{"type":"object","required":["type","number"],"properties":{"type":{"type":"string","enum":["number"],"description":"The answer type discriminator"},"number":{"$ref":"#/components/schemas/NumberAnswer"}}},{"type":"object","required":["type","boolean"],"properties":{"type":{"type":"string","enum":["boolean"],"description":"The answer type discriminator"},"boolean":{"$ref":"#/components/schemas/BooleanAnswer"}}},{"type":"object","required":["type","list"],"properties":{"type":{"type":"string","enum":["list"],"description":"The answer type discriminator"},"list":{"$ref":"#/components/schemas/ListAnswer"}}},{"type":"object","required":["type","percentage"],"properties":{"type":{"type":"string","enum":["percentage"],"description":"The answer type discriminator"},"percentage":{"$ref":"#/components/schemas/PercentageAnswer"}}},{"type":"object","required":["type","currency"],"properties":{"type":{"type":"string","enum":["currency"],"description":"The answer type discriminator"},"currency":{"$ref":"#/components/schemas/CurrencyAnswer"}}},{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["url"],"description":"The answer type discriminator"},"url":{"$ref":"#/components/schemas/URLAnswer"}}},{"type":"object","required":["type","contacts"],"properties":{"type":{"type":"string","enum":["contacts"],"description":"The answer type discriminator"},"contacts":{"$ref":"#/components/schemas/ContactsAnswer"}}},{"type":"object","required":["type","contactPosts"],"properties":{"type":{"type":"string","enum":["contact_posts"],"description":"The answer type discriminator"},"contactPosts":{"$ref":"#/components/schemas/ContactPostsAnswer"}}},{"type":"object","required":["type","contactEngagements"],"properties":{"type":{"type":"string","enum":["contact_engagements"],"description":"The answer type discriminator"},"contactEngagements":{"$ref":"#/components/schemas/ContactEngagementsAnswer"}}},{"type":"object","required":["type","jsonSchema"],"properties":{"type":{"type":"string","enum":["json_schema"],"description":"The answer type discriminator"},"jsonSchema":{"$ref":"#/components/schemas/JSONSchemaAnswer"}}}],"discriminator":{"propertyName":"type","mapping":{"open_text":"#/components/schemas/OpenTextAnswer","number":"#/components/schemas/NumberAnswer","boolean":"#/components/schemas/BooleanAnswer","list":"#/components/schemas/ListAnswer","percentage":"#/components/schemas/PercentageAnswer","currency":"#/components/schemas/CurrencyAnswer","url":"#/components/schemas/URLAnswer","contacts":"#/components/schemas/ContactsAnswer","contact_posts":"#/components/schemas/ContactPostsAnswer","contact_engagements":"#/components/schemas/ContactEngagementsAnswer","json_schema":"#/components/schemas/JSONSchemaAnswer"}}},"OpenTextAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","description":"Free-form text response"}}},"NumberAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"number","description":"Numeric value"}}},"BooleanAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"boolean","description":"True or false value"}}},"ListAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of string items (maximum 500 items)","maxItems":500,"items":{"type":"string"}}}},"PercentageAnswer":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number","description":"Percentage value"},"unit":{"type":"string","description":"Unit symbol (typically \"%\")"}}},"CurrencyAnswer":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"number","description":"Monetary amount"},"currency":{"type":"string","description":"ISO 4217 currency code"}}},"URLAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","format":"uri","description":"Valid URL string"}}},"ContactsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of contact objects with detailed information (maximum 100 contacts)","maxItems":100,"items":{"$ref":"#/components/schemas/Contact"}}}},"Contact":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Professional headline"},"summary":{"type":"string","description":"Professional summary"},"positions":{"type":"array","description":"Array of current and past positions","items":{"$ref":"#/components/schemas/ContactPosition"}},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Avatar/profile picture URL"},"location":{"type":"string","description":"Location of the contact"},"followerCount":{"type":"integer","description":"Number of followers on LinkedIn"},"education":{"type":"array","description":"Array of education entries","items":{"$ref":"#/components/schemas/Education"}}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Education":{"type":"object","required":["schoolName"],"properties":{"schoolName":{"type":"string","description":"Name of the educational institution"},"schoolUrl":{"type":"string","format":"uri","description":"LinkedIn URL of the school"},"degree":{"type":"string","description":"Degree obtained (e.g., \"Bachelor of Science\")"},"fieldOfStudy":{"type":"string","description":"Field of study (e.g., \"Computer Science\")"},"startDate":{"$ref":"#/components/schemas/ContactDate"},"endDate":{"description":"End date of education (null if currently enrolled)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactPostsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of post objects with detailed information","items":{"$ref":"#/components/schemas/Post"}}}},"Post":{"type":"object","required":["postUrl"],"properties":{"postUrl":{"type":"string","format":"uri","description":"LinkedIn post URL (identity key for tracking changes)"},"postText":{"type":"string","description":"Text content of the post"},"activityUrn":{"type":"string","description":"LinkedIn activity URN"},"publishedAt":{"type":"string","description":"Publication date"},"postType":{"type":"string","enum":["original","shared","repost"],"description":"Type of post"},"author":{"$ref":"#/components/schemas/PostAuthor"},"engagement":{"$ref":"#/components/schemas/PostEngagement"},"subject":{"type":"string","description":"AI-generated one-sentence summary of the post"}}},"PostAuthor":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Author's name"},"headline":{"type":"string","description":"Author's professional headline"},"profileUrl":{"type":"string","format":"uri","description":"Author's LinkedIn profile URL"}}},"PostEngagement":{"type":"object","properties":{"reactionCount":{"type":"integer","description":"Number of reactions"},"commentCount":{"type":"integer","description":"Number of comments"},"viewCount":{"type":"integer","description":"Number of views"},"topReactionTypes":{"type":"array","items":{"type":"string"},"description":"Most common reaction types"}}},"ContactEngagementsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of engagement objects (maximum 100 engagements)","maxItems":100,"items":{"$ref":"#/components/schemas/ContactEngagement"}}}},"ContactEngagement":{"type":"object","required":["postUrl","engagementType"],"properties":{"postUrl":{"type":"string","format":"uri","description":"URL of the LinkedIn post where the engagement occurred"},"postAuthor":{"$ref":"#/components/schemas/PostAuthor","description":"Author of the original post"},"postText":{"type":"string","description":"Snippet of post content"},"publishedAt":{"type":"string","format":"date-time","description":"ISO 8601 post publication timestamp"},"engagementType":{"type":"string","enum":["comment","reaction"],"description":"Type of engagement"},"engagementDate":{"type":"string","format":"date-time","description":"ISO 8601 engagement timestamp"},"commentText":{"type":"string","description":"Text of comment (if engagementType is comment)"},"reactionText":{"type":"string","description":"Reaction text extracted from LinkedIn header (e.g., \"John celebrates this\", \"John likes this\", \"John finds this insightful\")"}}},"JSONSchemaAnswer":{"type":"object","description":"The generated data conforming to the user-provided JSON Schema (payload at answer.jsonSchema directly)","additionalProperties":true},"LinkedInContext":{"type":"object","description":"LinkedIn capability usage context for a signal (only present when LinkedIn tools were involved)","required":["linkedInToolsUsed","mode","capabilities"],"properties":{"linkedInToolsUsed":{"type":"boolean","description":"Whether any LinkedIn tools were used"},"mode":{"type":"string","enum":["required","preferred","off"],"description":"LinkedIn connector mode used"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedInCapabilityStatus"},"description":"Per-capability status"},"degraded":{"type":"boolean","description":"Whether the signal was degraded due to LinkedIn limitations"}}},"LinkedInCapabilityStatus":{"type":"object","description":"Status of a single LinkedIn capability during signal generation","required":["capability","used"],"properties":{"capability":{"type":"string","enum":["contact_search","profile_enrichment","company_data","company_search","activity_tracking","post_search"],"description":"LinkedIn capability name"},"used":{"type":"boolean","description":"Whether this capability was used during signal generation"},"rateLimited":{"type":"boolean","description":"Whether this capability was rate-limited"}}},"ChangeContext":{"type":"object","description":"Information about changes between signal versions. The changeType field uses graduated change types: INITIAL for first versions, NO_CHANGE for identical or semantically equivalent results, and MINOR_CHANGE/MAJOR_CHANGE for graduated severity (replacing the legacy binary CHANGED type). Subscribers can filter broadly on changedFields (any event on a field) or precisely on addedFields/updatedFields/removedFields without inspecting the delta structure.\n","required":["changeType","changedFields","addedFields","updatedFields","removedFields"],"properties":{"changeType":{"$ref":"#/components/schemas/ChangeType"},"changeDelta":{"oneOf":[{"$ref":"#/components/schemas/ChangeDelta"},{"type":"null"}],"description":"Structured delta of the change (structure varies by answer type)"},"previousSignalId":{"type":["string","null"],"description":"ID of the previous signal version","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"changedFields":{"type":"array","items":{"type":"string"},"description":"Union of addedFields + updatedFields + removedFields. Use this to subscribe to any event on a field regardless of change type (e.g. changedFields.includes(\"headline\")). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"addedFields":{"type":"array","items":{"type":"string"},"description":"Fields where new values appeared (new contacts/posts, new certifications, etc.). Entity-level additions use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields where existing values were modified (headline changed, engagement updated, etc.). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"removedFields":{"type":"array","items":{"type":"string"},"description":"Fields where values were removed (contacts left, skills removed, etc.). Entity-level removals use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"}}},"ChangeType":{"type":"string","description":"Type of change detected between signal versions. INITIAL = first signal version, NO_CHANGE = identical or semantically equivalent to previous, MINOR_CHANGE = low-impact semantic change, CHANGED = significant change (legacy, pre-graduated), MAJOR_CHANGE = high-impact semantic change.\n","enum":["INITIAL","NO_CHANGE","CHANGED","MINOR_CHANGE","MAJOR_CHANGE"]},"ChangeDelta":{"type":"object","description":"Structured delta of the change between signal versions.\nThe structure varies based on the answer type:\n- LIST: {type: \"LIST\", added: string[], removed: string[]}\n- NUMBER: {type: \"NUMBER\", previous: number, current: number, change: number}\n- CURRENCY: {type: \"CURRENCY\", previous: number | object, current: number | object, currency?: string, change: number | string}\n- PERCENTAGE: {type: \"PERCENTAGE\", previous: number, current: number, unit: string, change: number}\n- BOOLEAN: {type: \"BOOLEAN\", previous: boolean, current: boolean}\n- GENERIC: {type: \"GENERIC\", previous: Answer | null, current: Answer | null}\n- SEMANTIC: {type: \"SEMANTIC\", previous: Answer | null, current: Answer | null, similarityScore: number}\n- SEMANTIC_LIST: {type: \"SEMANTIC_LIST\", added: string[], removed: string[], matched: [{previous: string, current: string, similarityScore: number}], similarityScore: number}\n- CONTACTS: {type: \"CONTACTS\", added: Contact[], removed: Contact[], updated: [{previous: Contact, current: Contact, fieldChanges: [...]}]}\n- CONTACT_POSTS: {type: \"CONTACT_POSTS\", added: Post[], removed: Post[], updated: [{previous: Post, current: Post, fieldChanges: [...], engagementGrowth?: EngagementGrowth}]}\n","additionalProperties":true},"CompanyFirmographics":{"type":"object","description":"Company firmographic and LinkedIn enrichment data included in webhook payloads","properties":{"id":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company domain"},"industry":{"type":"string","description":"Industry classification"},"website":{"type":"string","description":"Company website URL"},"size":{"type":"string","description":"Company size range"},"type":{"type":"string","description":"Company type (e.g. private, public)"},"founded":{"type":"integer","description":"Year the company was founded"},"city":{"type":"string","description":"City of headquarters"},"state":{"type":"string","description":"State or region of headquarters"},"countryCode":{"type":"string","description":"ISO country code"},"handle":{"type":"string","description":"Company handle/slug"},"linkedInId":{"type":"integer","description":"LinkedIn numeric company ID"},"linkedInUrl":{"type":"string","format":"uri","description":"LinkedIn company page URL"},"linkedInFollowers":{"type":"integer","description":"Number of LinkedIn followers"},"employeeCount":{"type":"integer","description":"Approximate employee count from LinkedIn"},"description":{"type":"string","description":"Company description"},"logoUrl":{"type":"string","format":"uri","description":"Company logo URL"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/companies/signals/subscriptions/{subscriptionId}/logs":{"get":{"summary":"List signal executions for a subscription","description":"Retrieve all signal executions that were triggered by a specific signal subscription.\nReturns the same paginated response as `GET /v1/companies/signals` but filtered to a single subscription.\nResults are sorted by creation date (latest first).\n","operationId":"listSubscriptionLogs","tags":["Using Signals API"],"parameters":[{"name":"subscriptionId","in":"path","required":true,"description":"The UUID of the signal subscription","schema":{"type":"string","format":"uuid"}},{"name":"domain","in":"query","required":false,"description":"Filter signals by company domain","schema":{"type":"string"}},{"name":"companyId","in":"query","required":false,"description":"Filter signals by company ID","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum number of results per page","schema":{"type":"integer","minimum":1,"maximum":25,"default":25}},{"name":"offset","in":"query","description":"Number of results to skip for pagination","schema":{"type":"integer","minimum":0,"default":0}},{"name":"fromDate","in":"query","description":"Filter signals completed on or after this date (RFC3339 format)","schema":{"type":"string","format":"date-time"}},{"name":"toDate","in":"query","description":"Filter signals completed on or before this date (RFC3339 format)","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","description":"Filter by signal status (can be specified multiple times)","schema":{"type":"array","items":{"type":"string","enum":["processing","completed","failed"]}},"style":"form","explode":true}],"responses":{"200":{"description":"Subscription logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","description":"Array of signal detail responses","items":{"$ref":"#/components/schemas/SignalDetailResponse"}},"total":{"type":"integer","description":"Total number of signals matching the filters"},"limit":{"type":"integer","description":"Maximum results per page"},"offset":{"type":"integer","description":"Number of results skipped"},"count":{"type":"integer","description":"Number of results in this response"}},"required":["results","total","limit","offset","count"]}}}},"400":{"description":"Bad Request - Invalid subscription ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Subscription does not exist or does not belong to this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Get a company signal by ID

> 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.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"SignalDetailResponse":{"allOf":[{"$ref":"#/components/schemas/SignalResponse"},{"type":"object","properties":{"completedAt":{"type":"string","format":"date-time","description":"When the signal processing completed (only present when status is completed)"},"answer":{"oneOf":[{"$ref":"#/components/schemas/Answer"},{"type":"null"}],"description":"The AI-generated answer (null when status is not completed)"},"reasoning":{"type":"string","description":"Detailed reasoning for the answer (only present when status is completed)"},"confidence":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Confidence score for the answer (0-1, only present when status is completed)"},"sources":{"type":"array","description":"Sources used to generate the answer (only present when status is completed, maximum 20 sources)","maxItems":20,"items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"snippet":{"type":"string"}}}},"metadata":{"type":"object","description":"Additional metadata about the processing (only present when status is completed)","additionalProperties":true,"properties":{"companyName":{"type":"string","description":"Company name (for company signals)"},"processingTimeMs":{"type":"number","description":"Processing time in milliseconds"},"connectors":{"type":"object","description":"Connector status information","properties":{"salesNavigator":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"Connector status for this request"},"reason":{"type":"string","enum":["rate_limited","disconnected"],"description":"Reason for degraded status (only present when status is degraded)"}}}}},"linkedInContext":{"$ref":"#/components/schemas/LinkedInContext"}}},"error":{"type":"string","description":"Error message (only present when status is failed)"},"errorCode":{"type":"string","description":"Machine-readable error code (only present when status is failed)","enum":["LINKEDIN_RATE_LIMIT_EXCEEDED","LINKEDIN_CONNECTOR_REQUIRED","CONNECTOR_UNAVAILABLE","VALIDATION_ERROR"]},"errorAction":{"type":"string","description":"Suggested action to resolve the error (only present when status is failed)"},"changeContext":{"$ref":"#/components/schemas/ChangeContext","description":"Information about changes between signal versions (only present when status is completed and a previous version exists)"},"verificationMode":{"type":"string","description":"Verification mode used for signal generation","enum":["strict","lenient"]},"company":{"$ref":"#/components/schemas/CompanyFirmographics","description":"Company firmographic data (only present in webhook payloads for company signals)"}}}]},"SignalResponse":{"description":"Polymorphic signal response (company or contact)","oneOf":[{"$ref":"#/components/schemas/CompanySignalResponse"},{"$ref":"#/components/schemas/ContactSignalResponse"}],"discriminator":{"propertyName":"signalType","mapping":{"COMPANY":"#/components/schemas/CompanySignalResponse","CONTACT":"#/components/schemas/ContactSignalResponse"}}},"CompanySignalResponse":{"description":"Response for company signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["COMPANY"]},"domain":{"type":"string","description":"The domain that was researched"}},"required":["domain"]}]},"BaseSignalResponse":{"type":"object","description":"Base schema containing fields common to all signal types","properties":{"id":{"type":"string","description":"Unique identifier for the signal (UUID format)","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"signalType":{"type":"string","description":"Type of signal (company or contact)","enum":["COMPANY","CONTACT"]},"status":{"type":"string","description":"Current processing status of the signal","enum":["processing","completed","failed"]},"question":{"type":"string","description":"The research question"},"answerType":{"type":"string","description":"Answer type for this signal","enum":["boolean","number","percentage","currency","open_text","url","list","json_schema","contacts","contact_posts"]},"createdAt":{"type":"string","format":"date-time","description":"When the signal was created"}},"required":["id","signalType","status","question","createdAt"]},"ContactSignalResponse":{"description":"Response for contact signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["CONTACT"]},"contactProfileUrl":{"type":"string","description":"LinkedIn profile URL"}},"required":["contactProfileUrl"]}]},"Answer":{"description":"Discriminated union representing different answer types.\nThe 'type' field indicates which specific answer format is used.\n","oneOf":[{"type":"object","required":["type","open_text"],"properties":{"type":{"type":"string","enum":["open_text"],"description":"The answer type discriminator"},"open_text":{"$ref":"#/components/schemas/OpenTextAnswer"}}},{"type":"object","required":["type","number"],"properties":{"type":{"type":"string","enum":["number"],"description":"The answer type discriminator"},"number":{"$ref":"#/components/schemas/NumberAnswer"}}},{"type":"object","required":["type","boolean"],"properties":{"type":{"type":"string","enum":["boolean"],"description":"The answer type discriminator"},"boolean":{"$ref":"#/components/schemas/BooleanAnswer"}}},{"type":"object","required":["type","list"],"properties":{"type":{"type":"string","enum":["list"],"description":"The answer type discriminator"},"list":{"$ref":"#/components/schemas/ListAnswer"}}},{"type":"object","required":["type","percentage"],"properties":{"type":{"type":"string","enum":["percentage"],"description":"The answer type discriminator"},"percentage":{"$ref":"#/components/schemas/PercentageAnswer"}}},{"type":"object","required":["type","currency"],"properties":{"type":{"type":"string","enum":["currency"],"description":"The answer type discriminator"},"currency":{"$ref":"#/components/schemas/CurrencyAnswer"}}},{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["url"],"description":"The answer type discriminator"},"url":{"$ref":"#/components/schemas/URLAnswer"}}},{"type":"object","required":["type","contacts"],"properties":{"type":{"type":"string","enum":["contacts"],"description":"The answer type discriminator"},"contacts":{"$ref":"#/components/schemas/ContactsAnswer"}}},{"type":"object","required":["type","contactPosts"],"properties":{"type":{"type":"string","enum":["contact_posts"],"description":"The answer type discriminator"},"contactPosts":{"$ref":"#/components/schemas/ContactPostsAnswer"}}},{"type":"object","required":["type","contactEngagements"],"properties":{"type":{"type":"string","enum":["contact_engagements"],"description":"The answer type discriminator"},"contactEngagements":{"$ref":"#/components/schemas/ContactEngagementsAnswer"}}},{"type":"object","required":["type","jsonSchema"],"properties":{"type":{"type":"string","enum":["json_schema"],"description":"The answer type discriminator"},"jsonSchema":{"$ref":"#/components/schemas/JSONSchemaAnswer"}}}],"discriminator":{"propertyName":"type","mapping":{"open_text":"#/components/schemas/OpenTextAnswer","number":"#/components/schemas/NumberAnswer","boolean":"#/components/schemas/BooleanAnswer","list":"#/components/schemas/ListAnswer","percentage":"#/components/schemas/PercentageAnswer","currency":"#/components/schemas/CurrencyAnswer","url":"#/components/schemas/URLAnswer","contacts":"#/components/schemas/ContactsAnswer","contact_posts":"#/components/schemas/ContactPostsAnswer","contact_engagements":"#/components/schemas/ContactEngagementsAnswer","json_schema":"#/components/schemas/JSONSchemaAnswer"}}},"OpenTextAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","description":"Free-form text response"}}},"NumberAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"number","description":"Numeric value"}}},"BooleanAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"boolean","description":"True or false value"}}},"ListAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of string items (maximum 500 items)","maxItems":500,"items":{"type":"string"}}}},"PercentageAnswer":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number","description":"Percentage value"},"unit":{"type":"string","description":"Unit symbol (typically \"%\")"}}},"CurrencyAnswer":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"number","description":"Monetary amount"},"currency":{"type":"string","description":"ISO 4217 currency code"}}},"URLAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","format":"uri","description":"Valid URL string"}}},"ContactsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of contact objects with detailed information (maximum 100 contacts)","maxItems":100,"items":{"$ref":"#/components/schemas/Contact"}}}},"Contact":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Professional headline"},"summary":{"type":"string","description":"Professional summary"},"positions":{"type":"array","description":"Array of current and past positions","items":{"$ref":"#/components/schemas/ContactPosition"}},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Avatar/profile picture URL"},"location":{"type":"string","description":"Location of the contact"},"followerCount":{"type":"integer","description":"Number of followers on LinkedIn"},"education":{"type":"array","description":"Array of education entries","items":{"$ref":"#/components/schemas/Education"}}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Education":{"type":"object","required":["schoolName"],"properties":{"schoolName":{"type":"string","description":"Name of the educational institution"},"schoolUrl":{"type":"string","format":"uri","description":"LinkedIn URL of the school"},"degree":{"type":"string","description":"Degree obtained (e.g., \"Bachelor of Science\")"},"fieldOfStudy":{"type":"string","description":"Field of study (e.g., \"Computer Science\")"},"startDate":{"$ref":"#/components/schemas/ContactDate"},"endDate":{"description":"End date of education (null if currently enrolled)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactPostsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of post objects with detailed information","items":{"$ref":"#/components/schemas/Post"}}}},"Post":{"type":"object","required":["postUrl"],"properties":{"postUrl":{"type":"string","format":"uri","description":"LinkedIn post URL (identity key for tracking changes)"},"postText":{"type":"string","description":"Text content of the post"},"activityUrn":{"type":"string","description":"LinkedIn activity URN"},"publishedAt":{"type":"string","description":"Publication date"},"postType":{"type":"string","enum":["original","shared","repost"],"description":"Type of post"},"author":{"$ref":"#/components/schemas/PostAuthor"},"engagement":{"$ref":"#/components/schemas/PostEngagement"},"subject":{"type":"string","description":"AI-generated one-sentence summary of the post"}}},"PostAuthor":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Author's name"},"headline":{"type":"string","description":"Author's professional headline"},"profileUrl":{"type":"string","format":"uri","description":"Author's LinkedIn profile URL"}}},"PostEngagement":{"type":"object","properties":{"reactionCount":{"type":"integer","description":"Number of reactions"},"commentCount":{"type":"integer","description":"Number of comments"},"viewCount":{"type":"integer","description":"Number of views"},"topReactionTypes":{"type":"array","items":{"type":"string"},"description":"Most common reaction types"}}},"ContactEngagementsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of engagement objects (maximum 100 engagements)","maxItems":100,"items":{"$ref":"#/components/schemas/ContactEngagement"}}}},"ContactEngagement":{"type":"object","required":["postUrl","engagementType"],"properties":{"postUrl":{"type":"string","format":"uri","description":"URL of the LinkedIn post where the engagement occurred"},"postAuthor":{"$ref":"#/components/schemas/PostAuthor","description":"Author of the original post"},"postText":{"type":"string","description":"Snippet of post content"},"publishedAt":{"type":"string","format":"date-time","description":"ISO 8601 post publication timestamp"},"engagementType":{"type":"string","enum":["comment","reaction"],"description":"Type of engagement"},"engagementDate":{"type":"string","format":"date-time","description":"ISO 8601 engagement timestamp"},"commentText":{"type":"string","description":"Text of comment (if engagementType is comment)"},"reactionText":{"type":"string","description":"Reaction text extracted from LinkedIn header (e.g., \"John celebrates this\", \"John likes this\", \"John finds this insightful\")"}}},"JSONSchemaAnswer":{"type":"object","description":"The generated data conforming to the user-provided JSON Schema (payload at answer.jsonSchema directly)","additionalProperties":true},"LinkedInContext":{"type":"object","description":"LinkedIn capability usage context for a signal (only present when LinkedIn tools were involved)","required":["linkedInToolsUsed","mode","capabilities"],"properties":{"linkedInToolsUsed":{"type":"boolean","description":"Whether any LinkedIn tools were used"},"mode":{"type":"string","enum":["required","preferred","off"],"description":"LinkedIn connector mode used"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedInCapabilityStatus"},"description":"Per-capability status"},"degraded":{"type":"boolean","description":"Whether the signal was degraded due to LinkedIn limitations"}}},"LinkedInCapabilityStatus":{"type":"object","description":"Status of a single LinkedIn capability during signal generation","required":["capability","used"],"properties":{"capability":{"type":"string","enum":["contact_search","profile_enrichment","company_data","company_search","activity_tracking","post_search"],"description":"LinkedIn capability name"},"used":{"type":"boolean","description":"Whether this capability was used during signal generation"},"rateLimited":{"type":"boolean","description":"Whether this capability was rate-limited"}}},"ChangeContext":{"type":"object","description":"Information about changes between signal versions. The changeType field uses graduated change types: INITIAL for first versions, NO_CHANGE for identical or semantically equivalent results, and MINOR_CHANGE/MAJOR_CHANGE for graduated severity (replacing the legacy binary CHANGED type). Subscribers can filter broadly on changedFields (any event on a field) or precisely on addedFields/updatedFields/removedFields without inspecting the delta structure.\n","required":["changeType","changedFields","addedFields","updatedFields","removedFields"],"properties":{"changeType":{"$ref":"#/components/schemas/ChangeType"},"changeDelta":{"oneOf":[{"$ref":"#/components/schemas/ChangeDelta"},{"type":"null"}],"description":"Structured delta of the change (structure varies by answer type)"},"previousSignalId":{"type":["string","null"],"description":"ID of the previous signal version","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"changedFields":{"type":"array","items":{"type":"string"},"description":"Union of addedFields + updatedFields + removedFields. Use this to subscribe to any event on a field regardless of change type (e.g. changedFields.includes(\"headline\")). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"addedFields":{"type":"array","items":{"type":"string"},"description":"Fields where new values appeared (new contacts/posts, new certifications, etc.). Entity-level additions use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields where existing values were modified (headline changed, engagement updated, etc.). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"removedFields":{"type":"array","items":{"type":"string"},"description":"Fields where values were removed (contacts left, skills removed, etc.). Entity-level removals use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"}}},"ChangeType":{"type":"string","description":"Type of change detected between signal versions. INITIAL = first signal version, NO_CHANGE = identical or semantically equivalent to previous, MINOR_CHANGE = low-impact semantic change, CHANGED = significant change (legacy, pre-graduated), MAJOR_CHANGE = high-impact semantic change.\n","enum":["INITIAL","NO_CHANGE","CHANGED","MINOR_CHANGE","MAJOR_CHANGE"]},"ChangeDelta":{"type":"object","description":"Structured delta of the change between signal versions.\nThe structure varies based on the answer type:\n- LIST: {type: \"LIST\", added: string[], removed: string[]}\n- NUMBER: {type: \"NUMBER\", previous: number, current: number, change: number}\n- CURRENCY: {type: \"CURRENCY\", previous: number | object, current: number | object, currency?: string, change: number | string}\n- PERCENTAGE: {type: \"PERCENTAGE\", previous: number, current: number, unit: string, change: number}\n- BOOLEAN: {type: \"BOOLEAN\", previous: boolean, current: boolean}\n- GENERIC: {type: \"GENERIC\", previous: Answer | null, current: Answer | null}\n- SEMANTIC: {type: \"SEMANTIC\", previous: Answer | null, current: Answer | null, similarityScore: number}\n- SEMANTIC_LIST: {type: \"SEMANTIC_LIST\", added: string[], removed: string[], matched: [{previous: string, current: string, similarityScore: number}], similarityScore: number}\n- CONTACTS: {type: \"CONTACTS\", added: Contact[], removed: Contact[], updated: [{previous: Contact, current: Contact, fieldChanges: [...]}]}\n- CONTACT_POSTS: {type: \"CONTACT_POSTS\", added: Post[], removed: Post[], updated: [{previous: Post, current: Post, fieldChanges: [...], engagementGrowth?: EngagementGrowth}]}\n","additionalProperties":true},"CompanyFirmographics":{"type":"object","description":"Company firmographic and LinkedIn enrichment data included in webhook payloads","properties":{"id":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company domain"},"industry":{"type":"string","description":"Industry classification"},"website":{"type":"string","description":"Company website URL"},"size":{"type":"string","description":"Company size range"},"type":{"type":"string","description":"Company type (e.g. private, public)"},"founded":{"type":"integer","description":"Year the company was founded"},"city":{"type":"string","description":"City of headquarters"},"state":{"type":"string","description":"State or region of headquarters"},"countryCode":{"type":"string","description":"ISO country code"},"handle":{"type":"string","description":"Company handle/slug"},"linkedInId":{"type":"integer","description":"LinkedIn numeric company ID"},"linkedInUrl":{"type":"string","format":"uri","description":"LinkedIn company page URL"},"linkedInFollowers":{"type":"integer","description":"Number of LinkedIn followers"},"employeeCount":{"type":"integer","description":"Approximate employee count from LinkedIn"},"description":{"type":"string","description":"Company description"},"logoUrl":{"type":"string","format":"uri","description":"Company logo URL"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/companies/signals/{signalId}":{"get":{"summary":"Get a company signal by ID","description":"Retrieve the current status and results of a signal. If the signal is completed,\nthe response will include the AI-generated answer, confidence score, and sources.\n","operationId":"getSignal","tags":["Using Signals API"],"parameters":[{"name":"signalId","in":"path","required":true,"description":"The unique identifier of the signal (UUID format)","schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"responses":{"200":{"description":"Signal retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalDetailResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Signal not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Get contact research by external ID

> Retrieve a contact research request by external ID and external source. This endpoint allows you\
> to look up contact research requests using identifiers from external systems (e.g., HubSpot contact ID).<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"ContactResearchDetailResponse":{"allOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the contact research request"},"status":{"type":"string","description":"Current processing status of the contact research","enum":["processing","completed","failed"]},"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"companyName":{"type":"string","description":"Company name"},"companyDomain":{"type":"string","description":"Company domain"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the research request was created"}},"required":["id","status","firstName","lastName","companyName","companyDomain","createdAt"]},{"type":"object","properties":{"contactProfileUrl":{"type":"string","description":"Contact profile URL if provided (e.g., LinkedIn or other professional profile)"},"jobTitle":{"type":"string","description":"Job title - prioritizes the title found during research (profile.currentRole), falls back to the title provided in the request if research didn't find one"},"profile":{"type":"object","description":"AI-generated profile analysis (only present when status is \"completed\")","properties":{"summary":{"type":"string","description":"Professional summary"},"currentRole":{"type":"string","description":"Current job title"},"currentCompany":{"type":"string","description":"Current company"},"location":{"type":"string","description":"Professional location"},"experience":{"type":"array","description":"Work experience history","items":{"type":"object","properties":{"title":{"type":"string"},"company":{"type":"string"},"duration":{"type":"string"}}}}}},"communicationStyle":{"type":"object","description":"Preferred communication style (only present when status is \"completed\")","properties":{"preference":{"type":"string"}}},"interests":{"type":"array","description":"Professional interests and topics (only present when status is \"completed\")","items":{"type":"string"}},"challenges":{"type":"array","description":"Potential challenges or pain points (only present when status is \"completed\")","items":{"type":"string"}},"linkedInActivity":{"type":"object","description":"Recent LinkedIn activity analysis (only present when status is \"completed\")","properties":{"postingFrequency":{"type":"string"},"engagementLevel":{"type":"string"},"lastActivityDate":{"type":"string","format":"date-time"}}},"error":{"type":"string","description":"Error message if status is \"failed\""},"completedAt":{"type":"string","format":"date-time","description":"Timestamp when the research completed (success or failure)"}}}]},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/contacts/research":{"get":{"summary":"Get contact research by external ID","description":"Retrieve a contact research request by external ID and external source. This endpoint allows you\nto look up contact research requests using identifiers from external systems (e.g., HubSpot contact ID).\n","operationId":"getContactResearchByExternalID","tags":["Using Signals API"],"parameters":[{"name":"externalId","in":"query","required":true,"description":"The external identifier of the contact research request (e.g., HubSpot contact ID)","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"externalSource","in":"query","required":true,"description":"The source system that provided the external ID (e.g., \"hubspot\")","schema":{"type":"string","minLength":1,"maxLength":50}}],"responses":{"200":{"description":"Contact research retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactResearchDetailResponse"}}}},"400":{"description":"Bad Request - Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Contact research not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity - Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Start a contact research job

> Submit contact details to create a new contact research request. The AI will gather information\
> from LinkedIn, email services, and other data sources to provide comprehensive contact insights.\
> \
> The research will be processed asynchronously. Use the returned contact research ID to check status\
> via the GET endpoint, or configure a webhook to receive completion notifications.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"CreateContactResearchRequest":{"type":"object","required":["firstName","lastName","companyName","companyDomain"],"properties":{"firstName":{"type":"string","description":"First name of the contact","minLength":1,"maxLength":100},"lastName":{"type":"string","description":"Last name of the contact","minLength":1,"maxLength":100},"companyName":{"type":"string","description":"Name of the contact's company","minLength":1,"maxLength":200},"companyDomain":{"type":"string","description":"Company domain (e.g., \"acme.com\")","pattern":"^[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])?)*$","minLength":1,"maxLength":253},"contactProfileUrl":{"type":"string","format":"uri","description":"Contact profile URL of the contact (e.g., LinkedIn or other professional profile, optional)","maxLength":500},"linkedInSalesNavigatorUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL of the contact (optional)","maxLength":500},"jobTitle":{"type":"string","description":"Job title of the contact (optional)","minLength":1,"maxLength":200},"webhookUrl":{"type":"string","format":"uri","description":"Optional webhook URL to receive notifications when processing completes","maxLength":2048}},"additionalProperties":false},"ContactResearchResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the contact research request"},"status":{"type":"string","description":"Current processing status of the contact research","enum":["processing","completed","failed"]},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the research request was created"}},"required":["id","status","createdAt"]},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/contacts/research":{"post":{"summary":"Start a contact research job","description":"Submit contact details to create a new contact research request. The AI will gather information\nfrom LinkedIn, email services, and other data sources to provide comprehensive contact insights.\n\nThe research will be processed asynchronously. Use the returned contact research ID to check status\nvia the GET endpoint, or configure a webhook to receive completion notifications.\n","operationId":"createContactResearch","tags":["Using Signals API"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactResearchRequest"}}}},"responses":{"201":{"description":"Contact research request created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactResearchResponse"}}}},"400":{"description":"Bad Request - Malformed request body (invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity - Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests - Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Get contact research by ID

> Retrieve a contact research request by ID, including its status and results if completed.\
> This endpoint returns the current state of the research request.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"ContactResearchDetailResponse":{"allOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the contact research request"},"status":{"type":"string","description":"Current processing status of the contact research","enum":["processing","completed","failed"]},"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"companyName":{"type":"string","description":"Company name"},"companyDomain":{"type":"string","description":"Company domain"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the research request was created"}},"required":["id","status","firstName","lastName","companyName","companyDomain","createdAt"]},{"type":"object","properties":{"contactProfileUrl":{"type":"string","description":"Contact profile URL if provided (e.g., LinkedIn or other professional profile)"},"jobTitle":{"type":"string","description":"Job title - prioritizes the title found during research (profile.currentRole), falls back to the title provided in the request if research didn't find one"},"profile":{"type":"object","description":"AI-generated profile analysis (only present when status is \"completed\")","properties":{"summary":{"type":"string","description":"Professional summary"},"currentRole":{"type":"string","description":"Current job title"},"currentCompany":{"type":"string","description":"Current company"},"location":{"type":"string","description":"Professional location"},"experience":{"type":"array","description":"Work experience history","items":{"type":"object","properties":{"title":{"type":"string"},"company":{"type":"string"},"duration":{"type":"string"}}}}}},"communicationStyle":{"type":"object","description":"Preferred communication style (only present when status is \"completed\")","properties":{"preference":{"type":"string"}}},"interests":{"type":"array","description":"Professional interests and topics (only present when status is \"completed\")","items":{"type":"string"}},"challenges":{"type":"array","description":"Potential challenges or pain points (only present when status is \"completed\")","items":{"type":"string"}},"linkedInActivity":{"type":"object","description":"Recent LinkedIn activity analysis (only present when status is \"completed\")","properties":{"postingFrequency":{"type":"string"},"engagementLevel":{"type":"string"},"lastActivityDate":{"type":"string","format":"date-time"}}},"error":{"type":"string","description":"Error message if status is \"failed\""},"completedAt":{"type":"string","format":"date-time","description":"Timestamp when the research completed (success or failure)"}}}]},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/contacts/research/{id}":{"get":{"summary":"Get contact research by ID","description":"Retrieve a contact research request by ID, including its status and results if completed.\nThis endpoint returns the current state of the research request.\n","operationId":"getContactResearch","tags":["Using Signals API"],"parameters":[{"name":"id","in":"path","required":true,"description":"The unique identifier of the contact research request","schema":{"type":"string"}}],"responses":{"200":{"description":"Contact research retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactResearchDetailResponse"}}}},"404":{"description":"Not Found - Contact research not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Search contacts with LinkedIn Sales Navigator

> Search for contacts using LinkedIn Sales Navigator. Optionally scoped to one or more companies\
> via companyLinkedInUrls. When multiple URLs are provided, each company is searched separately\
> and results are merged and deduplicated.\
> \
> \*\*Pagination:\*\* Use \`limit\` (default 25, max 100) and \`offset\` (default 0) in the request body\
> to page through results. The response includes \`total\`, \`limit\`, \`offset\`, and \`hasMore\`\
> to support cursor-free pagination.\
> \
> \*\*Requirements:\*\*\
> \- At least one search parameter must be provided: \`companyLinkedInUrls\`, \`firstName\`, \`lastName\`, \`jobTitles\`, \`keywords\`, \`countries\`, \`departments\`, or \`seniorityLevels\`.\
> \- LinkedIn Sales Navigator connection is required for the API key owner\
> \
> \*\*Response:\*\*\
> \- If Sales Navigator is not connected, returns \`salesNavConnected: false\` with empty contacts\
> \- If connected, returns matching contacts with profile information and pagination metadata<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"ContactSearchRequest":{"type":"object","additionalProperties":false,"anyOf":[{"required":["companyLinkedInUrls"]},{"required":["firstName"]},{"required":["lastName"]},{"required":["jobTitles"]},{"required":["keywords"]},{"required":["countries"]},{"required":["departments"]},{"required":["seniorityLevels"]}],"properties":{"companyLinkedInUrls":{"type":"array","items":{"type":"string","format":"uri"},"description":"LinkedIn company URLs to scope the search (note: plural — pass an array even for a single company). Supports multiple companies; results are merged and deduplicated. Omit to search across all companies.\n"},"firstName":{"type":"string","maxLength":100,"description":"First name of the contact to search for"},"lastName":{"type":"string","maxLength":100,"description":"Last name of the contact to search for"},"jobTitles":{"type":"array","items":{"type":"string","maxLength":200},"description":"Job titles to search for (plural — pass an array)"},"keywords":{"type":"string","maxLength":500,"description":"Keywords to search for in contact profiles (e.g., skills, technologies)"},"countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Za-z]{2}$"},"description":"Countries to filter contacts by location. Must be ISO 3166-1 alpha-2 codes (e.g., \"US\", \"GB\", \"DE\") — full country names are not accepted."},"departments":{"type":"array","items":{"type":"string","maxLength":40,"enum":["Accounting","Administrative","Arts and Design","Business Development","Community and Social Services","Consulting","Customer Success and Support","Education","Engineering","Entrepreneurship","Finance","Healthcare Services","Human Resources","Information Technology","Legal","Marketing","Media and Communication","Military and Protective Services","Operations","Product Management","Program and Project Management","Purchasing","Quality Assurance","Real Estate","Research","Sales"]},"description":"Department (function) filter using LinkedIn Sales Navigator taxonomy. Multiple values are OR'd together. Combined with other filters via AND. All values are treated as INCLUDED — exclusion is not currently supported.\n"},"seniorityLevels":{"type":"array","items":{"type":"string","maxLength":25,"enum":["Owner / Partner","CXO","Vice President","Director","Experienced Manager","Entry Level Manager","Strategic","Senior","Entry Level","In Training"]},"description":"Seniority level filter using LinkedIn Sales Navigator taxonomy. Multiple values are OR'd together. Combined with other filters via AND. All values are treated as INCLUDED — exclusion is not currently supported.\n"},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum number of contacts to return per page"},"offset":{"type":"integer","minimum":0,"default":0,"description":"Zero-based offset for pagination"}}},"ContactSearchResponse":{"type":"object","required":["items","total","limit","offset","hasMore","salesNavConnected"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ContactSearchResult"},"description":"Contacts matching the search on this page"},"total":{"type":"integer","description":"Total number of contacts matching the search (from LinkedIn)"},"limit":{"type":"integer","description":"Page size used for this request"},"offset":{"type":"integer","description":"Zero-based offset used for this request"},"hasMore":{"type":"boolean","description":"Whether more contacts are available beyond this page"},"salesNavConnected":{"type":"boolean","description":"Whether LinkedIn Sales Navigator is connected for the user"}}},"ContactSearchResult":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Headline/tagline from their profile"},"summary":{"type":"string","description":"Summary/about section from their profile"},"positions":{"type":"array","items":{"$ref":"#/components/schemas/ContactPosition"},"description":"Current positions held by the contact"},"role":{"type":"string","description":"Current job title/role"},"companyName":{"type":"string","description":"Current company name"},"tenureAtCompany":{"$ref":"#/components/schemas/Tenure"},"tenureAtPosition":{"$ref":"#/components/schemas/Tenure"},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Profile avatar URL"},"location":{"type":"string","description":"Geographic location"}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Tenure":{"type":"object","properties":{"years":{"type":"integer","description":"Number of years"},"months":{"type":"integer","description":"Number of months"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}},"RateLimitErrorResponse":{"type":"object","description":"Flat error envelope returned only by the global per-API-key rate-limit middleware (HTTP 429). All other errors — including 429s from per-route rate limiters — use the standard `ErrorResponse` envelope.\n","required":["statusCode","error","message"],"properties":{"statusCode":{"type":"integer"},"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"integer","description":"Seconds until the next request will be admitted."}}}}},"paths":{"/v1/contacts/search":{"post":{"summary":"Search contacts with LinkedIn Sales Navigator","description":"Search for contacts using LinkedIn Sales Navigator. Optionally scoped to one or more companies\nvia companyLinkedInUrls. When multiple URLs are provided, each company is searched separately\nand results are merged and deduplicated.\n\n**Pagination:** Use `limit` (default 25, max 100) and `offset` (default 0) in the request body\nto page through results. The response includes `total`, `limit`, `offset`, and `hasMore`\nto support cursor-free pagination.\n\n**Requirements:**\n- At least one search parameter must be provided: `companyLinkedInUrls`, `firstName`, `lastName`, `jobTitles`, `keywords`, `countries`, `departments`, or `seniorityLevels`.\n- LinkedIn Sales Navigator connection is required for the API key owner\n\n**Response:**\n- If Sales Navigator is not connected, returns `salesNavConnected: false` with empty contacts\n- If connected, returns matching contacts with profile information and pagination metadata\n","operationId":"searchContacts","tags":["Using Signals API"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactSearchRequest"}}}},"responses":{"200":{"description":"Contact search completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactSearchResponse"}}}},"400":{"description":"Bad Request - Malformed request body (invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity - Validation error (e.g., invalid department or seniority value, or company URL that cannot be resolved)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests - Global per-API-key rate limit exceeded. Uses the flat `RateLimitErrorResponse` envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## List contact signals

> 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.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"SignalDetailResponse":{"allOf":[{"$ref":"#/components/schemas/SignalResponse"},{"type":"object","properties":{"completedAt":{"type":"string","format":"date-time","description":"When the signal processing completed (only present when status is completed)"},"answer":{"oneOf":[{"$ref":"#/components/schemas/Answer"},{"type":"null"}],"description":"The AI-generated answer (null when status is not completed)"},"reasoning":{"type":"string","description":"Detailed reasoning for the answer (only present when status is completed)"},"confidence":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Confidence score for the answer (0-1, only present when status is completed)"},"sources":{"type":"array","description":"Sources used to generate the answer (only present when status is completed, maximum 20 sources)","maxItems":20,"items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"snippet":{"type":"string"}}}},"metadata":{"type":"object","description":"Additional metadata about the processing (only present when status is completed)","additionalProperties":true,"properties":{"companyName":{"type":"string","description":"Company name (for company signals)"},"processingTimeMs":{"type":"number","description":"Processing time in milliseconds"},"connectors":{"type":"object","description":"Connector status information","properties":{"salesNavigator":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"Connector status for this request"},"reason":{"type":"string","enum":["rate_limited","disconnected"],"description":"Reason for degraded status (only present when status is degraded)"}}}}},"linkedInContext":{"$ref":"#/components/schemas/LinkedInContext"}}},"error":{"type":"string","description":"Error message (only present when status is failed)"},"errorCode":{"type":"string","description":"Machine-readable error code (only present when status is failed)","enum":["LINKEDIN_RATE_LIMIT_EXCEEDED","LINKEDIN_CONNECTOR_REQUIRED","CONNECTOR_UNAVAILABLE","VALIDATION_ERROR"]},"errorAction":{"type":"string","description":"Suggested action to resolve the error (only present when status is failed)"},"changeContext":{"$ref":"#/components/schemas/ChangeContext","description":"Information about changes between signal versions (only present when status is completed and a previous version exists)"},"verificationMode":{"type":"string","description":"Verification mode used for signal generation","enum":["strict","lenient"]},"company":{"$ref":"#/components/schemas/CompanyFirmographics","description":"Company firmographic data (only present in webhook payloads for company signals)"}}}]},"SignalResponse":{"description":"Polymorphic signal response (company or contact)","oneOf":[{"$ref":"#/components/schemas/CompanySignalResponse"},{"$ref":"#/components/schemas/ContactSignalResponse"}],"discriminator":{"propertyName":"signalType","mapping":{"COMPANY":"#/components/schemas/CompanySignalResponse","CONTACT":"#/components/schemas/ContactSignalResponse"}}},"CompanySignalResponse":{"description":"Response for company signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["COMPANY"]},"domain":{"type":"string","description":"The domain that was researched"}},"required":["domain"]}]},"BaseSignalResponse":{"type":"object","description":"Base schema containing fields common to all signal types","properties":{"id":{"type":"string","description":"Unique identifier for the signal (UUID format)","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"signalType":{"type":"string","description":"Type of signal (company or contact)","enum":["COMPANY","CONTACT"]},"status":{"type":"string","description":"Current processing status of the signal","enum":["processing","completed","failed"]},"question":{"type":"string","description":"The research question"},"answerType":{"type":"string","description":"Answer type for this signal","enum":["boolean","number","percentage","currency","open_text","url","list","json_schema","contacts","contact_posts"]},"createdAt":{"type":"string","format":"date-time","description":"When the signal was created"}},"required":["id","signalType","status","question","createdAt"]},"ContactSignalResponse":{"description":"Response for contact signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["CONTACT"]},"contactProfileUrl":{"type":"string","description":"LinkedIn profile URL"}},"required":["contactProfileUrl"]}]},"Answer":{"description":"Discriminated union representing different answer types.\nThe 'type' field indicates which specific answer format is used.\n","oneOf":[{"type":"object","required":["type","open_text"],"properties":{"type":{"type":"string","enum":["open_text"],"description":"The answer type discriminator"},"open_text":{"$ref":"#/components/schemas/OpenTextAnswer"}}},{"type":"object","required":["type","number"],"properties":{"type":{"type":"string","enum":["number"],"description":"The answer type discriminator"},"number":{"$ref":"#/components/schemas/NumberAnswer"}}},{"type":"object","required":["type","boolean"],"properties":{"type":{"type":"string","enum":["boolean"],"description":"The answer type discriminator"},"boolean":{"$ref":"#/components/schemas/BooleanAnswer"}}},{"type":"object","required":["type","list"],"properties":{"type":{"type":"string","enum":["list"],"description":"The answer type discriminator"},"list":{"$ref":"#/components/schemas/ListAnswer"}}},{"type":"object","required":["type","percentage"],"properties":{"type":{"type":"string","enum":["percentage"],"description":"The answer type discriminator"},"percentage":{"$ref":"#/components/schemas/PercentageAnswer"}}},{"type":"object","required":["type","currency"],"properties":{"type":{"type":"string","enum":["currency"],"description":"The answer type discriminator"},"currency":{"$ref":"#/components/schemas/CurrencyAnswer"}}},{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["url"],"description":"The answer type discriminator"},"url":{"$ref":"#/components/schemas/URLAnswer"}}},{"type":"object","required":["type","contacts"],"properties":{"type":{"type":"string","enum":["contacts"],"description":"The answer type discriminator"},"contacts":{"$ref":"#/components/schemas/ContactsAnswer"}}},{"type":"object","required":["type","contactPosts"],"properties":{"type":{"type":"string","enum":["contact_posts"],"description":"The answer type discriminator"},"contactPosts":{"$ref":"#/components/schemas/ContactPostsAnswer"}}},{"type":"object","required":["type","contactEngagements"],"properties":{"type":{"type":"string","enum":["contact_engagements"],"description":"The answer type discriminator"},"contactEngagements":{"$ref":"#/components/schemas/ContactEngagementsAnswer"}}},{"type":"object","required":["type","jsonSchema"],"properties":{"type":{"type":"string","enum":["json_schema"],"description":"The answer type discriminator"},"jsonSchema":{"$ref":"#/components/schemas/JSONSchemaAnswer"}}}],"discriminator":{"propertyName":"type","mapping":{"open_text":"#/components/schemas/OpenTextAnswer","number":"#/components/schemas/NumberAnswer","boolean":"#/components/schemas/BooleanAnswer","list":"#/components/schemas/ListAnswer","percentage":"#/components/schemas/PercentageAnswer","currency":"#/components/schemas/CurrencyAnswer","url":"#/components/schemas/URLAnswer","contacts":"#/components/schemas/ContactsAnswer","contact_posts":"#/components/schemas/ContactPostsAnswer","contact_engagements":"#/components/schemas/ContactEngagementsAnswer","json_schema":"#/components/schemas/JSONSchemaAnswer"}}},"OpenTextAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","description":"Free-form text response"}}},"NumberAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"number","description":"Numeric value"}}},"BooleanAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"boolean","description":"True or false value"}}},"ListAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of string items (maximum 500 items)","maxItems":500,"items":{"type":"string"}}}},"PercentageAnswer":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number","description":"Percentage value"},"unit":{"type":"string","description":"Unit symbol (typically \"%\")"}}},"CurrencyAnswer":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"number","description":"Monetary amount"},"currency":{"type":"string","description":"ISO 4217 currency code"}}},"URLAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","format":"uri","description":"Valid URL string"}}},"ContactsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of contact objects with detailed information (maximum 100 contacts)","maxItems":100,"items":{"$ref":"#/components/schemas/Contact"}}}},"Contact":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Professional headline"},"summary":{"type":"string","description":"Professional summary"},"positions":{"type":"array","description":"Array of current and past positions","items":{"$ref":"#/components/schemas/ContactPosition"}},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Avatar/profile picture URL"},"location":{"type":"string","description":"Location of the contact"},"followerCount":{"type":"integer","description":"Number of followers on LinkedIn"},"education":{"type":"array","description":"Array of education entries","items":{"$ref":"#/components/schemas/Education"}}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Education":{"type":"object","required":["schoolName"],"properties":{"schoolName":{"type":"string","description":"Name of the educational institution"},"schoolUrl":{"type":"string","format":"uri","description":"LinkedIn URL of the school"},"degree":{"type":"string","description":"Degree obtained (e.g., \"Bachelor of Science\")"},"fieldOfStudy":{"type":"string","description":"Field of study (e.g., \"Computer Science\")"},"startDate":{"$ref":"#/components/schemas/ContactDate"},"endDate":{"description":"End date of education (null if currently enrolled)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactPostsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of post objects with detailed information","items":{"$ref":"#/components/schemas/Post"}}}},"Post":{"type":"object","required":["postUrl"],"properties":{"postUrl":{"type":"string","format":"uri","description":"LinkedIn post URL (identity key for tracking changes)"},"postText":{"type":"string","description":"Text content of the post"},"activityUrn":{"type":"string","description":"LinkedIn activity URN"},"publishedAt":{"type":"string","description":"Publication date"},"postType":{"type":"string","enum":["original","shared","repost"],"description":"Type of post"},"author":{"$ref":"#/components/schemas/PostAuthor"},"engagement":{"$ref":"#/components/schemas/PostEngagement"},"subject":{"type":"string","description":"AI-generated one-sentence summary of the post"}}},"PostAuthor":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Author's name"},"headline":{"type":"string","description":"Author's professional headline"},"profileUrl":{"type":"string","format":"uri","description":"Author's LinkedIn profile URL"}}},"PostEngagement":{"type":"object","properties":{"reactionCount":{"type":"integer","description":"Number of reactions"},"commentCount":{"type":"integer","description":"Number of comments"},"viewCount":{"type":"integer","description":"Number of views"},"topReactionTypes":{"type":"array","items":{"type":"string"},"description":"Most common reaction types"}}},"ContactEngagementsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of engagement objects (maximum 100 engagements)","maxItems":100,"items":{"$ref":"#/components/schemas/ContactEngagement"}}}},"ContactEngagement":{"type":"object","required":["postUrl","engagementType"],"properties":{"postUrl":{"type":"string","format":"uri","description":"URL of the LinkedIn post where the engagement occurred"},"postAuthor":{"$ref":"#/components/schemas/PostAuthor","description":"Author of the original post"},"postText":{"type":"string","description":"Snippet of post content"},"publishedAt":{"type":"string","format":"date-time","description":"ISO 8601 post publication timestamp"},"engagementType":{"type":"string","enum":["comment","reaction"],"description":"Type of engagement"},"engagementDate":{"type":"string","format":"date-time","description":"ISO 8601 engagement timestamp"},"commentText":{"type":"string","description":"Text of comment (if engagementType is comment)"},"reactionText":{"type":"string","description":"Reaction text extracted from LinkedIn header (e.g., \"John celebrates this\", \"John likes this\", \"John finds this insightful\")"}}},"JSONSchemaAnswer":{"type":"object","description":"The generated data conforming to the user-provided JSON Schema (payload at answer.jsonSchema directly)","additionalProperties":true},"LinkedInContext":{"type":"object","description":"LinkedIn capability usage context for a signal (only present when LinkedIn tools were involved)","required":["linkedInToolsUsed","mode","capabilities"],"properties":{"linkedInToolsUsed":{"type":"boolean","description":"Whether any LinkedIn tools were used"},"mode":{"type":"string","enum":["required","preferred","off"],"description":"LinkedIn connector mode used"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedInCapabilityStatus"},"description":"Per-capability status"},"degraded":{"type":"boolean","description":"Whether the signal was degraded due to LinkedIn limitations"}}},"LinkedInCapabilityStatus":{"type":"object","description":"Status of a single LinkedIn capability during signal generation","required":["capability","used"],"properties":{"capability":{"type":"string","enum":["contact_search","profile_enrichment","company_data","company_search","activity_tracking","post_search"],"description":"LinkedIn capability name"},"used":{"type":"boolean","description":"Whether this capability was used during signal generation"},"rateLimited":{"type":"boolean","description":"Whether this capability was rate-limited"}}},"ChangeContext":{"type":"object","description":"Information about changes between signal versions. The changeType field uses graduated change types: INITIAL for first versions, NO_CHANGE for identical or semantically equivalent results, and MINOR_CHANGE/MAJOR_CHANGE for graduated severity (replacing the legacy binary CHANGED type). Subscribers can filter broadly on changedFields (any event on a field) or precisely on addedFields/updatedFields/removedFields without inspecting the delta structure.\n","required":["changeType","changedFields","addedFields","updatedFields","removedFields"],"properties":{"changeType":{"$ref":"#/components/schemas/ChangeType"},"changeDelta":{"oneOf":[{"$ref":"#/components/schemas/ChangeDelta"},{"type":"null"}],"description":"Structured delta of the change (structure varies by answer type)"},"previousSignalId":{"type":["string","null"],"description":"ID of the previous signal version","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"changedFields":{"type":"array","items":{"type":"string"},"description":"Union of addedFields + updatedFields + removedFields. Use this to subscribe to any event on a field regardless of change type (e.g. changedFields.includes(\"headline\")). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"addedFields":{"type":"array","items":{"type":"string"},"description":"Fields where new values appeared (new contacts/posts, new certifications, etc.). Entity-level additions use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields where existing values were modified (headline changed, engagement updated, etc.). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"removedFields":{"type":"array","items":{"type":"string"},"description":"Fields where values were removed (contacts left, skills removed, etc.). Entity-level removals use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"}}},"ChangeType":{"type":"string","description":"Type of change detected between signal versions. INITIAL = first signal version, NO_CHANGE = identical or semantically equivalent to previous, MINOR_CHANGE = low-impact semantic change, CHANGED = significant change (legacy, pre-graduated), MAJOR_CHANGE = high-impact semantic change.\n","enum":["INITIAL","NO_CHANGE","CHANGED","MINOR_CHANGE","MAJOR_CHANGE"]},"ChangeDelta":{"type":"object","description":"Structured delta of the change between signal versions.\nThe structure varies based on the answer type:\n- LIST: {type: \"LIST\", added: string[], removed: string[]}\n- NUMBER: {type: \"NUMBER\", previous: number, current: number, change: number}\n- CURRENCY: {type: \"CURRENCY\", previous: number | object, current: number | object, currency?: string, change: number | string}\n- PERCENTAGE: {type: \"PERCENTAGE\", previous: number, current: number, unit: string, change: number}\n- BOOLEAN: {type: \"BOOLEAN\", previous: boolean, current: boolean}\n- GENERIC: {type: \"GENERIC\", previous: Answer | null, current: Answer | null}\n- SEMANTIC: {type: \"SEMANTIC\", previous: Answer | null, current: Answer | null, similarityScore: number}\n- SEMANTIC_LIST: {type: \"SEMANTIC_LIST\", added: string[], removed: string[], matched: [{previous: string, current: string, similarityScore: number}], similarityScore: number}\n- CONTACTS: {type: \"CONTACTS\", added: Contact[], removed: Contact[], updated: [{previous: Contact, current: Contact, fieldChanges: [...]}]}\n- CONTACT_POSTS: {type: \"CONTACT_POSTS\", added: Post[], removed: Post[], updated: [{previous: Post, current: Post, fieldChanges: [...], engagementGrowth?: EngagementGrowth}]}\n","additionalProperties":true},"CompanyFirmographics":{"type":"object","description":"Company firmographic and LinkedIn enrichment data included in webhook payloads","properties":{"id":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company domain"},"industry":{"type":"string","description":"Industry classification"},"website":{"type":"string","description":"Company website URL"},"size":{"type":"string","description":"Company size range"},"type":{"type":"string","description":"Company type (e.g. private, public)"},"founded":{"type":"integer","description":"Year the company was founded"},"city":{"type":"string","description":"City of headquarters"},"state":{"type":"string","description":"State or region of headquarters"},"countryCode":{"type":"string","description":"ISO country code"},"handle":{"type":"string","description":"Company handle/slug"},"linkedInId":{"type":"integer","description":"LinkedIn numeric company ID"},"linkedInUrl":{"type":"string","format":"uri","description":"LinkedIn company page URL"},"linkedInFollowers":{"type":"integer","description":"Number of LinkedIn followers"},"employeeCount":{"type":"integer","description":"Approximate employee count from LinkedIn"},"description":{"type":"string","description":"Company description"},"logoUrl":{"type":"string","format":"uri","description":"Company logo URL"}}}}},"paths":{"/v1/contacts/signals":{"get":{"summary":"List contact signals","description":"Retrieve all contact signals with optional filtering by LinkedIn URL, pagination and filtering.\nResults are sorted by creation date (latest first).\n\n**Note:** For creating contact signals and getting results in one step, we recommend using the\n`/v1/contacts/signals/sync` endpoint instead, which returns the result directly.\n","operationId":"listContactSignals","tags":["Using Signals API"],"parameters":[{"name":"contactProfileUrl","in":"query","required":false,"description":"Filter signals by contact profile URL (LinkedIn or other professional profile)","schema":{"type":"string","format":"uri"}},{"name":"limit","in":"query","description":"Maximum number of results per page","schema":{"type":"integer","minimum":1,"maximum":25,"default":25}},{"name":"offset","in":"query","description":"Number of results to skip for pagination","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Contact signals retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/SignalDetailResponse"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"count":{"type":"integer"}}}}}},"400":{"$ref":"#/paths/~1v1~1companies~1signals/get/responses/400"},"401":{"$ref":"#/paths/~1v1~1companies~1signals/get/responses/401"},"500":{"$ref":"#/paths/~1v1~1companies~1signals/get/responses/500"}}}}}}
```

## Get a contact signal by ID

> 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.<br>

```json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"SignalDetailResponse":{"allOf":[{"$ref":"#/components/schemas/SignalResponse"},{"type":"object","properties":{"completedAt":{"type":"string","format":"date-time","description":"When the signal processing completed (only present when status is completed)"},"answer":{"oneOf":[{"$ref":"#/components/schemas/Answer"},{"type":"null"}],"description":"The AI-generated answer (null when status is not completed)"},"reasoning":{"type":"string","description":"Detailed reasoning for the answer (only present when status is completed)"},"confidence":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Confidence score for the answer (0-1, only present when status is completed)"},"sources":{"type":"array","description":"Sources used to generate the answer (only present when status is completed, maximum 20 sources)","maxItems":20,"items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"snippet":{"type":"string"}}}},"metadata":{"type":"object","description":"Additional metadata about the processing (only present when status is completed)","additionalProperties":true,"properties":{"companyName":{"type":"string","description":"Company name (for company signals)"},"processingTimeMs":{"type":"number","description":"Processing time in milliseconds"},"connectors":{"type":"object","description":"Connector status information","properties":{"salesNavigator":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"Connector status for this request"},"reason":{"type":"string","enum":["rate_limited","disconnected"],"description":"Reason for degraded status (only present when status is degraded)"}}}}},"linkedInContext":{"$ref":"#/components/schemas/LinkedInContext"}}},"error":{"type":"string","description":"Error message (only present when status is failed)"},"errorCode":{"type":"string","description":"Machine-readable error code (only present when status is failed)","enum":["LINKEDIN_RATE_LIMIT_EXCEEDED","LINKEDIN_CONNECTOR_REQUIRED","CONNECTOR_UNAVAILABLE","VALIDATION_ERROR"]},"errorAction":{"type":"string","description":"Suggested action to resolve the error (only present when status is failed)"},"changeContext":{"$ref":"#/components/schemas/ChangeContext","description":"Information about changes between signal versions (only present when status is completed and a previous version exists)"},"verificationMode":{"type":"string","description":"Verification mode used for signal generation","enum":["strict","lenient"]},"company":{"$ref":"#/components/schemas/CompanyFirmographics","description":"Company firmographic data (only present in webhook payloads for company signals)"}}}]},"SignalResponse":{"description":"Polymorphic signal response (company or contact)","oneOf":[{"$ref":"#/components/schemas/CompanySignalResponse"},{"$ref":"#/components/schemas/ContactSignalResponse"}],"discriminator":{"propertyName":"signalType","mapping":{"COMPANY":"#/components/schemas/CompanySignalResponse","CONTACT":"#/components/schemas/ContactSignalResponse"}}},"CompanySignalResponse":{"description":"Response for company signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["COMPANY"]},"domain":{"type":"string","description":"The domain that was researched"}},"required":["domain"]}]},"BaseSignalResponse":{"type":"object","description":"Base schema containing fields common to all signal types","properties":{"id":{"type":"string","description":"Unique identifier for the signal (UUID format)","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"signalType":{"type":"string","description":"Type of signal (company or contact)","enum":["COMPANY","CONTACT"]},"status":{"type":"string","description":"Current processing status of the signal","enum":["processing","completed","failed"]},"question":{"type":"string","description":"The research question"},"answerType":{"type":"string","description":"Answer type for this signal","enum":["boolean","number","percentage","currency","open_text","url","list","json_schema","contacts","contact_posts"]},"createdAt":{"type":"string","format":"date-time","description":"When the signal was created"}},"required":["id","signalType","status","question","createdAt"]},"ContactSignalResponse":{"description":"Response for contact signals","allOf":[{"$ref":"#/components/schemas/BaseSignalResponse"},{"type":"object","properties":{"signalType":{"type":"string","enum":["CONTACT"]},"contactProfileUrl":{"type":"string","description":"LinkedIn profile URL"}},"required":["contactProfileUrl"]}]},"Answer":{"description":"Discriminated union representing different answer types.\nThe 'type' field indicates which specific answer format is used.\n","oneOf":[{"type":"object","required":["type","open_text"],"properties":{"type":{"type":"string","enum":["open_text"],"description":"The answer type discriminator"},"open_text":{"$ref":"#/components/schemas/OpenTextAnswer"}}},{"type":"object","required":["type","number"],"properties":{"type":{"type":"string","enum":["number"],"description":"The answer type discriminator"},"number":{"$ref":"#/components/schemas/NumberAnswer"}}},{"type":"object","required":["type","boolean"],"properties":{"type":{"type":"string","enum":["boolean"],"description":"The answer type discriminator"},"boolean":{"$ref":"#/components/schemas/BooleanAnswer"}}},{"type":"object","required":["type","list"],"properties":{"type":{"type":"string","enum":["list"],"description":"The answer type discriminator"},"list":{"$ref":"#/components/schemas/ListAnswer"}}},{"type":"object","required":["type","percentage"],"properties":{"type":{"type":"string","enum":["percentage"],"description":"The answer type discriminator"},"percentage":{"$ref":"#/components/schemas/PercentageAnswer"}}},{"type":"object","required":["type","currency"],"properties":{"type":{"type":"string","enum":["currency"],"description":"The answer type discriminator"},"currency":{"$ref":"#/components/schemas/CurrencyAnswer"}}},{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["url"],"description":"The answer type discriminator"},"url":{"$ref":"#/components/schemas/URLAnswer"}}},{"type":"object","required":["type","contacts"],"properties":{"type":{"type":"string","enum":["contacts"],"description":"The answer type discriminator"},"contacts":{"$ref":"#/components/schemas/ContactsAnswer"}}},{"type":"object","required":["type","contactPosts"],"properties":{"type":{"type":"string","enum":["contact_posts"],"description":"The answer type discriminator"},"contactPosts":{"$ref":"#/components/schemas/ContactPostsAnswer"}}},{"type":"object","required":["type","contactEngagements"],"properties":{"type":{"type":"string","enum":["contact_engagements"],"description":"The answer type discriminator"},"contactEngagements":{"$ref":"#/components/schemas/ContactEngagementsAnswer"}}},{"type":"object","required":["type","jsonSchema"],"properties":{"type":{"type":"string","enum":["json_schema"],"description":"The answer type discriminator"},"jsonSchema":{"$ref":"#/components/schemas/JSONSchemaAnswer"}}}],"discriminator":{"propertyName":"type","mapping":{"open_text":"#/components/schemas/OpenTextAnswer","number":"#/components/schemas/NumberAnswer","boolean":"#/components/schemas/BooleanAnswer","list":"#/components/schemas/ListAnswer","percentage":"#/components/schemas/PercentageAnswer","currency":"#/components/schemas/CurrencyAnswer","url":"#/components/schemas/URLAnswer","contacts":"#/components/schemas/ContactsAnswer","contact_posts":"#/components/schemas/ContactPostsAnswer","contact_engagements":"#/components/schemas/ContactEngagementsAnswer","json_schema":"#/components/schemas/JSONSchemaAnswer"}}},"OpenTextAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","description":"Free-form text response"}}},"NumberAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"number","description":"Numeric value"}}},"BooleanAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"boolean","description":"True or false value"}}},"ListAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of string items (maximum 500 items)","maxItems":500,"items":{"type":"string"}}}},"PercentageAnswer":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number","description":"Percentage value"},"unit":{"type":"string","description":"Unit symbol (typically \"%\")"}}},"CurrencyAnswer":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"number","description":"Monetary amount"},"currency":{"type":"string","description":"ISO 4217 currency code"}}},"URLAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"string","format":"uri","description":"Valid URL string"}}},"ContactsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of contact objects with detailed information (maximum 100 contacts)","maxItems":100,"items":{"$ref":"#/components/schemas/Contact"}}}},"Contact":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"fullName":{"type":"string","description":"Full name of the contact"},"headline":{"type":"string","description":"Professional headline"},"summary":{"type":"string","description":"Professional summary"},"positions":{"type":"array","description":"Array of current and past positions","items":{"$ref":"#/components/schemas/ContactPosition"}},"seniority":{"type":"array","items":{"type":"string"},"description":"Seniority levels"},"linkedInSalesNavigatorProfileUrl":{"type":"string","format":"uri","description":"LinkedIn Sales Navigator profile URL"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL"},"avatar":{"type":"string","format":"uri","description":"Avatar/profile picture URL"},"location":{"type":"string","description":"Location of the contact"},"followerCount":{"type":"integer","description":"Number of followers on LinkedIn"},"education":{"type":"array","description":"Array of education entries","items":{"$ref":"#/components/schemas/Education"}}}},"ContactPosition":{"type":"object","required":["companyName","title"],"properties":{"companyName":{"type":"string","description":"Name of the company"},"companyUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"title":{"type":"string","description":"Job title/role"},"tenureInMonths":{"type":"integer","description":"Total tenure in months (computed from tenure)"},"location":{"type":"string","description":"Location of the position"},"description":{"type":"string","description":"Description of the role"},"startedOn":{"$ref":"#/components/schemas/ContactDate"},"endedOn":{"description":"End date of position (null if currently employed)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactDate":{"type":"object","required":["year"],"properties":{"year":{"type":"integer","description":"Year"},"month":{"type":"integer","description":"Month (1-12)"}}},"Education":{"type":"object","required":["schoolName"],"properties":{"schoolName":{"type":"string","description":"Name of the educational institution"},"schoolUrl":{"type":"string","format":"uri","description":"LinkedIn URL of the school"},"degree":{"type":"string","description":"Degree obtained (e.g., \"Bachelor of Science\")"},"fieldOfStudy":{"type":"string","description":"Field of study (e.g., \"Computer Science\")"},"startDate":{"$ref":"#/components/schemas/ContactDate"},"endDate":{"description":"End date of education (null if currently enrolled)","oneOf":[{"$ref":"#/components/schemas/ContactDate"},{"type":"null"}]}}},"ContactPostsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of post objects with detailed information","items":{"$ref":"#/components/schemas/Post"}}}},"Post":{"type":"object","required":["postUrl"],"properties":{"postUrl":{"type":"string","format":"uri","description":"LinkedIn post URL (identity key for tracking changes)"},"postText":{"type":"string","description":"Text content of the post"},"activityUrn":{"type":"string","description":"LinkedIn activity URN"},"publishedAt":{"type":"string","description":"Publication date"},"postType":{"type":"string","enum":["original","shared","repost"],"description":"Type of post"},"author":{"$ref":"#/components/schemas/PostAuthor"},"engagement":{"$ref":"#/components/schemas/PostEngagement"},"subject":{"type":"string","description":"AI-generated one-sentence summary of the post"}}},"PostAuthor":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Author's name"},"headline":{"type":"string","description":"Author's professional headline"},"profileUrl":{"type":"string","format":"uri","description":"Author's LinkedIn profile URL"}}},"PostEngagement":{"type":"object","properties":{"reactionCount":{"type":"integer","description":"Number of reactions"},"commentCount":{"type":"integer","description":"Number of comments"},"viewCount":{"type":"integer","description":"Number of views"},"topReactionTypes":{"type":"array","items":{"type":"string"},"description":"Most common reaction types"}}},"ContactEngagementsAnswer":{"type":"object","required":["value"],"properties":{"value":{"type":"array","description":"Array of engagement objects (maximum 100 engagements)","maxItems":100,"items":{"$ref":"#/components/schemas/ContactEngagement"}}}},"ContactEngagement":{"type":"object","required":["postUrl","engagementType"],"properties":{"postUrl":{"type":"string","format":"uri","description":"URL of the LinkedIn post where the engagement occurred"},"postAuthor":{"$ref":"#/components/schemas/PostAuthor","description":"Author of the original post"},"postText":{"type":"string","description":"Snippet of post content"},"publishedAt":{"type":"string","format":"date-time","description":"ISO 8601 post publication timestamp"},"engagementType":{"type":"string","enum":["comment","reaction"],"description":"Type of engagement"},"engagementDate":{"type":"string","format":"date-time","description":"ISO 8601 engagement timestamp"},"commentText":{"type":"string","description":"Text of comment (if engagementType is comment)"},"reactionText":{"type":"string","description":"Reaction text extracted from LinkedIn header (e.g., \"John celebrates this\", \"John likes this\", \"John finds this insightful\")"}}},"JSONSchemaAnswer":{"type":"object","description":"The generated data conforming to the user-provided JSON Schema (payload at answer.jsonSchema directly)","additionalProperties":true},"LinkedInContext":{"type":"object","description":"LinkedIn capability usage context for a signal (only present when LinkedIn tools were involved)","required":["linkedInToolsUsed","mode","capabilities"],"properties":{"linkedInToolsUsed":{"type":"boolean","description":"Whether any LinkedIn tools were used"},"mode":{"type":"string","enum":["required","preferred","off"],"description":"LinkedIn connector mode used"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedInCapabilityStatus"},"description":"Per-capability status"},"degraded":{"type":"boolean","description":"Whether the signal was degraded due to LinkedIn limitations"}}},"LinkedInCapabilityStatus":{"type":"object","description":"Status of a single LinkedIn capability during signal generation","required":["capability","used"],"properties":{"capability":{"type":"string","enum":["contact_search","profile_enrichment","company_data","company_search","activity_tracking","post_search"],"description":"LinkedIn capability name"},"used":{"type":"boolean","description":"Whether this capability was used during signal generation"},"rateLimited":{"type":"boolean","description":"Whether this capability was rate-limited"}}},"ChangeContext":{"type":"object","description":"Information about changes between signal versions. The changeType field uses graduated change types: INITIAL for first versions, NO_CHANGE for identical or semantically equivalent results, and MINOR_CHANGE/MAJOR_CHANGE for graduated severity (replacing the legacy binary CHANGED type). Subscribers can filter broadly on changedFields (any event on a field) or precisely on addedFields/updatedFields/removedFields without inspecting the delta structure.\n","required":["changeType","changedFields","addedFields","updatedFields","removedFields"],"properties":{"changeType":{"$ref":"#/components/schemas/ChangeType"},"changeDelta":{"oneOf":[{"$ref":"#/components/schemas/ChangeDelta"},{"type":"null"}],"description":"Structured delta of the change (structure varies by answer type)"},"previousSignalId":{"type":["string","null"],"description":"ID of the previous signal version","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"changedFields":{"type":"array","items":{"type":"string"},"description":"Union of addedFields + updatedFields + removedFields. Use this to subscribe to any event on a field regardless of change type (e.g. changedFields.includes(\"headline\")). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"addedFields":{"type":"array","items":{"type":"string"},"description":"Fields where new values appeared (new contacts/posts, new certifications, etc.). Entity-level additions use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields where existing values were modified (headline changed, engagement updated, etc.). Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"},"removedFields":{"type":"array","items":{"type":"string"},"description":"Fields where values were removed (contacts left, skills removed, etc.). Entity-level removals use \"contacts\" or \"posts\" as the field name. Empty for scalar answer types (number, boolean, etc.) and NO_CHANGE.\n"}}},"ChangeType":{"type":"string","description":"Type of change detected between signal versions. INITIAL = first signal version, NO_CHANGE = identical or semantically equivalent to previous, MINOR_CHANGE = low-impact semantic change, CHANGED = significant change (legacy, pre-graduated), MAJOR_CHANGE = high-impact semantic change.\n","enum":["INITIAL","NO_CHANGE","CHANGED","MINOR_CHANGE","MAJOR_CHANGE"]},"ChangeDelta":{"type":"object","description":"Structured delta of the change between signal versions.\nThe structure varies based on the answer type:\n- LIST: {type: \"LIST\", added: string[], removed: string[]}\n- NUMBER: {type: \"NUMBER\", previous: number, current: number, change: number}\n- CURRENCY: {type: \"CURRENCY\", previous: number | object, current: number | object, currency?: string, change: number | string}\n- PERCENTAGE: {type: \"PERCENTAGE\", previous: number, current: number, unit: string, change: number}\n- BOOLEAN: {type: \"BOOLEAN\", previous: boolean, current: boolean}\n- GENERIC: {type: \"GENERIC\", previous: Answer | null, current: Answer | null}\n- SEMANTIC: {type: \"SEMANTIC\", previous: Answer | null, current: Answer | null, similarityScore: number}\n- SEMANTIC_LIST: {type: \"SEMANTIC_LIST\", added: string[], removed: string[], matched: [{previous: string, current: string, similarityScore: number}], similarityScore: number}\n- CONTACTS: {type: \"CONTACTS\", added: Contact[], removed: Contact[], updated: [{previous: Contact, current: Contact, fieldChanges: [...]}]}\n- CONTACT_POSTS: {type: \"CONTACT_POSTS\", added: Post[], removed: Post[], updated: [{previous: Post, current: Post, fieldChanges: [...], engagementGrowth?: EngagementGrowth}]}\n","additionalProperties":true},"CompanyFirmographics":{"type":"object","description":"Company firmographic and LinkedIn enrichment data included in webhook payloads","properties":{"id":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company domain"},"industry":{"type":"string","description":"Industry classification"},"website":{"type":"string","description":"Company website URL"},"size":{"type":"string","description":"Company size range"},"type":{"type":"string","description":"Company type (e.g. private, public)"},"founded":{"type":"integer","description":"Year the company was founded"},"city":{"type":"string","description":"City of headquarters"},"state":{"type":"string","description":"State or region of headquarters"},"countryCode":{"type":"string","description":"ISO country code"},"handle":{"type":"string","description":"Company handle/slug"},"linkedInId":{"type":"integer","description":"LinkedIn numeric company ID"},"linkedInUrl":{"type":"string","format":"uri","description":"LinkedIn company page URL"},"linkedInFollowers":{"type":"integer","description":"Number of LinkedIn followers"},"employeeCount":{"type":"integer","description":"Approximate employee count from LinkedIn"},"description":{"type":"string","description":"Company description"},"logoUrl":{"type":"string","format":"uri","description":"Company logo URL"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/contacts/signals/{signalId}":{"get":{"summary":"Get a contact signal by ID","description":"Retrieve the current status and results of a contact signal. If the signal is completed,\nthe response will include the AI-generated answer, confidence score, and sources.\n","operationId":"getContactSignal","tags":["Using Signals API"],"parameters":[{"name":"signalId","in":"path","required":true,"description":"The unique identifier of the contact signal (UUID format)","schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"responses":{"200":{"description":"Contact signal retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SignalDetailResponse"},{"type":"object","properties":{"contactProfileUrl":{"type":"string","format":"uri","description":"Contact profile URL (LinkedIn or other professional profile)"}}}]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Signal not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Get remaining credit balance

> Returns the remaining credits balance for your organization.\
> \
> Use this endpoint to check how many credits you have available before running large batches\
> or to monitor usage programmatically.\
> \
> \---\
> \
> \## What Are Credits?\
> \
> Each API call that generates a signal consumes credits:\
> \- \*\*Company signal\*\* (\`POST /v1/companies/signals/sync\`) — consumes 1 credit per signal\
> \- \*\*Contact signal\*\* (\`POST /v1/contacts/signals/sync\`) — consumes 1 credit per signal\
> \- \*\*Batch signals\*\* — consumes 1 credit per signal in the batch\
> \- \*\*Read-only operations\*\* (listing, getting, templates) — free, no credits consumed\
> \
> Credits reset at the start of each billing period.\
> \
> \---\
> \
> \## When to Use This Endpoint\
> \
> \- \*\*Before large batches:\*\* Check that you have enough credits before submitting a bulk request\
> \- \*\*Monitoring dashboards:\*\* Poll periodically to display current usage\
> \- \*\*Conditional logic:\*\* Skip signal generation if credits are exhausted\
> \
> \---\
> \
> \## Example\
> \
> \`\`\`bash\
> curl <https://api.saber.app/v1/credits> \\\
> &#x20; -H "Authorization: Bearer YOUR\_API\_KEY"\
> \`\`\`<br>

````json
{"openapi":"3.2.0","info":{"title":"Saber Platform API","version":"1.0.0"},"tags":[{"name":"Using Signals API","summary":"Using Signals API","kind":"nav","description":"## Using the Signals API\n\nOperations for managing and retrieving signals:\n\n- **List signals** - Get all signals with filtering options\n- **Get signal by ID** - Retrieve a specific signal's details\n- **Contact research** - Deep-dive analysis of individual contacts\n- **Contact search** - Find contacts at companies using LinkedIn Sales Navigator\n\nFor creating signals, see the **\"Creating a Signal\"** section which includes the recommended synchronous endpoints.\n"}],"servers":[{"url":"https://api.saber.app","description":"Production server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key authentication using Bearer token. Format: sk_live_ followed by a secure random string."}},"schemas":{"CreditsBalance":{"type":"object","description":"Remaining credits balance for the organization in the current billing period","required":["remainingCredits"],"properties":{"remainingCredits":{"type":"integer","minimum":0,"description":"Number of credits remaining in the current billing period. Each signal creation consumes one credit. Returns 0 when the organization has no credits left; credits reset at the start of each new billing period.\n"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope returned by every endpoint that flows through the global error handler. Note: the global rate-limit middleware (HTTP 429 from per-API-key throttling) returns a different, flat shape — see `RateLimitErrorResponse`.\n","required":["error"],"properties":{"error":{"type":"object","required":["type","code","requestId"],"properties":{"type":{"type":"string","description":"Error category. Maps 1:1 to HTTP status (e.g. VALIDATION → 422, UNAUTHORIZED → 401).","enum":["BAD_REQUEST","VALIDATION","UNPROCESSABLE_ENTITY","NOT_FOUND","CONFLICT","UNAUTHORIZED","FORBIDDEN","PAYMENT_REQUIRED","PAYLOAD_TOO_LARGE","INTERNAL","EXTERNAL","TIMEOUT"]},"code":{"type":"string","description":"Stable machine-readable error code. Safe to switch on in client code."},"message":{"type":"string","description":"Human-readable error message. Wording may change; do not match against this string."},"errorCode":{"type":"string","description":"Optional public error code propagated from a downstream service (e.g. NestJS, LinkedIn)."},"errorAction":{"type":"string","description":"Optional user action guidance (e.g. \"reconnect Sales Navigator\")."},"details":{"type":"object","additionalProperties":true,"description":"Optional structured fields forwarded from a downstream service. Shape depends on the source."},"requestId":{"type":"string","format":"uuid","description":"Correlation ID for this request. Include when reporting issues."},"fields":{"type":"array","description":"Per-field validation errors (populated when `type` is `VALIDATION` and the cause is a struct-tag validator).","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"debug":{"type":"object","description":"Debug information. Only present in development environments.","properties":{"cause":{"type":"string"}}}}}}}}},"paths":{"/v1/credits":{"get":{"summary":"Get remaining credit balance","description":"Returns the remaining credits balance for your organization.\n\nUse this endpoint to check how many credits you have available before running large batches\nor to monitor usage programmatically.\n\n---\n\n## What Are Credits?\n\nEach API call that generates a signal consumes credits:\n- **Company signal** (`POST /v1/companies/signals/sync`) — consumes 1 credit per signal\n- **Contact signal** (`POST /v1/contacts/signals/sync`) — consumes 1 credit per signal\n- **Batch signals** — consumes 1 credit per signal in the batch\n- **Read-only operations** (listing, getting, templates) — free, no credits consumed\n\nCredits reset at the start of each billing period.\n\n---\n\n## When to Use This Endpoint\n\n- **Before large batches:** Check that you have enough credits before submitting a bulk request\n- **Monitoring dashboards:** Poll periodically to display current usage\n- **Conditional logic:** Skip signal generation if credits are exhausted\n\n---\n\n## Example\n\n```bash\ncurl https://api.saber.app/v1/credits \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n","operationId":"getCredits","tags":["Using Signals API"],"responses":{"200":{"description":"Credit balance retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditsBalance"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests - Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
````


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.saber.app/using-signals-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
