Overview
Webhooks allow you to receive real-time notifications when events occur in the Gather API. This guide walks you through setting up and handling webhooks.Setting Up Webhooks
Webhooks are configured per organization/team via the Gather API’s webhook configuration endpoints (
/qsi/gather/webhooks — create, list, get, update, delete). See the Webhooks API reference for events and delivery details.Configuration Requirements
- Webhook URL: Your endpoint URL that will receive webhook events
- Event Types: Which events you want to receive
- Webhook Secret: Secret key for signature verification
Webhook Endpoint Setup
Your webhook endpoint should:- Accept POST requests
- Respond quickly (within 5 seconds)
- Return appropriate HTTP status codes
- Verify webhook signatures
Basic Endpoint Structure
- JavaScript (Express)
- Python (Flask)
Verifying the Timestamped Signature (recommended)
Every delivery includesX-Qualifi-Timestamp and X-Qualifi-Signature-V2 (formatted t=<timestamp>,v1=<hex>), where the signature is computed over "<timestamp>.<rawBody>". Prefer this over the deprecated X-Qualifi-Signature header because the signed timestamp lets you reject replayed deliveries within a tolerance window (recommended: 5 minutes).
- JavaScript (Express)
- Python (Flask)
The
X-Qualifi-Signature header shown in the endpoint examples above is deprecated but still sent for backward compatibility. New integrations should verify X-Qualifi-Signature-V2.Handling Events
Interview Completed
When a candidate completes an interview, the request includesX-Qualifi-Event: candidate_interview.completed and a flat JSON body:
Audio Generated
When question audio generation completes (X-Qualifi-Event: question.audio_generated):
Status Changed
When candidate interview status changes (X-Qualifi-Event: candidate_interview.status_changed):
status for the new value; previousStatus may be null if the prior status was not captured.
When status changes to
new_response, you may receive both candidate_interview.status_changed and candidate_interview.completed webhooks.Candidate Interview Lifecycle & Workflow Events
Switch onX-Qualifi-Event to handle the remaining events. Each payload schema and a sample delivery are documented in the Webhooks API reference.
- Candidate interview lifecycle:
candidate_interview.invited,candidate_interview.partially_completed,candidate_interview.expired— track an interview from invite through completion or expiry.invitedfires on the actual invite send (not record creation), and workflow-step invites useworkflow.step.invitedinstead, so the two never double-fire. - Workflow lifecycle:
workflow.enrollment.created,workflow.enrollment.completed,workflow.enrollment.failedand the per-stepworkflow.step.invited,workflow.step.completed,workflow.step.failed,workflow.step.waiting_for_evaluation— follow a candidate through a multi-step job workflow. UseenrollmentIdto correlate step events with their enrollment.
Best Practices
- Verify Signatures: Always verify webhook signatures to ensure authenticity
- Idempotency: Handle duplicate webhook deliveries gracefully using event IDs or timestamps
- Quick Response: Respond to webhooks quickly (within 5 seconds) to avoid retries
- Error Handling: Return appropriate HTTP status codes (200 for success, 4xx/5xx for errors)
- Logging: Log all webhook events for debugging and auditing
- Async Processing: Process webhook data asynchronously if operations take time
Retry Logic
The Gather API retries failed webhook 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. Ensure your endpoint is available and handles errors gracefully.
Testing Webhooks
Use a tool like ngrok to test webhooks locally:Related Resources
Webhooks API
Complete webhook API reference
Error Handling
Learn about error handling best practices
Best Practices
Review API best practices

