Skip to main content
Deutero sends signed HTTP POSTs to your endpoint when things happen: an interview starts or completes, a study fills up, credits run out. Deliveries use the Standard Webhooks scheme. There are two kinds of delivery, and the same code verifies both:

Subscribe an endpoint

create and rotate_secret are the only calls that return the signing secret. Store it before doing anything else.

Verify and parse deliveries

deutero.webhooks needs no API key, so it works in a receiver that never calls the API.

Good practice

  • Use the raw body. The signature covers the exact bytes Deutero sent. Parsing and re-serializing the JSON changes them.
  • Deduplicate. Deliveries can be retried. event.webhook_id (the webhook-id header) is unique per message.
  • Respond quickly with a 2xx, and do slow work in a background job.
  • Don’t trust participant fields as identity. external_participant_id and web_source come from the participant’s link. The signature proves the event came from Deutero, not who the participant is.

Event types

survey_id is the study ID under its older name. created_via is dashboard, import or api (which includes MCP clients). Every event also has type, timestamp, webhook_id and simulated. Flow signals and any event type the SDK doesn’t know yet come back as a plain WebhookEvent, with data as a dict. simulated is True for signals sent from a simulated interview. Get the live list, with each type’s payload fields, from the API:

Timestamps and replays

Deliveries whose webhook-timestamp is more than 5 minutes old (or in the future) are rejected, which protects against replay attacks. Change the window with tolerance= in seconds, or pass tolerance=None to verify stored deliveries you’re replaying:

Test your receiver locally

webhooks.sign builds the headers Deutero would send, so you can exercise your endpoint without a real delivery:

Manage endpoints

delete permanently removes an endpoint, its secret and its delivery log. To stop deliveries temporarily, set enabled=False instead.