Skip to main content

Overview

The Signals API exposes Scrunch’s nightly detection sweep as a queryable feed. Each signal is a statistically-tested movement — a level change or trend — in one of your brand’s AI visibility metrics on a specific slice of your data (a platform, topic, or the account as a whole). Use it to feed alerts into your own tools, drive weekly briefs, or automate follow-up on the same “what changed” events surfaced in the Scrunch dashboard.

What the Signals API includes

  • Detected level changes and trends on core metrics (presence_rate, position_top_rate, cited_domain_rate)
  • A confidence tier for each signal (high, confident, worth_a_look, provisional), with noise-floor tiers available on request
  • Human-readable narrative: what happened, why it matters, and what to do
  • A stable fingerprint for each underlying issue — the same signal keeps its fingerprint across nightly re-detections, so reactions and downstream state survive
  • Reactions (useful, not_useful, dismissed, actioned) with optional free-text reasons, listable brand-wide for team-level reporting
  • Anchor dates (distinct detection days) for building date pickers and polling loops
Signals are dedup-to-latest per identity: over a multi-day range you see one row per underlying issue, not one row per re-detection.

When to use the Signals API

Use the Signals API when you need to:
  • Post “what changed this week” summaries to Slack, email, or a stakeholder digest
  • Route detected drops on a specific platform, topic, or metric into an incident tracker
  • Export the team’s reactions on signals for reporting or feedback loops
  • Build a custom alerting dashboard that mirrors the Scrunch Signals feed
For ad-hoc “how is metric X trending” questions, use the Query API — Signals only surfaces movements that pass detection thresholds.

Endpoints

All endpoints require a bearer token with the query scope. Reaction writes additionally require a user token (JWT) — API keys have no user identity to attribute a reaction to and receive 403. See Authentication.

Filters

The list endpoint accepts: The reactions list endpoint supports fingerprint (all reactions on one signal identity) and reaction (all reactions of a given value).

Example: list recent high-confidence signals

Response:

Example: get one signal’s full narrative

getSignal returns 404 for IDs that exist but aren’t user-facing (non-fired detections or cluster-child rows) — the same population rule as the list endpoint.

Example: react to a signal

Reactions are keyed on the signal’s stable fingerprint, so a thumbs-up survives the nightly re-detection of the same underlying issue. This call requires a user token (JWT).
Clear a reaction with DELETE /v1/{brand_id}/signals/{signal_id}/reaction.

Example: list team reactions

The reactions list is brand-wide — it returns every user’s reactions, not just the caller’s — so an integration can export the team’s aggregate feedback.
Filter by fingerprint to pull every reaction on one signal identity across re-detections.

Example: poll for new detection dates

Every returned date has at least one user-facing signal. Use it to drive a date picker or as a cheap check before pulling the full list.

URL movers on citation signals

For cited_domain_rate signals, each response includes a url_movers array — the per-URL citation movers behind the movement. Each mover carries: url_movers is empty for non-citation metrics and for signals detected before movers were recorded.

Filter signals by mover URL

Use mover_url to narrow the feed to signals whose citation movers touch a specific page or domain fragment. The match is a case-insensitive substring against each mover’s normalized_url.
Example mover on a returned signal:
Signals without any URL movers never match mover_url, so combine it with metric=cited_domain_rate when you want a citation-focused feed. % and _ in the input are matched literally.

Signal identity and dedupe

Every signal carries a fingerprint — a hash over its slice and metric — that stays stable across the nightly re-detection of the same underlying issue. Two implications:
  • List responses dedupe to the latest detection. Over a multi-day anchor_from/anchor_to window you see one row per fingerprint, not one per day.
  • Reactions follow the fingerprint, not the row ID. A useful set today still applies to tomorrow’s re-detection of the same signal.
Persist the fingerprint (not the numeric id) if you need to correlate signals across runs in your own system.

Track one issue over time

Use the fingerprint filter with a wide anchor_from to follow a single issue through remediation. A later detection with the opposite direction on the same fingerprint is the recovery (or regression) of the original movement. Fetch the original drop:
Then check whether the same fingerprint has since flipped back up:
Signal detections are retained for 180 days, which covers a 90–120 day remediation tracking window.

Best practices

  • Poll /signals/anchors first to check whether a new detection day exists before pulling the full list.
  • Sort by detected_desc for “what’s new” digests, score_desc for “what matters most”, and delta_desc when ranking by raw movement.
  • Store the fingerprint alongside your internal record so reactions and follow-up state survive re-detections.
  • Use the reactions list to close the loop on “which alerts drove action” — filter by reaction=actioned for a running list of resolved signals.
  • For automated triage from an AI assistant, the same feed is available through the Scrunch MCP server via the list_signals and get_signal tools.