API
FAQ
Answers about webhook signatures, missing or duplicate events, disabled endpoints, ordering, filters, cost and how these docs stay accurate.
Is the webhook signed? How do I verify it?
Yes. Every request carries Signals-Signature: t=<unix seconds>,v1=<hex>. It is an HMAC-SHA256 of <t>.<raw body>, keyed with the whsec_… secret of the webhook. Compare in constant time and reject timestamps older than 300 seconds. See Verify signatures for the exact steps.
Why didn't I get old events?
A webhook sends only runs that finish after it was added. There is no backfill. Resume and Re-enable are different: they continue where the webhook stopped, so runs that finished while it was paused or disabled are still sent. To load older history, use the pull API.
Why is my endpoint disabled?
Signals disables a webhook when its deliveries fail for 3 days with no success. The row shows a red banner and Re-enable. It is also disabled at once when your server answers 410 Gone. Fix your server, check View deliveries for the failure label, then re-enable. Re-enable queues the dead deliveries again. See Retries and failures.
If you did not pause it and the banner says "The Steve team turned this webhook off", re-enable it when you are ready.
Why do I get duplicate events?
Delivery is at least once. The same POST can arrive twice after a timeout your server did process. A replay sends a run again with a new webhookId. Skip a POST whose webhookId you handled, and skip each page item whose eventId you have. Return 200 for duplicates. See Make your endpoint idempotent.
Why does the webhook not contain the events?
A run can find thousands of items. The POST stays small (about 1 to 2 KB): the run, and per event name a total and a firstPageToken. You read the events with GET /api/public/v1/events?pageToken=…, 100 per page, using an API key. See Read a run's events.
My page token returns 410. What now?
Page tokens are valid for 30 days. Read the run through the pull API instead: call GET /api/public/v1/events?trackerId=…&since=… with the run's trackerId and a since before it ran, and keep the items whose runId is the run's id. A replay does not help here: it only takes dead or failed deliveries, and the delivery log keeps them for 30 days. A 400 means the token was changed or cut short. A 404 means the API key belongs to another organization, or the webhook was deleted.
In what order do events arrive?
Not guaranteed. Signals sends one run at a time per webhook, oldest first, but a retried POST can arrive after newer ones. Inside a page, events are in sequence order. If order matters across runs, sort by detectedAt. The pull API returns events oldest first.
Why is there no LinkedIn engagement in my webhook?
LinkedIn engagement is never sent by webhook or posted to Slack. It is available only through the pull API with source=linkedin_engagement, and in the People tab of a competitor page.
Why is title null on Google ads?
Google's Ads Transparency Center usually shows only an image of the ad. There is no headline to copy. Expect title: null and text: null, and use media[0].url or previewUrl. See Ads events.
Does a webhook cost credits?
No. Webhooks and their pages are free. Credits are spent when trackers run, not when Signals sends a webhook.
Can I filter by project?
Yes. Each webhook has a Projects filter next to Events, Actions and Competitors. An empty filter means all projects. Filters combine with AND. Webhooks belong to the organization, not to a project, so one webhook can cover several projects. Every event body includes projectId (events stored before projects existed may lack it). If you delete a project, its entry in the filter shows as Deleted project and matches nothing.
Can I send events to more than one URL?
Yes, up to 5 webhooks per organization. Each has its own filters and its own secret. Two webhooks cannot share the same URL.
Why does my signature check fail?
Almost always one of three causes: you verified parsed JSON instead of the raw body, you used the old secret after a rotation, or your server clock is off by more than 5 minutes. See Common mistakes.
How do these docs stay in sync with the product?
Event shapes come from the same type definitions the product uses to build the payloads. Examples marked real are captured from real runs of the product. Unmarked ones are samples. The version field only changes on a breaking change. Signals can add new fields at any time, so ignore keys you do not know and do not fail on them.
Do the examples show private data?
No. Examples use public data of real competitors, such as a public ad or a public review. They never contain customer data, secrets or API keys.
Can webhooks and the pull API be used together?
Yes. Many teams use webhooks for live delivery and the pull API for a one-time history load or to catch up after downtime. Both use the same event id, which is eventId in a webhook page.