SteveSignalsDocs

Webhooks

Test and manage

Every action in the webhook row menu, the Deliveries sheet, pause and resume, replay, validation and server messages, roles and the public webhook management API.

Everything lives in Developers → Webhooks. Each webhook is one row. You see its status, its filters and when it last delivered.

API keys and webhooks on the Developers page
One row per webhook: status pill, filter pills and last delivery.

Who can do what:

  • Org admins and managers can add, edit, pause, delete, rotate and replay. Other members see the message "Only org admins and managers can manage webhooks."
  • You can have 5 webhooks per organization. At the limit the page says "You can have up to 5 webhooks. Delete one to add another."
  • A row shows Active, Paused or Disabled.

Row menu

Click Webhook actions on a row.

The webhook row menu
Webhook actions: test, deliveries, edit, rotate, pause or resume, delete.
ActionWhat it does
Send test eventQueues a test run webhook with reviews.new at total: 1. Its token returns one sample G2 review. It carries Signals-Test: true, is signed and goes through the normal path, so it arrives within a minute. Active webhooks only. One test can wait at a time.
View deliveriesOpens the Deliveries sheet (below).
EditChange the URL and the filters. The signing secret stays the same.
Rotate secretCreates a new secret and shows it once. The old secret keeps signing for 24 hours, so requests carry two v1= values. See Verify signatures.
PauseStops sending. Deliveries that were waiting stay waiting. A request already in flight still completes.
ResumeStarts sending again, from where it stopped: runs that finished while the webhook was paused are sent, oldest first.
DeleteRemoves the webhook and its delivery log for good. Nothing more is sent, also not deliveries that were waiting. Its page tokens stop working (404). The confirmation reads: "Signals stops sending events to (your URL) and its delivery log is deleted. This can't be undone."

For a Disabled webhook the banner offers Re-enable. Like Resume, it continues where it stopped, and it queues the dead deliveries again. See Retries and failures.

Last delivered does not refresh itself

The Last delivered time updates when you reload the page.

Edit filters

Changes apply to runs sent after the change. Runs already sent keep the counts in their POST, but their pages apply the current filters: after an edit, a page's total and events can differ from those counts. If you remove a project from the filter, its runs stop. If a project in the filter was deleted, the row shows a Deleted project pill and that entry matches nothing.

Deliveries sheet

View deliveries lists the delivery log, newest first. One row is one POST: one run for one webhook. The log keeps 30 days.

The Deliveries sheet
The Deliveries sheet with status, counts, code and timing per run.

Each row shows:

ItemShows
StatusPending, Sending, Delivered, Failed, Dead or Replayed. See Status labels
RunRun and a short run id, with the counts per event name, for example "3 events". A test delivery shows a Test tag and Sample review. A replayed row shows the run of the new delivery that replaced it. Deliveries from before run webhooks show no run and no counts
AttemptAttempt N of 9
DurationThe last attempt's time, N ms
HTTP statusThe status code your server returned
ErrorThe failure label when it failed

Buttons: Resend on a failed row (the same delivery again, same webhookId), Replay on a dead row (a new delivery with a new webhookId), Replay dead at the top (every dead delivery, not failed ones), Load more. The footer reads "Showing N of M deliveries", where M is every delivery of the webhook. When the total is unknown it reads "Showing N deliveries". An empty log reads "No deliveries yet. Send a test event to see one here."

Resend and Replay need an active webhook. The message "This webhook isn't active. Resume it first." appears otherwise. See Replay.

Messages

URL validation

The dialog checks the URL as you type.

MessageCause
Enter the URL to send events to.The field is empty.
This URL is too long.More than 2048 characters.
Enter a full URL, like https://your-app.com/signals-hook.Not a valid URL.
The URL must start with https://.http:// or another scheme.
Use the default https port (443).A custom port.
Remove the username and password from the URL.Credentials in the URL.
Use a hostname, not an IP address.An IPv4 or IPv6 address.
Use a public hostname. localhost and internal names can't receive webhooks.localhost, a name without a dot, or .local, .internal, .lan and similar.
Wildcard DNS services like nip.io or sslip.io can't receive webhooks. Use your own hostname.nip.io, sslip.io, xip.io, localtest.me, lvh.me.

