> For the complete documentation index, see [llms.txt](https://docs.sumble.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sumble.com/api/intelligence/signals.md).

# Signals

Search Sumble Signals across the accounts available to your API key. Signals include champion movements, recent hires and promotions, technology and product mentions, projects and initiatives, and technology or job function trends.

Use this endpoint when you want a filtered feed across many accounts. If you already have one Sumble organization `id`, use [Organization signals](/api/core-data/organizations/organization-signals.md) instead.

Use Priority Signals search when you want the AI-generated digest items from your Priority Signals feed, filtered by the signal, organization, person, or job post IDs attached to their source signals.

Use the signal configs listing when you want the standing rules behind the feed — what each signal watches for, and how much of your feed it drives.

## Search signals

Search by any combination of signal IDs, organization IDs, person IDs, technology slugs, job function names, priorities, saved organization list IDs, and signal config IDs. The request body may be omitted; when present, all filter fields are optional. Filters are combined with AND; values inside each filter array are combined with OR.

```bash
curl https://api.sumble.com/v9/signals \
  --request POST \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "filter": {
      "signal_ids": [123],
      "organization_ids": [31],
      "person_ids": [12729201],
      "job_functions": ["Account Executive"],
      "priorities": ["high"],
      "account_list_ids": [4],
      "signal_config_ids": [512]
    }
  }'
```

To search people-movement signals by job function, omit `technology_slugs` unless the same signals also have matching technology metadata.

To search for signals about specific people, pass their Sumble person IDs in `person_ids`. This matches the `person_id` field returned on person-related signals.

To see what one of your standing rules has turned up, pass its ID in `signal_config_ids`. This matches the `signal_config_id` returned on each signal; use [List signal configs](#list-signal-configs) to find the IDs your account can read. Because a search only ever covers signals already in your feed, this filter narrows that feed — it never exposes signals or configs you could not otherwise see.

### Recency window

This endpoint returns only signals from the **last 60 days**, regardless of the other filters you apply. This keeps searches fast and focused on current activity.

The only exception is a direct lookup by `signal_ids`: those signals are always returned regardless of age.

### Pagination

Results default to 100 signals per page, with a maximum `limit` of 100. Use `offset` to skip results; it defaults to 0 and accepts values up to 10,000. Results use deterministic newest-first ordering. Each returned signal costs 1 credit, so larger pages and additional pages consume credits for every signal returned.

### Response

The response contains a `signals` array. Each signal includes `signal_id`, a display-ready `title`, `display_type`, and `date`, plus optional context such as `subtitle`, `type`, `organization_name`, `organization_id`, `person_id`, `matched_technologies`, `location`, `job_function`, `priority`, `explanation`, and `sales_angle`.

Each signal carries the `signal_config_name` of the rule that generated it. When that config is visible to your account, the signal also carries its `signal_config_id`; pass the ID to [List signal configs](#list-signal-configs) to read the full rule. A coworker's individual config remains private, but its name still explains why the signal appears in a shared domain feed.

For person-movement signals, `subtitle` may include a normalized start-date label such as `Started Jun 2026` or `Starting Jul 2026`.

A signal about a person carries two links for them: `person_sumble_url`, their Sumble profile page, and `linkedin_url`. Use the Sumble profile as the primary link — it is the page that carries what Sumble knows about them.

Job-post signals (technology and product mentions, projects, and first mentions) also include `suggested_contacts`: the top contacts to consider reaching out to at the account, ranked by relevance. It contains a `people` array — each with `person_id`, `name`, `title`, `sumble_url`, `linkedin_url`, and a relevance `score` from 1 to 10 (higher is a stronger match) — and a `sumble_url` on `suggested_contacts` itself, linking to all matching people for the job post.

Each signal also includes `account_status`: the CRM relationship between the signal's organization and your account (`customer`, `prospect`, or `not_in_crm`). Only populated when your account has a linked CRM seat (Salesforce or HubSpot). Without one, the REST API omits the field and the `SearchSignals` MCP tool returns it as `null`.

### File download

Set `file_name` to a filename ending in `.csv`, `.xlsx` for an Excel workbook, or `.json`, to download the matching signals. The file contains the requested page, with one row per signal and one column per response field. `matched_technologies` and `suggested_contacts` contain compact JSON text within their cells in a `.csv` or `.xlsx`, and stay nested in a `.json`.

The response keeps its credit metadata, adds an authenticated Sumble download URL and file details, and returns an empty `signals` array because the rows are in the file. Ask Sumble and Slack attach the file automatically. Other MCP clients should present the download URL instead of recreating the file with code execution.

### Credit cost

1 credit per signal returned. Searches with no returned signals do not consume credits.

## Search signals

> Signals are sales-relevant events such as champion job changes, recent hires and promotions, technology and product mentions, projects and initiatives, and technology and job-function trends. Job-post signals (technology and product mentions, projects, and first mentions) also include \`suggested\_contacts\`: the top few people to consider reaching out to at the account, plus a link to view all of them. Each signal also carries \`account\_status\`: the CRM relationship between the signal's organization and the calling account ('customer', 'prospect', or 'not\_in\_crm'). Only populated when the calling account has a linked CRM seat (Salesforce or HubSpot). Results are paginated with \`limit\` (default and maximum 100) and \`offset\` (default 0, maximum 10,000).

```json
{"openapi":"3.1.0","info":{"title":"Sumble API","version":"v9"},"servers":[{"url":"https://api.sumble.com"}],"security":[{"api_token":[]}],"components":{"securitySchemes":{"api_token":{"type":"http","scheme":"bearer"}},"schemas":{"SearchSignalsRequest":{"properties":{"filter":{"$ref":"#/components/schemas/SearchSignalsFilter","description":"Filter criteria for signals search."},"limit":{"type":"integer","maximum":100,"minimum":1,"title":"Limit","description":"Maximum number of signals to return.","default":100},"offset":{"type":"integer","maximum":10000,"minimum":0,"title":"Offset","description":"Number of signals to skip.","default":0}},"additionalProperties":false,"type":"object","title":"SearchSignalsRequest"},"SearchSignalsFilter":{"properties":{"organization_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Organization Ids","description":"Organization IDs to filter signals by."},"person_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Person Ids","description":"Sumble person IDs to filter signals by."},"signal_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Signal Ids","description":"Signal IDs to filter signals by."},"technology_slugs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Technology Slugs","description":"Canonical technology slugs to filter signals by, such as `kubernetes` or `salesforce`."},"job_functions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Job Functions","description":"Job function names to filter signals by, such as `Engineering` or `Sales`."},"priorities":{"anyOf":[{"items":{"type":"string","enum":["high","medium","low"]},"type":"array"},{"type":"null"}],"title":"Priorities","description":"Priorities to filter signals by. Matches the `priority` field returned on each signal."},"account_list_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Account List Ids","description":"Account list IDs to filter signals to accounts in those lists."},"signal_config_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Signal Config Ids","description":"Signal config IDs to filter signals by. Matches the `signal_config_id` returned on each signal."}},"additionalProperties":false,"type":"object","title":"SearchSignalsFilter"},"SignalsResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"credits_used":{"type":"integer","title":"Credits Used"},"credits_remaining":{"type":"integer","title":"Credits Remaining"},"signals":{"items":{"$ref":"#/components/schemas/Signal"},"type":"array","title":"Signals"}},"type":"object","required":["id","credits_used","credits_remaining","signals"],"title":"SignalsResponse"},"Signal":{"properties":{"signal_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Id"},"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation"},"sales_angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sales Angle"},"date":{"type":"string","format":"date-time","title":"Date"},"sumble_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sumble Url"},"display_type":{"type":"string","title":"Display Type"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"matched_technologies":{"anyOf":[{"items":{"$ref":"#/components/schemas/SignalTechnology"},"type":"array"},{"type":"null"}],"title":"Matched Technologies"},"organization_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Name"},"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"job_post_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Job Post Id"},"person_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Person Id"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"job_function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Function"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"},"signal_config_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Config Id","description":"The `id` of the signal config that generated this signal. Returned only when that config is visible to your account; pass it to List Signal Configs to read the full definition."},"signal_config_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signal Config Name","description":"Display name of the signal config that generated this signal. This remains available as explanation context even when the full config is not visible to your account."},"suggested_contacts":{"anyOf":[{"$ref":"#/components/schemas/SuggestedContacts"},{"type":"null"}]},"account_status":{"anyOf":[{"type":"string","enum":["customer","prospect","not_in_crm"]},{"type":"null"}],"title":"Account Status","description":"CRM relationship between the signal's organization and the calling account: 'customer' (a customer account in the calling account's CRM), 'prospect' (tracked in CRM but not a customer), or 'not_in_crm' (no CRM record). Only populated when the calling account has a linked CRM seat (Salesforce or HubSpot); otherwise absent or null even when requested, depending on the caller (the REST API omits null fields, MCP returns them as null)."}},"type":"object","required":["title","date","display_type"],"title":"Signal"},"SignalTechnology":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["name","slug"],"title":"SignalTechnology"},"SuggestedContacts":{"properties":{"people":{"items":{"$ref":"#/components/schemas/SuggestedContact"},"type":"array","title":"People"},"sumble_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sumble Url"}},"type":"object","required":["people"],"title":"SuggestedContacts"},"SuggestedContact":{"properties":{"person_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Person Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"}},"type":"object","title":"SuggestedContact"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v9/signals":{"post":{"tags":["signals"],"summary":"Search signals","description":"Signals are sales-relevant events such as champion job changes, recent hires and promotions, technology and product mentions, projects and initiatives, and technology and job-function trends. Job-post signals (technology and product mentions, projects, and first mentions) also include `suggested_contacts`: the top few people to consider reaching out to at the account, plus a link to view all of them. Each signal also carries `account_status`: the CRM relationship between the signal's organization and the calling account ('customer', 'prospect', or 'not_in_crm'). Only populated when the calling account has a linked CRM seat (Salesforce or HubSpot). Results are paginated with `limit` (default and maximum 100) and `offset` (default 0, maximum 10,000).","operationId":"search_signals__api_version__signals_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchSignalsRequest"}}}},"responses":{"200":{"description":"Signals matching the requested filters. Charged one credit per signal returned. Job-post signals also carry `suggested_contacts` with the top contacts to consider and a link to view all.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Search Priority Signals

