Webhooks
Webhooks let AnswerScout notify your own systems when something happens — a run finishes, your score drops, or a competitor overtakes you. You give AnswerScout a URL, and it sends a signed JSON request to it after each run.
Webhooks and Slack alerts are available on Growth and higher (Growth, Growth & More, Pro). They’re set up under Settings → Notifications in the app.
Events
When you create a webhook, you choose which events it subscribes to:
| Event | Fires when |
|---|---|
run.completed | A run finishes (always available) |
score.dropped | Your visibility score falls by a meaningful amount |
competitor.overtake | A competitor crosses above you for the first time |
dropped.top3 | A prompt where you ranked near the top now drops out of the lead |
Setting one up
- Go to Settings → Notifications and add a Webhook.
- Enter your endpoint URL (must be public and HTTPS).
- Choose the events you want.
- Copy the signing secret — it’s shown once, so store it somewhere safe.
- Use Send test to fire a sample request and confirm your endpoint receives it.
You can have up to five webhooks per account.
Verifying the signature
Every request includes a signature header so you can confirm it really came from AnswerScout and wasn’t tampered with:
X-AnswerScout-Signature: t=1718409600,v1=3ba2...e9tis the timestamp the request was signed.v1is an HMAC-SHA256 of the string`${t}.${rawBody}`using your signing secret.
Recompute it on your side and compare. Here’s a Node.js / Express example:
import crypto from 'node:crypto'
function verifyAnswerScout(req, secret) {
const header = req.get('X-AnswerScout-Signature') || ''
const parts = Object.fromEntries(
header.split(',').map((kv) => kv.split('=')),
)
const signed = `${parts.t}.${req.rawBody}` // rawBody = the exact bytes received
const expected = crypto
.createHmac('sha256', secret)
.update(signed)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(parts.v1),
Buffer.from(expected),
)
}Verify against the raw request body — the exact bytes you received — not a
re-serialized object. Re-stringifying parsed JSON can change whitespace or key
order and the signature won’t match. Also reject requests whose timestamp t
is too old to protect against replays.
Delivery & retries
AnswerScout sends one request per subscribed event that fired on a run. If your endpoint doesn’t return a success response, delivery is retried, and a delivery that already succeeded for a run won’t be sent again — so your handler should be safe to receive the same event more than once (idempotent).