Overview
Webhooks allow you to receive real-time notifications when events occur in the Gather API. Configure webhooks to be notified when interviews are completed, statuses change, or audio generation finishes.Webhook Events
The following events are available. Interview & question eventsquestion.audio_generated- Question audio generation completedinterview.created- Interview createdinterview.updated- Interview updated
candidate_interview.invited- Invite sent to a candidatecandidate_interview.partially_completed- Candidate answered some but not all questionscandidate_interview.completed- Candidate completed the interviewcandidate_interview.status_changed- Candidate interview status changedcandidate_interview.expired- Candidate interview expired before completion
workflow.enrollment.created- Candidate enrolled in a job workflowworkflow.enrollment.completed- Candidate passed the final workflow stepworkflow.enrollment.failed- Candidate failed a gated workflow stepworkflow.step.invited- Invite sent for a workflow stepworkflow.step.completed- Workflow step gate passedworkflow.step.failed- Workflow step gate failedworkflow.step.waiting_for_evaluation- Step awaiting asynchronous evaluation
Only the event names listed above are accepted when creating or updating a subscription. Subscribing (or updating) with an unknown event name is rejected with a
400; a request mixing valid and invalid names is rejected as a whole. Pre-existing configurations that contain legacy event names continue to read without error.Webhook Delivery Format
Each webhook is delivered as an HTTPPOST to your configured URL.
Request Headers
Request Body
The request body is a flat JSON object containing event-specific fields. The event type is not included in the body — read it from theX-Qualifi-Event header.
Example for candidate_interview.completed:
Webhook Configuration
Webhooks can be configured per organization/team via the Gather API’s webhook configuration endpoints (
/qsi/gather/webhooks — create, list, get, update, delete). Use the Webhook Delivery Logs endpoint to retrieve delivery history.Deleting a configuration that has delivery history is rejected with a
400 to prevent accidental loss of that history. To delete the configuration and its deliveries, send DELETE /qsi/gather/webhooks/:id?deleteDeliveries=true.Configuration Options
- Multiple URLs: Supports multiple webhook URLs per organization
- Event Filtering: Configure which events to receive
- Retry Logic: Automatic retries with exponential backoff (3 attempts)
- Signature Verification: HMAC-SHA256 signature for security
Webhook Delivery Logs
Retrieve a paginated history of webhook delivery attempts for the authenticated organization, sorted newest-first. Useful for debugging failed deliveries and reconciling expected vs. received events.Webhook secrets are never returned in delivery logs.
Endpoint
GET /qsi/gather/webhook-deliveries
Query Parameters
string
Override team scope (must be allowed for the API key).
string
Filter to a single webhook configuration.
string
Filter by event type, e.g.
candidate_interview.completed.string
One of
pending, processing, completed, failed.string
Filter to deliveries whose payload contains this candidate interview ID. Useful for tracing the events emitted for a specific interview.
string
Inclusive lower bound on
createdAt (ISO 8601).string
Inclusive upper bound on
createdAt (ISO 8601).number
Page number, 1-indexed. Default
1.number
Records per page, max
200. Default 50.Response
Status State Machine
Webhook Signature Verification
Every delivery is signed two ways. New integrations should verify the recommended timestamped signature (X-Qualifi-Signature-V2); the legacy hex signature is kept only for backward compatibility.
Recommended: timestamped signature (X-Qualifi-Signature-V2)
The X-Qualifi-Signature-V2 header has the form t=<timestamp>,v1=<hex>, where <hex> is the HMAC-SHA256 of the string "<timestamp>.<rawBody>" using your webhook secret, and <timestamp> is also sent in X-Qualifi-Timestamp. Because the timestamp is signed, this scheme lets you reject replayed deliveries.
- Parse
tandv1from theX-Qualifi-Signature-V2header. - Reject the delivery if
tis outside your tolerance window (recommended: 5 minutes, i.e.|now − t| > 300s). - Compute
HMAC-SHA256(secret, "<t>.<rawBody>")and compare it tov1in constant time.
Deprecated: hex signature (X-Qualifi-Signature)
The X-Qualifi-Signature header contains the HMAC-SHA256 hex digest of the raw JSON request body. It has no replay protection (the timestamp is not signed) and is deprecated — verify X-Qualifi-Signature-V2 instead. To verify it: compute HMAC-SHA256 of the raw body string with your secret and compare to the header.
Signature verification must use the exact raw JSON string from the request body. Re-serializing a parsed JSON object can change key order or whitespace and cause verification to fail.
Example Verification (timestamped)
- JavaScript
- Python
Event Details
question.audio_generated
Triggered when question audio generation completes. Header:X-Qualifi-Event: question.audio_generated
candidate_interview.completed
Triggered when a candidate completes an interview. May fire when status changes tonew_response or when the interview completion worker processes the interview.
Header: X-Qualifi-Event: candidate_interview.completed
candidate_interview.status_changed
Triggered when candidate interview status changes. Header:X-Qualifi-Event: candidate_interview.status_changed
candidate_interview.invited
Triggered after an interview invite is actually sent to a candidate (not on mere record creation). For invites sent as part of a workflow step,workflow.step.invited fires instead, so the two never double-fire.
Header: X-Qualifi-Event: candidate_interview.invited
candidate_interview.partially_completed
Triggered when a candidate has answered some, but not all, of an interview and the interview transitions from invited to partially completed. Header:X-Qualifi-Event: candidate_interview.partially_completed
candidate_interview.expired
Triggered when an invited or partially-completed candidate interview expires before completion. Header:X-Qualifi-Event: candidate_interview.expired
interview.created
Triggered when a new interview is created. Header:X-Qualifi-Event: interview.created
interview.updated
Triggered when an interview is updated. Header:X-Qualifi-Event: interview.updated
workflow.enrollment.created
Triggered when a candidate is enrolled in a job workflow. Organization/team scope is derived from the enrollment’s job. Header:X-Qualifi-Event: workflow.enrollment.created
workflow.enrollment.completed
Triggered when a candidate passes the final step of a workflow. Header:X-Qualifi-Event: workflow.enrollment.completed
workflow.enrollment.failed
Triggered when a candidate fails a gated workflow step; no further step invites are sent. Header:X-Qualifi-Event: workflow.enrollment.failed
workflow.step.invited
Triggered after an invite is sent for a workflow step.inviteUrl is the candidate-facing link with internal tokens removed; candidateInterviewId or candidateMeetingId is present depending on the step type.
Header: X-Qualifi-Event: workflow.step.invited
workflow.step.completed
Triggered when a workflow step’s gate passes.hasNextStep indicates whether a subsequent step exists (a workflow.step.invited for the next step follows when it does). score/scoreThreshold are present when the step is scored.
Header: X-Qualifi-Event: workflow.step.completed
workflow.step.failed
Triggered when a workflow step’s gate fails. Header:X-Qualifi-Event: workflow.step.failed
workflow.step.waiting_for_evaluation
Triggered when a step’s gate cannot be decided yet and is awaiting asynchronous evaluation (e.g. interview scoring). Header:X-Qualifi-Event: workflow.step.waiting_for_evaluation
Retry Logic
Webhooks use exponential backoff for failed deliveries:- First attempt: Immediate
- Second attempt: After 1 minute
- Third attempt: After 5 minutes
If all retry attempts fail, the webhook delivery is marked as failed. Check your webhook endpoint availability and error handling.
Best Practices
- Verify Signatures: Always verify webhook signatures to ensure authenticity
- Idempotency: Handle duplicate webhook deliveries gracefully
- Quick Response: Respond to webhooks quickly (within 5 seconds)
- Error Handling: Return appropriate HTTP status codes
- Logging: Log all webhook events for debugging
Related Resources
Handling Webhooks
Step-by-step guide for handling webhooks
Candidate Interviews
Learn about candidate interview events

