Webhooks
Whenever a screener participant starts or completes a run, Spot Thought can push an event to your infrastructure instead of forcing you to poll our APIs. Webhooks are delivered through Svix, so you configure HTTPS endpoints, obtain signing secrets, and subscribe to event types directly from the Spot Thought Admin console.
Registering endpoints
- Navigate to Developers → Webhooks in Spot Thought Admin.
- Click Add endpoint, provide the public HTTPS URL you want Spot Thought to call, and choose the events you care about.
- Spot Thought creates a Svix application for your tenant (UID matches your
account_id). Each endpoint receives its own signing secret; copy it somewhere safe—you’ll need it to verify signatures. - Deploy your endpoint so it accepts
POSTrequests with a JSON body and responds with a2xxstatus within a few seconds.
Spot Thought retries failed deliveries automatically (following Svix’s exponential backoff strategy) until the event is acknowledged with a 2xx response or the retry window expires.
Event types
Currently, screener session lifecycle events are exposed:
- Name
screener-session.created- Description
A participant accepted an invitation and Spot Thought created a session record.
- Name
screener-session.started- Description
The participant began answering your screener (first question rendered).
- Name
screener-session.completed- Description
The participant reached the end of the screener and their responses are ready for ingestion.
Security
Svix signs every delivery using a secret per endpoint. Each request includes:
- Name
svix-id- Description
- Unique message identifier.
- Name
svix-timestamp- Description
Unix timestamp (seconds) when the signature was created.
- Name
svix-signature- Description
Signature string containing one or more HMAC signatures.
Use the Svix libraries for your language to verify the signature before processing the payload.
Verify Svix signature
import { Webhook } from 'svix';
const WEBHOOK_SECRET = process.env.SVIX_WEBHOOK_SECRET!;
export async function handler(req, res) {
const payload = JSON.stringify(req.body);
const headers = {
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
};
const wh = new Webhook(WEBHOOK_SECRET);
try {
const event = wh.verify(payload, headers);
// Process event.payload.screener_sessions
res.status(200).end();
} catch (err) {
res.status(400).send('invalid signature');
}
}
Rotate the Svix secret whenever you suspect compromise. Anyone with the secret can forge requests.
Payload structure
Spot Thought batches screener sessions per event so you can process multiple participants in a single delivery:
Example payload
{
"event_id": "evt_7ff49dfa",
"event_type": "screener-session.completed",
"payload": {
"screener_sessions": [
{
"screener_session": {
"id": "ssn_123",
"publicationId": "pub_456",
"status": "completed",
"participant": {
"id": "par_789",
"email": "avery@example.com",
"externalUid": "crm_123"
},
"createdAt": "2024-11-06T14:01:32.000Z",
"updatedAt": "2024-11-06T14:05:12.000Z"
},
"session_responses": [
{
"questionId": "q_01",
"responseType": "text",
"value": "North America"
}
]
}
]
}
}
Use the event_type to branch your business logic, and read payload.screener_sessions[*].session_responses to hydrate downstream systems.