Server messages

MessageCause
You already have a webhook for this URL.Another webhook in your org has the same URL.
You can have up to 5 webhooks. Delete one to add another.The limit is reached.
This webhook isn't active. Resume it first.Test, resend or replay on a paused or disabled webhook.
A test event is already on its way. Wait for it to finish before sending another.A test is still pending.
One of the chosen projects no longer exists. Remove it from the Projects filter.A project in the filter was deleted.
Couldn't load more deliveries. Reopen the log.Load more failed.

Public webhook management API

You can manage webhooks without the app. The same API key authenticates, sent in the x-api-key header. Send test event, Rotate secret and the delivery log are app-only.

Method and pathDoes
GET /api/public/v1/webhooksList up to 5 webhooks, oldest first. Secrets are never returned. Response { "items": [...] }.
POST /api/public/v1/webhooksCreate. Body { "url": "...", "filters": {...} }. Returns 201 with the webhook and its secret, once.
PATCH /api/public/v1/webhooks/{id}Change url, filters and/or status (active or paused). At least one field. With status: "active", resume picks where sending continues (below).
POST /api/public/v1/webhooks/{id}/replayQueue deliveries again. Body below.
DELETE /api/public/v1/webhooks/{id}Delete the webhook and its delivery log. Returns { "deleted": true }.

filters has five lists: eventTypes, subEventTypes, actions (new, updated, removed), domains (lowercase competitor domains) and projectIds. An empty or missing list matches everything.

resume on PATCH takes one of two values:

ValueSends
where_it_stopped (default)Every run that finished since the last one sent, oldest first. Dead deliveries are queued again.
nowOnly runs that finish from now on. Runs that finished while it was paused or disabled are skipped.

The replay body picks what to queue again. Every key is optional, and the keys you send are combined with AND:

KeyNarrows to
statusdead (the default) or failed. Only deliveries with this status are replayed.
deliveryIdsThese deliveries (string[], up to 100). They must also have the status above, so send "status": "failed" to replay failed ones.
runIdThe delivery of one run.
sinceDeliveries created at or after this ISO 8601 time.

An empty body {} replays every dead delivery. Test deliveries are never replayed. One call replays at most 500 deliveries, oldest first; call again until replayed is 0. The response is { "replayed": n }.

A replay is a new delivery with a new webhookId and fresh page tokens. The old row turns Replayed.

Set SIGNALS_HOST to the address of the app you sign in to. The Try it command on the Developers page shows it.

bash
1curl -X POST $SIGNALS_HOST/api/public/v1/webhooks \
2 -H "x-api-key: $SIGNALS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://your-app.com/signals-hook",
6 "filters": { "eventTypes": ["jobs"], "subEventTypes": [], "actions": ["removed"], "domains": ["hubspot.com"] }
7 }'
bash
1curl -X POST $SIGNALS_HOST/api/public/v1/webhooks/$WEBHOOK_ID/replay \
2 -H "x-api-key: $SIGNALS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{ "status": "dead" }'
StatusMeaning
201 / 200Created / OK.
400Invalid body: URL rules, filters, a projectIds entry that does not exist, or a replay body with an unknown key or a bad value.
401Missing or invalid API key.
403The key does not belong to a Signals organization.
404No such webhook in your organization (PATCH, DELETE, replay), or Signals is switched off.
409Another webhook already has this URL, or a replay on a webhook that is not active.
422You already have 5 webhooks (POST).
429More than 30 requests per minute from one IP. Retry after 60 s.

The API errors have the form { "error": "..." }. The full machine-readable spec is at /api/public/docs.