Search your Priority Signals digest items by any combination of signal IDs, organization IDs, person IDs, job post IDs, your relevance feedback, and whether you wrote feedback. The request body may be omitted; when present, all filter fields are optional. Filters are combined with AND; values inside each filter array are combined with OR.

Priority Signals are AI-generated summaries of the highest-priority signals in your account feed. Each result includes the digest item `id`, headline and content, a URL to view the digest in Sumble, source `signal_ids`, searchable `organization_ids`, `person_ids`, and `job_post_ids` derived from the source signals, your relevance feedback (`is_relevant`), and your written `feedback`.

```bash
curl https://api.sumble.com/v9/signals/priority \
  --request POST \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "filter": {
      "signal_ids": [123],
      "organization_ids": [31],
      "person_ids": [12729201],
      "job_post_ids": [789],
      "is_relevant": true
    }
  }'
```

The `is_relevant` filter accepts `true` (only signals you marked relevant) or `false` (only signals you marked not relevant). Omit it to return priority signals regardless of feedback — omitting it does **not** match only unreviewed (no-feedback) signals.

The `has_feedback` filter accepts `true` (only signals you wrote feedback on) or `false` (only signals without written feedback). Omit it to return priority signals either way.

### Pagination

Results default to 20 priority signals per page, with a maximum `limit` of 100. Use `offset` to skip results; it defaults to 0 and accepts values up to 10,000. Results are ordered by completion time, with a deterministic tie-breaker. Each returned priority signal costs 1 credit, so larger pages and additional pages consume credits for every priority signal returned.

