Endpoint Reference
Full reference for all Signals API endpoints — search, enrich, timeline, webhooks, intent scoring, and account management.
All endpoints require authentication via x-api-key header or Authorization: Bearer token. Base URL: https://signals.autobound.ai
Using MCP? All endpoints below are also accessible via the Autobound MCP server — no direct API calls required for AI agents and tools.
Signal Response Shape
All endpoints that return signals share a common object structure:
{
"signal_id": "7dfdb4b4-c0b4-4620-aca6-e7263123028e",
"signal_type": "news",
"signal_subtype": "fundingAnnouncement",
"signal_name": "Funding Announcement",
"detected_at": "2026-03-01T00:00:00Z",
"association": "company",
"company": {
"name": "Acme Corp",
"domain": "acmecorp.com",
"linkedin_url": "linkedin.com/company/acme-corp",
"industries": ["Software"],
"employee_count_low": 51,
"employee_count_high": 200
},
"contact": null,
"data": {
"summary": "Acme Corp announced a $25M Series B funding round led by Sequoia Capital.",
"...": "signal-specific fields vary by type"
},
"score": 0.87
}Key fields:
association—"company"or"contact". Tells you whether this signal is about the company as a whole or a specific individual.data— the signal-specific payload. Structure varies bysignal_type. See the Signal Catalog for per-type schemas.score— semantic similarity score (0–1). Only present on results from the/searchendpoint when aqueryis provided.
Search
POST /v1/signals/search
POST /v1/signals/searchCredits: 1 per call
When to use this: When you don't know which specific company or contact you're looking for, but you know the type of signal you want to find. The search endpoint scans the entire Autobound database and returns the most relevant matches — either by semantic similarity to a natural language query, by structured filters, or both combined.
How it works: If you provide a query, Autobound embeds it as a vector and runs approximate nearest-neighbor search against all signals in the database. If you add structured filters (signal type, date range, company size, etc.), those are applied on top of the vector search as hard constraints. If you omit query, it's a pure structured filter query.
Common use cases:
- Find companies showing AI investment signals:
query: "investing in AI infrastructure" - Find all 10-K signals from enterprise software companies in the last 90 days
- Find contacts who recently changed jobs into VP roles
Request body:
| Field | Type | Description |
|---|---|---|
query | string | Natural language semantic query (max 2,000 chars). Optional — omit for purely structured search. |
signal_types | string[] | Filter to specific signal type slugs (see Signal Catalog) |
signal_subtype | string | Filter to a specific subtype within a signal type |
company_domain | string | Restrict to signals from a specific company |
company_name | string | Filter by company name (fuzzy matched) |
company_industries | string[] | Filter by industry tags (max 20) |
association | "company" | "contact" | Return only company-level or contact-level signals |
detected_after | ISO-8601 date | Only signals detected after this date |
detected_before | ISO-8601 date | Only signals detected before this date |
employee_count_min | integer | Min company employee count |
employee_count_max | integer | Max company employee count |
contact_email | string | Restrict to signals for a specific contact email |
contact_linkedin_url | string | Restrict to signals for a specific contact LinkedIn URL |
limit | integer | Results per page. Default: 20, max: 500 |
offset | integer | Pagination offset. Default: 0, max: 1000 |
Response:
{
"signals": [ "..." ],
"total": 47,
"offset": 0,
"limit": 20,
"has_more": true
}GET /v1/signals/trending
GET /v1/signals/trendingCredits: Free
When to use this: When you want a live feed of what's happening across the database right now — without targeting any specific company or contact. Useful for building a "signal pulse" dashboard, monitoring breaking news, or surfacing timely outreach triggers for your team.
How it works: Returns recent signals sorted by detected_at descending, optionally filtered by type, time window, or company. The signal_summary in the response gives you a count breakdown by type — handy for understanding signal volume before diving into individual results.
Query parameters:
| Param | Type | Description |
|---|---|---|
time_window | "24h" | "7d" | "30d" | How far back to look. Default: "7d" |
signal_types | string (comma-separated) | Filter to specific types |
association | "company" | "contact" | Filter by association |
company_domain | string | Scope to a single company |
limit | integer | Max results. Default: 50, max: 200 |
Response:
{
"time_window": "7d",
"since": "2026-02-26",
"signals": [ "..." ],
"signal_summary": {
"news": 18,
"work-milestones": 12,
"hiring-trends": 9
},
"total": 39
}GET /v1/signals/:signal_id
GET /v1/signals/:signal_idCredits: 1 per call
When to use this: When you have a signal_id (from a previous search, webhook delivery, or stored reference) and need to fetch the full signal record. Useful for re-hydrating signal data in your database or verifying a specific signal still exists.
Response: A single signal object.
GET /v1/signals/types
GET /v1/signals/typesCredits: Free
When to use this: To discover what signal types are available in the database — and optionally see how many records exist per type. Useful for building dropdowns, validating slugs before filtering, or understanding data volume before running a large query.
| Param | Type | Description |
|---|---|---|
include_counts | "true" | "false" | Include record count per type |
since | ISO-8601 date | Count signals detected after this date |
association | "company" | "contact" | Filter to one association type |
Response (with counts):
{
"signal_types": [
{
"type": "news",
"association": "company",
"description": "Company news articles and press releases",
"count": 2847201
}
],
"total_signals": 18200000,
"counted_at": "2026-03-05T00:00:00Z"
}GET /v1/signals/types/:type/history
GET /v1/signals/types/:type/historyCredits: Free
When to use this: To see how signal volume for a given type has changed over time — useful for understanding data freshness, validating that a pipeline is running, or showing customers data recency.
| Param | Type | Description |
|---|---|---|
months | integer | Lookback in months. Default: 6, max: 24 |
interval | "monthly" | "weekly" | Grouping interval |
Companies
POST /v1/companies/enrich
POST /v1/companies/enrichCredits: 1 per call
When to use this: When you know exactly which company you want signals for. This is the right call for account-level enrichment — loading a company page, running a pre-meeting brief, or triggering a workflow when a specific account enters your pipeline.
How it works: Pass a domain, company name, or LinkedIn URL (at least one required). Autobound looks up all signals associated with that company and returns them, optionally filtered by signal type and date. The signal_summary in the response gives you a count by type so you can see at a glance what's available.
Request body:
| Field | Type | Description |
|---|---|---|
domain | string | Company domain (e.g., "salesforce.com") — most reliable identifier |
company_name | string | Company name (fuzzy matched) |
linkedin_url | string | Company LinkedIn URL |
signal_types | string[] | Filter to specific signal types |
detected_after | ISO-8601 date | Only signals after this date |
limit | integer | Max signals to return. Default: 50, max: 500 |
Response:
{
"company": { "..." },
"signals": [ "..." ],
"signal_summary": {
"news": 8,
"hiring-trends": 3,
"10k": 1
}
}POST /v1/companies/bulk
POST /v1/companies/bulkCredits: 1 credit per domain (e.g., 50 domains = 50 credits)
When to use this: When you need to enrich a list of companies in a single request — for example, enriching all accounts in a Salesforce list, or running nightly enrichment against your ICP. More efficient than making individual enrich calls in a loop.
How it works: Pass an array of domains (up to 500). Each domain is enriched independently and returned as its own entry in the results array. Use limit_per_company to control how many signals you get per company — lower values keep response size manageable for large batches.
Request body:
| Field | Type | Description |
|---|---|---|
domains | string[] | Company domains. Min: 1, max: 500 |
signal_types | string[] | Filter to specific signal types |
detected_after | ISO-8601 date | Only signals after this date |
limit_per_company | integer | Max signals per company. Default: 10, max: 100 |
Response: { total_companies, results: [...per-company enrich responses] }
GET /v1/companies/:domain/timeline
GET /v1/companies/:domain/timelineCredits: 1 per call
When to use this: When you want a chronological view of everything that's happened at a company — not filtered by type, just sorted by time. Useful for building an account activity feed, understanding the arc of a company's recent history, or generating pre-meeting briefs that cover the full story.
How it works: Returns all signals for the company sorted by detected_at descending. You can optionally filter to specific signal types and limit the lookback window with since.
| Param | Type | Description |
|---|---|---|
since | ISO-8601 date | Only signals after this date |
signal_types | string (comma-separated) | Filter to specific types |
limit | integer | Default: 100, max: 500 |
Response: { company, domain, timeline: [...signals], total, has_more }
Note: signals are in the
timelinekey (notsignals) for this endpoint.
Contacts
POST /v1/contacts/enrich
POST /v1/contacts/enrichCredits: 1 per call
When to use this: When you need a full picture of a specific person — both who they are (job changes, LinkedIn activity, podcast appearances) and the context of their company (funding, news, hiring signals). This is the right call before an outreach email, a sales call, or when personalizing an AI-generated message.
How it works: Pass a work email or LinkedIn URL (at least one required). Autobound resolves the contact against our identity graph (250M+ contacts) and returns their contact-level signals plus, optionally, signals from their current employer. The contact field in the response includes their resolved title, email, and LinkedIn URL — confirming identity before you use the data.
Request body:
| Field | Type | Description |
|---|---|---|
contact_email | string | Contact work email |
contact_linkedin_url | string | Contact LinkedIn URL |
signal_types | string[] | Filter to specific signal types |
detected_after | ISO-8601 date | Only signals after this date |
include_company_signals | boolean | Also return signals from the contact's employer. Default: true |
limit | integer | Default: 50, max: 500 |
Response:
{
"contact": {
"name": "Jane Doe",
"email": "[email protected]",
"linkedin_url": "linkedin.com/in/janedoe",
"title": "VP of Sales"
},
"company": { "..." },
"contact_signals": [ "..." ],
"company_signals": [ "..." ],
"signal_summary": {
"work-milestones": 1,
"linkedin-post-contact": 4,
"news": 8
},
"total": 13
}POST /v1/contacts/bulk
POST /v1/contacts/bulkCredits: 1 credit per contact
When to use this: When enriching a list of contacts — a new import, a sequence audience, or an outbound list. Pass up to 100 contacts at once instead of making individual calls. Each contact is identified by email or LinkedIn URL.
Request body:
| Field | Type | Description |
|---|---|---|
contacts | object[] | Array of { contact_email?, contact_linkedin_url? }. Min: 1, max: 100 |
signal_types | string[] | Filter to specific signal types |
detected_after | ISO-8601 date | Only signals after this date |
limit_per_contact | integer | Max signals per contact. Default: 10, max: 100 |
Response: { total_contacts, results: [...per-contact enrich responses] }
GET /v1/contacts/timeline
GET /v1/contacts/timelineCredits: 1 per call
When to use this: Same use case as the company timeline, but for an individual person. Returns all signals for a contact in chronological order — useful for building a contact activity feed or understanding someone's professional trajectory over time.
| Param | Type | Description |
|---|---|---|
contact_email | string | Required if no contact_linkedin_url |
contact_linkedin_url | string | Required if no contact_email |
since | ISO-8601 date | Only signals after this date |
signal_types | string (comma-separated) | Filter to specific types |
limit | integer | Default: 50, max: 200 |
Response: { contact, company, identifier, timeline: [...signals], total, has_more }
Note: signals are in the
timelinekey (notsignals) for this endpoint.
Intent Scoring (Coming Soon)
Intent scoring endpoints are in active development. Contact us for early access.
Intent scoring is different from search and enrichment. Instead of returning individual signals, intent endpoints aggregate signals across a company or contact and return a relevance score — a single number (0–1) representing how strongly their recent activity aligns with your query or product category.
Example: If you query "companies evaluating CRM solutions", the intent endpoints look at all recent signals for each company in their scope — LinkedIn posts from employees about CRM pain points, job postings for Salesforce admins, earnings call mentions of sales process improvements — and roll them up into a score. Companies where multiple signals point in the same direction score higher.
Intent endpoints require more compute than standard search/enrich calls and will be priced at a higher credit rate.
POST /v1/intent/companies (Coming Soon)
POST /v1/intent/companies (Coming Soon)Scores companies by how relevant their recent signal activity is to a query. Returns companies ranked by intent score with the specific signals that drove the score.
| Field | Type | Description |
|---|---|---|
query | string | What you're looking for (e.g., "companies switching CRM vendors") |
filters | object | Optional: signal_types, industries, employee_count_min/max, detected_after, etc. |
limit | integer | Max companies to return. Default: 50, max: 200 |
min_intent_score | float | Minimum score threshold (0–1). Default: 0 |
min_signals | integer | Minimum number of signals required to score a company. Default: 2 |
POST /v1/intent/contacts (Coming Soon)
POST /v1/intent/contacts (Coming Soon)Same as company intent, scoped to individual contacts. Identifies people whose recent activity (job changes, LinkedIn posts, podcast appearances) most strongly matches your query.
Account & Utilities
GET /v1/account
GET /v1/accountCredits: Free
Returns full account info for the authenticated API key — customer name, rate limit, and current credit balance. Useful for debugging auth issues or confirming which account a key belongs to.
Response:
{
"customer_id": "v47l57P2PpvlwFcMNLdw",
"customer_name": "Acme Inc",
"rate_limit": 1000,
"credits": {
"monthly_limit": 10000,
"used": 142,
"remaining": 9858,
"period_start": "2026-03-01T00:00:00Z",
"period_reset": "2026-04-01T00:00:00Z",
"unlimited": false
}
}GET /v1/credits
GET /v1/creditsCredits: Free
Returns just the credit balance for the current billing period. Lighter than /v1/account if that's all you need.
{
"monthly_limit": 10000,
"used": 142,
"remaining": 9858,
"period_start": "2026-03-01T00:00:00Z",
"period_reset": "2026-04-01T00:00:00Z",
"unlimited": false
}GET /v1/logs
GET /v1/logsCredits: Free
Returns your request history — useful for debugging, auditing credit usage, or understanding which endpoints your integration is calling most. Filterable by endpoint path, HTTP method, status code, and date range.
| Param | Type | Description |
|---|---|---|
path | string | Filter by endpoint path (e.g., /v1/signals/search) |
method | string | GET, POST, PATCH, or DELETE |
status_min / status_max | integer | Filter by response status code range |
since / before | ISO-8601 date | Date range |
limit | integer | Default: 50, max: 200 |
Error Reference
All errors follow a consistent shape:
{
"error": "invalid_request",
"message": "Invalid request parameters",
"code": 400,
"details": [ "..." ]
}| Status | Error | Meaning |
|---|---|---|
400 | invalid_request | Bad parameters. Check details for field-level errors. |
401 | unauthorized | Missing or invalid API key |
402 | credits_exhausted | Monthly credit limit reached. Credits reset at start of next billing period. |
404 | not_found | Signal ID or resource not found |
429 | rate_limited | Too many requests — back off and retry |
500 | internal_error | Server error — contact support if persistent |
Updated about 7 hours ago
