Overview
Webhooks let you receive interview data in real time. After you register a webhook, User Intuition sends an HTTPPOST request to your hook_url every time any
interview in your account is completed — no polling required. A webhook is
account-wide: it covers every study, so you register it once, not per study.
Each request contains the completed interview in the same public shape returned
by Get Interview: study_id, the
participant, status, quality, messages, recording links, and screener
responses.
Register a webhook
Call Create Webhook with the
hook_url
that should receive completed interviews. There is no study_id — the webhook
covers your whole account. The response includes a signing_secret (shown
once) — store it securely to verify signatures.Receive interview data
When any interview in your account completes, your endpoint receives a
POST
request with the interview payload described below.Stop receiving data
Call Delete Webhook with the same
hook_url to unregister it.Webhooks are account-wide: one registration receives completed interviews for
every study in your account. You can register more than one
hook_url, and each
receives a copy of every completed interview. Use the payload’s study_id to tell
which study an interview belongs to.Delivery behavior
| Property | Value |
|---|---|
| Method | POST |
| Content type | application/json |
| Trigger | Fired once per interview, after the interview is finalized |
| Timeout | 30 seconds — respond before then |
| Retries | None. A non-2xx response or a timeout is logged and the interview is not re-delivered |
| Expected response | Any 2xx status. Acknowledge quickly and do heavy processing asynchronously |
Payload
The request body is the completed interview, using the same public field names as the rest of the API. The participant who took the interview is nested underparticipant.
Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier of the interview |
study_id | string | Identifier of the study this interview belongs to |
participant | object | null | Who took the interview. null for anonymous panel interviews |
participant.id | string | Participant identifier |
participant.email | string | null | Participant email, when available |
status | string | Final status of the interview, e.g. completed |
quality | string | null | Quality label: Poor, Fair, Good, or Excellent |
end_reason | string | null | Why the interview ended |
started_at | string (date-time) | null | When the interview started |
duration_seconds | integer | null | Interview length in seconds |
messages | array | null | Turn-by-turn messages exchanged during the interview |
audio_recording_url | string | null | Link to the audio recording, when available |
video_recording_url | string | null | Link to the video recording, for video-mode studies |
screener_responses | array | null | Participant’s screener answers as { question, type, answer } |
Anonymous panel interviews have no identifiable participant, so
participant is
null for them. Internal columns (transcripts of the raw call, internal IDs, and
the like) are never included — the webhook delivers exactly the public interview
shape.Authentication
Every delivery is signed so you can verify it genuinely came from User Intuition. When you register a webhook, the response includes asigning_secret (prefixed
whsec_, shown once). Each request carries two headers:
| Header | Description |
|---|---|
X-UI-Timestamp | Unix timestamp (seconds) when the request was signed |
X-UI-Signature | sha256=<hex> — HMAC-SHA256 of "<X-UI-Timestamp>.<raw body>", keyed with your signing_secret |
Verifying a signature
Recompute the HMAC over"<timestamp>.<raw request body>" using your stored
signing_secret and compare it to X-UI-Signature in constant time. Use the
raw request body bytes — do not re-serialize the parsed JSON, or the signature
won’t match.
Check the timestamp
Reject requests with an
X-UI-Timestamp outside a small window (e.g. 5 minutes)
to prevent replay attacks.Managing webhooks
Create Webhook
Register a
hook_url to receive completed interviews for a study.Delete Webhook
Stop sending completed interviews to a
hook_url.