### Response

The response contains a `priority_signals` array. Each priority signal includes `id`, `url`, `signal_ids`, `headline`, `content`, `date`, `organization_ids`, `person_ids`, and `job_post_ids`. `is_relevant` is `true` or `false` when you have given feedback. Without feedback, the REST API omits the field and the `SearchPrioritySignals` MCP tool returns it as `null`. `feedback` holds your written feedback and follows the same rule when there is none. The `date` is returned as `YYYY-MM-DD`.

### File download

Set `file_name` to a filename ending in `.csv`, `.xlsx` for an Excel workbook, or `.json`, to download the requested page. The file contains one row per priority signal. `signal_ids`, `organization_ids`, `person_ids`, and `job_post_ids` contain compact JSON text within their cells in a `.csv` or `.xlsx`, and stay nested in a `.json`.

The response keeps its credit metadata, adds an authenticated Sumble download URL and file details, and returns an empty `priority_signals` array because the rows are in the file. Ask Sumble and Slack attach the file automatically. Other MCP clients should present the download URL instead of recreating the file with code execution.

### Credit cost

1 credit per priority signal returned. Searches with no returned priority signals do not consume credits.

## Search priority signals

> Priority signals are AI-generated digest items summarizing the most important signals in a user's account feed. They optionally can be searched by signal, organization, person, or job post IDs attached to their source signals. Returns the most recent priority signals based on the specified filters, or omit filters to simply return the latest. Results are paginated with \`limit\` (default 20, maximum 100) and \`offset\` (default 0, maximum 10,000).

