Overview
Webhooks and push notifications let your team or downstream systems know immediately when key events occur in your research project. You can use webhooks to automatically notify your own systems, and push notifications to alert users in real time through their browser.
Browser Notifications
- Open Settings from the account menu.
- In UI Preferences, tick Enable notifications.
- Click Save Preferences.
- Allow the browser permission request when prompted.
Notification events
You are notified for:
- Interview Completed — When a participant completes an interview.
- Analysis Complete — When the thematic analysis of an interview finishes.
- Simulation Complete — When a simulation run finishes successfully.
- Credits Exhausted — When your credit balance reaches zero.
- Survey Limit Reached — When a survey reaches its maximum number of responses.
Turning them off
Untick Enable notifications in Settings and save. Your browser subscription is removed.
Webhooks
Webhooks allow external systems to receive signed HTTP POST requests when specific events occur in your organization.
Supported Events
| Event | Description |
|---|---|
interview.completed |
A participant has completed an interview. |
interview.started |
A participant has started an interview — fired once the interview exists, before the first question is answered. |
analysis.completed |
Thematic analysis has finished for an interview. |
simulation.completed |
A simulation run has completed successfully. |
study.created |
A new study has been created. |
credits.exhausted |
Your organization's credit balance has reached zero. |
study.full |
A survey has reached its maximum number of responses. |
Webhook Payload
Each webhook is delivered as an HTTP POST request with the following structure:
{
"type": "interview.completed",
"timestamp": "2024-12-15T14:30:00+00:00",
"data": {
"interview_id": "550e8400-e29b-41d4-a716-446655440000",
"survey_id": "550e8400-e29b-41d4-a716-446655440001",
"completed": true,
"external_participant_id": "u_9f2c…",
"web_source": "newsletter"
}
}
external_participant_id is your own ID for the participant — whatever the entry link's ?participant_id= or the embed metadata carried — and web_source is the link's ?source= tag. Both are null when the interview arrived without them. They are what makes this event actionable: it tells you who finished in your own terms, so you can credit an account or issue a reward without calling the API back. See Rewarding people who finish.
Neither value is authenticated — they come off a link the participant could have edited — so use them to look up your own record, and rely on the signature below as the proof that the event came from Deutero.
interview.started carries the same identities, minus the outcome:
{
"type": "interview.started",
"timestamp": "2024-12-15T14:12:00+00:00",
"data": {
"interview_id": "550e8400-e29b-41d4-a716-446655440000",
"survey_id": "550e8400-e29b-41d4-a716-446655440001",
"participant_id": "550e8400-e29b-41d4-a716-446655440002",
"external_participant_id": "u_9f2c…",
"web_source": "newsletter"
}
}
participant_id is Deutero's own ID for the person — the one every API and MCP call uses — and external_participant_id is yours. external_participant_id and web_source are null when the link carried neither. The event fires as the interview begins, before anyone has answered anything: treat it as "someone has arrived", not as a completion, and expect an interview that never finishes to have a started with no completed after it.
study.created names the study and how it was made — dashboard, import or api (which includes every MCP client):
{
"type": "study.created",
"timestamp": "2024-12-15T09:00:00+00:00",
"data": {
"study_id": "550e8400-e29b-41d4-a716-446655440001",
"survey_id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Meal kit churn",
"project_id": "550e8400-e29b-41d4-a716-446655440003",
"created_via": "api"
}
}
Security
All webhook requests are signed with a per-endpoint secret so you can verify authenticity:
- Header:
webhook-signature— Standard Webhooks signature. - Header:
webhook-id— Unique message ID for idempotency. - Header:
webhook-timestamp— Unix timestamp of delivery.
To verify a webhook in your endpoint:
- Read the raw request body.
- Extract
webhook-id,webhook-timestamp, andwebhook-signaturefrom the headers. - Use the Standard Webhooks library with your endpoint secret to verify the signature.
Creating a Webhook Endpoint
- Navigate to Settings from the account menu.
- Find Create Webhook Endpoint.
- Enter a Label — how you will recognize this endpoint in the list.
- Enter the Endpoint URL.
- Tick the Events you want. Leave every box unchecked to receive every event.
- Click Create Endpoint.
- Copy the signing secret from the confirmation. It is shown only once and cannot be retrieved later.
Endpoints are listed with label, URL, events, status and creation date, and the list header shows how many are active.
Managing Endpoints
- Edit: Update the URL or subscribed events.
- Disable: Temporarily stop receiving events without deleting the endpoint.
- Delete: Permanently remove the endpoint.
Delivery & Retries
- Webhooks are delivered with a 10-second timeout.
- A delivery is considered successful if your endpoint returns an HTTP status code below 300.
- Failed deliveries are logged but are not automatically retried.
Delivery Logs
Each webhook endpoint shows a delivery log with the following information:
- Event Type: The event that was sent.
- Message ID: The unique identifier for the delivery.
- Status Code: The HTTP response code from your endpoint.
- Success: Whether the delivery was successful.
- Error: Any error message if delivery failed.
With MCP
Everything above can be set up from an agent — creating the subscription is the one part of wiring up a study that used to be dashboard-only.
list_webhook_event_types {}
create_webhook {"label": "Rewards", "url": "https://hooks.example.com/deutero",
"events": ["interview.completed"]}
list_webhook_event_types returns every event with what makes it fire and the exact keys its data object carries — read it before subscribing, because an unknown event name is refused, not quietly dropped. An empty events list subscribes to everything.
create_webhook returns signing_secret and it is shown once; store it before doing anything else. If it is lost, rotate_webhook_secret {"webhook_id": "…"} mints a new one — the old one stops verifying the moment it does, so deploy the new one first.
list_webhooks {}
update_webhook {"webhook_id": "…", "enabled": false}
list_webhook_deliveries {"webhook_id": "…", "success": false}
delete_webhook {"webhook_id": "…"}
update_webhook changes only the fields you pass, and a new events list replaces the old one rather than adding to it. list_webhook_deliveries is the log to read when an event never arrived: a failed row means the delivery was attempted and your server refused it, while no row at all means nothing fired — check the endpoint is enabled and subscribed to that event type.
Signals inside an interview
An Interview Flow can also send a webhook mid-interview, from a "Send a signal" step, which is a different thing from the organization-level events above: it fires at a point in the conversation rather than on a lifecycle event, and each step has its own signing secret. get_flow_signals {"study_id": "…"} lists those steps with their URLs and secrets, and get_interview_fetches_and_signals {"interview_id": "…"} shows what one interview actually sent and whether it was accepted.
Best Practices
- Verify Signatures
- Always verify webhook signatures before processing events.
-
Reject requests with invalid signatures immediately.
-
Handle Idempotency
-
Use
webhook-idto deduplicate events if your endpoint is called more than once. -
Return Quickly
- Respond to webhook requests as fast as possible (under 10 seconds).
-
Offload long-running processing to a background queue.
-
Subscribe Selectively
- Only subscribe to events your system actually needs.
-
Reduces unnecessary load on both sides.
-
Monitor Endpoints
- Check delivery logs regularly for failures.
- Keep your endpoint URL up to date if it changes.
Troubleshooting
Common Issues
- Not Receiving Webhooks
- Verify the endpoint URL is correct and publicly accessible.
- Check that the endpoint is enabled in your settings.
-
Ensure your endpoint responds with HTTP 200–299 within 10 seconds.
-
Invalid Signature Errors
- Use the exact raw request body for verification.
-
Ensure you are using the correct secret for the endpoint.
-
Push Notifications Not Appearing
- Check browser notification permissions for this site.
- Re-enable notifications from the Settings page.
-
Some browsers block notifications in private or incognito mode.
-
Endpoint Timeouts
- Return a response immediately and process the event asynchronously.
- Check for slow database queries or external API calls in your handler.
Getting Help
For assistance with webhooks and notifications: - Refer to our Help Center - Contact our support team - Check our knowledge base for tutorials
With MCP
There are no webhook tools — endpoint management is dashboard-only.
Not to be confused with an Interview Flow's Send a signal step, which fires its own signed HTTP call from inside an interview and is configured per step. See Interview Flow.
Last updated: September 2026