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

  1. Navigate to Developers → Webhooks in Spot Thought Admin.
  2. Click Add endpoint, provide the public HTTPS URL you want Spot Thought to call, and choose the events you care about.
  3. 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.
  4. Deploy your endpoint so it accepts POST requests with a JSON body and responds with a 2xx status 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.

Was this page helpful?