```json
{"openapi":"3.1.0","info":{"title":"Sumble API","version":"v9"},"servers":[{"url":"https://api.sumble.com"}],"security":[{"api_token":[]}],"components":{"securitySchemes":{"api_token":{"type":"http","scheme":"bearer"}},"schemas":{"SearchPrioritySignalsRequest":{"properties":{"filter":{"$ref":"#/components/schemas/SearchPrioritySignalsFilter","description":"Filter criteria for priority signals search."},"limit":{"type":"integer","maximum":100,"minimum":1,"title":"Limit","description":"Maximum number of priority signals to return.","default":20},"offset":{"type":"integer","maximum":10000,"minimum":0,"title":"Offset","description":"Number of priority signals to skip.","default":0}},"additionalProperties":false,"type":"object","title":"SearchPrioritySignalsRequest"},"SearchPrioritySignalsFilter":{"properties":{"organization_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Organization Ids","description":"Organization IDs to filter priority signals by."},"person_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Person Ids","description":"Sumble person IDs to filter priority signals by."},"signal_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Signal Ids","description":"Signal IDs to filter priority signals by."},"job_post_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Job Post Ids","description":"Job post IDs to filter priority signals by."},"is_relevant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Relevant","description":"Filter by your relevance feedback: true for priority signals you marked relevant, false for ones you marked not relevant. Omit to return priority signals regardless of feedback -- this does not match only unreviewed (null-feedback) signals."}},"additionalProperties":false,"type":"object","title":"SearchPrioritySignalsFilter"},"PrioritySignalsResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"credits_used":{"type":"integer","title":"Credits Used"},"credits_remaining":{"type":"integer","title":"Credits Remaining"},"priority_signals":{"items":{"$ref":"#/components/schemas/PrioritySignal"},"type":"array","title":"Priority Signals"}},"type":"object","required":["id","credits_used","credits_remaining","priority_signals"],"title":"PrioritySignalsResponse"},"PrioritySignal":{"properties":{"id":{"type":"integer","title":"Id"},"url":{"type":"string","title":"Url"},"headline":{"type":"string","title":"Headline"},"content":{"type":"string","title":"Content"},"date":{"type":"string","format":"date","title":"Date"},"signal_ids":{"items":{"type":"integer"},"type":"array","title":"Signal Ids"},"organization_ids":{"items":{"type":"integer"},"type":"array","title":"Organization Ids"},"person_ids":{"items":{"type":"integer"},"type":"array","title":"Person Ids"},"job_post_ids":{"items":{"type":"integer"},"type":"array","title":"Job Post Ids"},"is_relevant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Relevant","description":"Your relevance feedback on this priority signal: true (relevant), false (not relevant), or no feedback. When no feedback exists, the REST API omits this field and MCP returns it as null. Update it with the Update Priority Signal Relevance endpoint."}},"type":"object","required":["id","url","headline","content","date"],"title":"PrioritySignal"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v9/signals/priority":{"post":{"tags":["signals"],"summary":"Search priority signals","description":"Priority signals are AI-generated digest items summarizing the most important signals in a user's account feed. They optionally can be searched by signal, organization, person, or job post IDs attached to their source signals. Returns the most recent priority signals based on the specified filters, or omit filters to simply return the latest. Results are paginated with `limit` (default 20, maximum 100) and `offset` (default 0, maximum 10,000).","operationId":"search_priority_signals__api_version__signals_priority_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchPrioritySignalsRequest"}}}},"responses":{"200":{"description":"Priority signals matching the requested filters. Charged one credit per priority signal returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrioritySignalsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Priority Signal Relevance

Mark a priority signal (identified by its `id` from Search Priority Signals) as relevant or not relevant, or clear previously-set feedback. This mirrors the relevant / not relevant feedback available in the web app, and the feedback is weighed when generating your future digests.

```bash
curl https://api.sumble.com/v9/signals/priority/88/relevance \
  --request POST \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{ "is_relevant": true }'
