Webhook Setup
Receive real-time notifications when interviews complete and analysis finishes using webhooks.
Webhook Setup
Webhooks let you receive real-time notifications from Koji when key events happen in your project — most importantly, when an interview completes and its analysis is ready. Instead of polling the API, you provide a URL and Koji sends the data to you.
Why Use Webhooks
Polling the API to check if an interview's analysis is done works, but it has drawbacks: unnecessary requests, delayed detection, and wasted resources. Webhooks solve all of these by pushing data to your server the moment it is available.
Common use cases for webhooks include:
- Syncing results to your database as soon as analysis completes
- Triggering downstream workflows like sending a thank-you email to respondents
- Updating dashboards in real time as new interviews come in
- Alerting your team when a high-priority interview finishes
- Aggregating structured answers from scale, choice, and ranking questions across interviews
Configuring a Webhook
Set up webhooks from your project settings:
- Open your project in Koji.
- Navigate to Settings > Integrations > Webhooks.
- Click Add Webhook Endpoint.
- Enter your endpoint URL. This must be an HTTPS URL that accepts POST requests.
- Select the events you want to receive.
- Click Save.
Koji sends a verification request to your endpoint when you save it. Your server must respond with a 200 status code to confirm it is ready to receive events.
Supported Events
| Event | Trigger | Description |
|---|---|---|
interview.completed | Interview is marked complete | Fires when the complete endpoint is called or the interview ends naturally |
interview.analysis_ready | Analysis finishes processing | Fires when the automatic analysis pipeline finishes and results are available |
interview.quality_scored | Quality score is assigned | Fires when the quality gate has evaluated the interview |
You can subscribe to one or more events per webhook endpoint. Most integrations subscribe to interview.analysis_ready since that is when actionable data is available.
Webhook Payload
Koji sends a POST request to your endpoint with a JSON body:
{
"event": "interview.analysis_ready",
"timestamp": "2025-01-15T10:26:15Z",
"project_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"interview_id": "f8e7d6c5-b4a3-2109-8765-432109876543",
"status": "completed",
"analysis_status": "completed",
"quality_score": 4.2,
"respondent": {
"id": "r_abc123def456",
"display_name": "Jane Doe",
"external_id": "user_12345"
},
"stats": {
"duration_seconds": 1530,
"total_messages": 37
},
"metadata": {
"segment": "power_users",
"source": "onboarding_flow"
},
"structured_answers_summary": {
"has_structured_answers": true,
"question_count": 3,
"question_types": ["scale", "single_choice", "yes_no"]
}
}
}
The payload includes enough information to identify the interview and decide if you need to fetch full results. The structured_answers_summary field indicates whether the interview collected structured data and how many questions were answered.
To retrieve the complete transcript, analysis, and full structured answers, call GET https://koji.so/api/v1/interviews/:interview_id using your API key.
Structured Answer Data
When you fetch the full interview after receiving a webhook, the analysis includes a structured_answers array. Each structured answer contains:
questionIdandquestionText— identifies which question was answeredquestionType— scale, single_choice, multiple_choice, ranking, or yes_nostructuredValue— the typed response (number for scale, string for single choice, string array for multiple choice or ranking, boolean for yes/no)qualitativeAnswer— any additional context the respondent providedconfidence— how confident the analysis is in the extracted answerfollowUpInsights— insights from follow-up probing
This enables programmatic aggregation of quantitative data alongside qualitative insights across all interviews in your project.
Verifying Webhook Signatures
Every webhook request includes a signature header that lets you verify the request genuinely came from Koji:
X-Koji-Signature: sha256=abc123...
To verify the signature:
- Retrieve the raw request body as a string (before any JSON parsing).
- Compute an HMAC-SHA256 of the body using your webhook secret as the key.
- Compare the computed hash with the value in the
X-Koji-Signatureheader.
const crypto = require('crypto');
function verifyWebhookSignature(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Your webhook secret is displayed once when you create the webhook endpoint. Store it securely.
Always verify signatures before processing webhook data. Without verification, an attacker could send fake events to your endpoint.
Responding to Webhooks
Your endpoint must return a 2xx status code within 10 seconds to acknowledge receipt. If Koji does not receive a successful response, it retries the delivery.
Retry Policy
- Immediate retry after the first failure.
- Exponential backoff for subsequent retries: 1 minute, 5 minutes, 30 minutes, 2 hours.
- Maximum retries: 5 attempts over approximately 2.5 hours.
- After all retries are exhausted, the event is marked as failed. You can see failed deliveries in the webhook logs on your Integrations page.
Best Practices for Handling Webhooks
- Return 200 immediately. Do your heavy processing asynchronously after acknowledging receipt. If your processing takes more than 10 seconds, the webhook times out.
- Be idempotent. Koji may send the same event more than once (for example, if your server returned 200 but the connection dropped before Koji received the response). Use the
interview_idand event type to deduplicate. - Log everything. Store raw webhook payloads so you can debug issues later.
- Monitor failures. Check the webhook logs in your Integrations page regularly.
Testing Webhooks
The Integrations page includes a Send Test Event button for each webhook endpoint. This sends a sample payload to your URL so you can verify your handler works correctly before real interviews generate events.
During development, tools like ngrok or similar tunneling services let you expose a local server to receive webhook deliveries.
Troubleshooting
If your webhook is not receiving events:
- Check the endpoint URL is correct and accessible from the internet.
- Verify HTTPS. Koji only delivers webhooks to HTTPS URLs.
- Check your firewall allows incoming requests from Koji's IP ranges.
- Review the delivery logs in Settings > Integrations > Webhooks for error details.
- Confirm event subscription. Make sure you are subscribed to the events you expect.
Next Steps
Related Articles
Exporting Research Data from Koji: CSV, JSON, and Transcript Access
A complete guide to every way you can get your interview data out of Koji — from one-click CSV downloads to real-time webhook pipelines.
Send Research Insights to Slack: Real-Time Customer Interview Notifications via Webhooks
Pipe customer interview insights from Koji into your Slack workspace in real time. Use Koji webhooks to notify a #research channel the moment an interview completes, post quote highlights to #product-feedback, or alert #cs-alerts when a churn signal is detected. Step-by-step setup with a working Slack incoming webhook recipe.
Connect Koji to Zapier: Automate Customer Research Workflows in Minutes
Route every completed AI customer interview from Koji into 6,000+ Zapier apps — including Notion, Linear, Salesforce, Airtable, and Gmail. A step-by-step integration guide.
API Authentication
Learn how to authenticate with the Koji API using API keys and Bearer tokens.
User Research API: Embed AI Interviews into Any Product or Workflow
How to use Koji's User Research API to run AI-moderated interviews from your own backend. Covers REST endpoints, the embed widget, webhooks, authentication, rate limits, and headless interview patterns.
Sync Koji Customer Interviews to HubSpot: Live Insights on Every Contact
Push Koji interview transcripts, themes, and quality scores onto HubSpot contact and company records in real time using webhooks and the HubSpot API.
Completing Interviews via API
Use the POST /complete endpoint to finish an interview session and trigger automatic analysis.
Research Automation: How to Build Real-Time Research Pipelines with Webhooks
Koji webhooks push interview and report data to your systems the instant something happens — enabling Slack alerts, CRM sync, automated tagging, and fully automated research pipelines that operate without manual intervention.
Headless API Overview
Manage interviews programmatically with the Koji REST API — start, message, and complete interviews from your own code.
How to Build a Continuous Product Feedback Loop
A step-by-step guide to building a durable product feedback loop — using trigger-based AI interviews, structured question trend tracking, and webhook integrations to keep your product decisions grounded in real user experience.