```

Pass `"is_relevant": true` (relevant), `false` (not relevant), or `null` to clear previously-set feedback.

### Response

Returns the updated `id` and `is_relevant`.

### Credit cost

Free — this endpoint does not consume credits.

## Update priority signal relevance

> Mark a priority signal (identified by its \`id\` from Search Priority Signals) as relevant or not relevant, or clear previously-set feedback by passing \`is\_relevant: null\`. Mirrors the relevant / not relevant feedback available in the web app. Free -- does not consume credits.

```json
{"openapi":"3.1.0","info":{"title":"Sumble API","version":"v9"},"servers":[{"url":"https://api.sumble.com"}],"security":[{"api_token":[]}],"components":{"securitySchemes":{"api_token":{"type":"http","scheme":"bearer"}},"schemas":{"UpdatePrioritySignalRelevanceRequest":{"properties":{"is_relevant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Relevant","description":"Whether this priority signal is relevant (true) or not relevant (false). Pass null to clear previously-set feedback."}},"additionalProperties":false,"type":"object","required":["is_relevant"],"title":"UpdatePrioritySignalRelevanceRequest"},"PrioritySignalRelevanceResponse":{"properties":{"id":{"type":"integer","title":"Id"},"is_relevant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Relevant"}},"type":"object","required":["id"],"title":"PrioritySignalRelevanceResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v9/signals/priority/{item_id}/relevance":{"post":{"tags":["signals"],"summary":"Update priority signal relevance","description":"Mark a priority signal (identified by its `id` from Search Priority Signals) as relevant or not relevant, or clear previously-set feedback by passing `is_relevant: null`. Mirrors the relevant / not relevant feedback available in the web app. Free -- does not consume credits.","operationId":"update_priority_signal_relevance__api_version__signals_priority__item_id__relevance_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"integer","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrioritySignalRelevanceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrioritySignalRelevanceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Priority Signal Feedback

Tell Sumble why a priority signal (identified by its `id` from Search Priority Signals) was or wasn't relevant, in your own words. Sumble reads this feedback when it writes your future priority signals, and Ask Sumble sees it too. A sentence about why works better than a bare verdict: "Already a customer, so expansion signals matter more than new hiring" tells the model what to change.

```bash
curl https://api.sumble.com/v9/signals/priority/88/feedback \
  --request POST \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{ "feedback": "Already a customer, so expansion signals matter more than new hiring." }'
```

`feedback` takes up to 2,000 characters and replaces any earlier feedback on the item. Pass `null` or an empty string to clear it. Written feedback is separate from `is_relevant`; set that with Update Priority Signal Relevance.

### Response

Returns the updated `id` and `feedback`.

### Credit cost

Free. This endpoint does not consume credits.

## List signal configs

A signal config is a standing rule that decides which signals reach you — "this technology mentioned in a job post", "a champion changed jobs", "this hiring trend is increasing" — narrowed by a filter over organizations, technologies, job functions and other attributes. Every signal in your feed was generated by one of them.

This endpoint lists the configs your account can read, so you can tell what your feed is actually watching and, when authorized, resolve a signal's `signal_config_id` into the rule behind it. It is read-only: configs are created and edited in the web app, not through the API.

For an active-config listing, filter by types and priorities, or omit the request body to return everything visible. An explicit `signal_config_ids` filter is a separate historical lookup: it cannot be combined with types or priorities, and it can return deleted configs that your account is authorized to read. Values inside each filter array are combined with OR.

```bash
curl https://api.sumble.com/v9/signals/configs \
  --request POST \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "filter": {
      "signal_config_ids": [512]
    }
  }'
```

### Access

Configs are scoped exactly as they are on the web app's signal settings page:

* If your account belongs to a Sumble Enterprise customer with Signals enabled, you read that customer's shared configs.
* On a Pro plan, you read your own configs, preceded by any configs shared across your email domain.
* Otherwise you read only your own configs.

Normal listings exclude deleted configs. An explicit lookup by `signal_config_ids` also uses the web app's config-detail permissions and can return an authorized deleted config so historical signals remain explainable. A coworker's individual config is not readable even when one of its generated signals appears in your shared domain feed. An ID your account cannot read is reported in the response `message` rather than returned, and the response never reveals whether such a config exists.

### Response

The response contains a `signal_configs` array. Each config includes:

| Field                        | Description                                                                                                                                                                                                                                                            |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                         | The config's ID. Matches `signal_config_id` on the signals it generates.                                                                                                                                                                                               |
| `name`, `slug`               | Display name and stable slug.                                                                                                                                                                                                                                          |
| `type`                       | The kind of event watched for, e.g. `technology_any_mentions`. Matches `type` on the signals it generates.                                                                                                                                                             |
| `priority`                   | `high`, `medium`, or `low` — stamped on every signal it generates.                                                                                                                                                                                                     |
| `scope`                      | `user` (yours alone), `customer` (shared across your Sumble Enterprise account), or `domain` (shared across your email domain). Only `user` configs are yours to change.                                                                                               |
| `sumble_url`                 | Link to the config's settings page in the web app. For deleted configs, the REST API omits the field and the `ListSignalConfigs` MCP tool returns it as `null`.                                                                                                        |
| `deleted`                    | Whether the config has been deleted. `true` appears only in explicit ID lookups.                                                                                                                                                                                       |
| `days`                       | Lookback window, in days, over which the config evaluates activity.                                                                                                                                                                                                    |
| `filter_by`                  | `advanced_query` or `customer_people` — how the config selects matches.                                                                                                                                                                                                |
| `advanced_query`             | The filter tree deciding which organizations, technologies, job functions and other attributes match.                                                                                                                                                                  |
| `people_filter`, `job_level` | Extra restrictions on people-movement configs.                                                                                                                                                                                                                         |
| `sales_play`                 | Free-text sales play shown alongside the config's signals.                                                                                                                                                                                                             |
| `increasing`                 | For trend configs, whether it watches an increasing (`true`) or decreasing (`false`) trend.                                                                                                                                                                            |
| `sort_order`                 | The config's position in the web app's signal settings list.                                                                                                                                                                                                           |
| `signal_count_7d`            | How many signals the config produced in the last 7 days — a good proxy for how much of your feed it drives. For a `user`-scoped config this counts signals delivered to you; for a shared (`customer` or `domain`) config it counts every signal the config generated. |

A `message` explains when the account has no readable active configs or a requested `signal_config_ids` value is not visible. Otherwise the REST API omits the field and the `ListSignalConfigs` MCP tool returns it as `null`.

### File download

Set `file_name` to a filename ending in `.csv`, `.xlsx` for an Excel workbook, or `.json`, to download the matching configs. The file contains one row per config and one column per response field. `advanced_query` contains compact JSON text within its cell in a `.csv` or `.xlsx`, and stays nested in a `.json`.

The response keeps any explanatory `message`, adds an authenticated Sumble download URL and file details, and returns an empty `signal_configs` array because the rows are in the file. Ask Sumble and Slack attach the file automatically. Other MCP clients should present the download URL instead of recreating the file with code execution.

### Credit cost

Free — this endpoint does not consume credits.

## List signal configs

> List the signal configs that decide which signals you receive -- their names, types, priorities, lookback windows, and filters, plus how many signals each has produced in the last 7 days and a link to its settings page. Read-only, and scoped exactly as the web app's signal settings page is: your own configs, your Sumble Enterprise account's shared configs, or your email domain's shared configs, whichever apply to you. Normal listings exclude deleted configs; an explicit ID lookup can return an authorized deleted config without a settings link. Free -- does not consume credits.

```json
{"openapi":"3.1.0","info":{"title":"Sumble API","version":"v9"},"servers":[{"url":"https://api.sumble.com"}],"security":[{"api_token":[]}],"components":{"securitySchemes":{"api_token":{"type":"http","scheme":"bearer"}},"schemas":{"ListSignalConfigsRequest":{"properties":{"filter":{"$ref":"#/components/schemas/ListSignalConfigsFilter","description":"Filter criteria for the signal configs listing."}},"additionalProperties":false,"type":"object","title":"ListSignalConfigsRequest"},"ListSignalConfigsFilter":{"properties":{"signal_config_ids":{"anyOf":[{"items":{"type":"integer","exclusiveMinimum":0},"type":"array"},{"type":"null"}],"title":"Signal Config Ids","description":"Signal config IDs to look up, including authorized deleted configs. Cannot be combined with `types` or `priorities`. IDs not visible to your account are reported in the response `message` rather than returned."},"types":{"anyOf":[{"items":{"$ref":"#/components/schemas/SignalTypeEnum"},"type":"array"},{"type":"null"}],"title":"Types","description":"Signal config types to return."},"priorities":{"anyOf":[{"items":{"type":"string","enum":["high","medium","low"]},"type":"array"},{"type":"null"}],"title":"Priorities","description":"Signal config priorities to return."}},"additionalProperties":false,"type":"object","title":"ListSignalConfigsFilter"},"SignalTypeEnum":{"type":"string","enum":["project","org_technology_first_mentions","team_technology_first_mentions","job_function_recent_hires","job_function_any_mentions","job_keyword_any_mentions","technology_any_mentions","technology_trends","technology_recent_hires","job_function_trends","champion_alert","funding_event"],"title":"SignalTypeEnum"},"SignalConfigsResponse":{"properties":{"signal_configs":{"items":{"$ref":"#/components/schemas/SignalConfig"},"type":"array","title":"Signal Configs"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"Explains when the account has no signal configs or a requested `signal_config_ids` value is not visible. Otherwise the REST API omits this field and MCP returns it as null."}},"type":"object","required":["signal_configs"],"title":"SignalConfigsResponse"},"SignalConfig":{"properties":{"id":{"type":"integer","title":"Id","description":"The signal config's ID. Matches `signal_config_id` on the signals it generates."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"The config's display name, as shown in the web app."},"slug":{"type":"string","title":"Slug","description":"Stable slug identifying the config."},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The kind of event this config watches for. Matches the `type` field on the signals it generates."},"priority":{"anyOf":[{"type":"string","enum":["high","medium","low"]},{"type":"null"}],"title":"Priority","description":"Priority stamped on every signal this config generates. Matches the `priority` field on those signals."},"scope":{"type":"string","enum":["user","customer","domain"],"title":"Scope","description":"Who the config belongs to: 'user' (yours alone), 'customer' (shared across your Sumble Enterprise account), or 'domain' (shared across everyone at your email domain). Only 'user' configs are yours to change."},"sumble_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sumble Url","description":"Web app URL for this config's settings page. For deleted configs, whose settings page no longer exists, the REST API omits this field and MCP returns it as null."},"deleted":{"type":"boolean","title":"Deleted","description":"Whether the config has been deleted. Deleted configs are returned only for explicit `signal_config_ids` lookups.","default":false},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sort Order","description":"The config's position in the web app's signal settings list."},"days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days","description":"Lookback window, in days, over which the config evaluates matching activity."},"job_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Level","description":"Job level the config restricts people-movement matches to."},"sales_play":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sales Play","description":"Free-text sales play attached to the config, shown with its signals."},"increasing":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Increasing","description":"For trend configs, whether it watches for an increasing (true) or decreasing (false) trend."},"filter_by":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"How the config selects matches: 'advanced_query' (see `advanced_query`) or 'customer_people' (tracked people from your CRM)."},"people_filter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"People Filter","description":"Additional people filter applied to people-movement configs."},"advanced_query":{"anyOf":[{"$ref":"#/components/schemas/AdvancedQuery"},{"type":"null"}],"description":"The config's advanced query: the filter tree deciding which organizations, technologies, job functions, and other attributes match."},"signal_count_7d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Count 7D","description":"How many signals this config produced in the last 7 days -- a good proxy for how much of the feed it drives. Counted the same way the web app counts it: for a 'user'-scoped config, signals delivered to you; for a shared ('customer' or 'domain') config, every signal the config generated."}},"type":"object","required":["id","slug","scope"],"title":"SignalConfig","description":"One signal config, as the owning user sees it in the web app."},"AdvancedQuery":{"properties":{"operator":{"type":"string","enum":["AND","OR","EQ","NOT EQ","IN","NOT IN","IN ALL","NOOP"],"title":"Operator"},"children":{"anyOf":[{"items":{"$ref":"#/components/schemas/AdvancedQuery"},"type":"array"},{"type":"null"}],"title":"Children"},"field":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field"},"value":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"string","format":"date"},{"type":"null"}],"title":"Value"},"values":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"items":{"type":"integer"},"type":"array"},{"items":{"type":"string","format":"date"},"type":"array"},{"items":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"string","format":"date"}]},"type":"array"},{"type":"null"}],"title":"Values"}},"type":"object","required":["operator"],"title":"AdvancedQuery"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v9/signals/configs":{"post":{"tags":["signals"],"summary":"List signal configs","description":"List the signal configs that decide which signals you receive -- their names, types, priorities, lookback windows, and filters, plus how many signals each has produced in the last 7 days and a link to its settings page. Read-only, and scoped exactly as the web app's signal settings page is: your own configs, your Sumble Enterprise account's shared configs, or your email domain's shared configs, whichever apply to you. Normal listings exclude deleted configs; an explicit ID lookup can return an authorized deleted config without a settings link. Free -- does not consume credits.","operationId":"list_signal_configs__api_version__signals_configs_post","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ListSignalConfigsRequest"},{"type":"null"}],"title":"Model"}}}},"responses":{"200":{"description":"Signal configs matching the requested filters. Free -- does not consume credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalConfigsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```
