New

Now in Claude, ChatGPT, Cursor & more with our MCP server

Back to docs
API Reference

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:

  1. Open your project in Koji.
  2. Navigate to Settings > Integrations > Webhooks.
  3. Click Add Webhook Endpoint.
  4. Enter your endpoint URL. This must be an HTTPS URL that accepts POST requests.
  5. Select the events you want to receive.
  6. 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

EventTriggerDescription
interview.completedInterview is marked completeFires when the complete endpoint is called or the interview ends naturally
interview.analysis_readyAnalysis finishes processingFires when the automatic analysis pipeline finishes and results are available
interview.quality_scoredQuality score is assignedFires 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:

  • questionId and questionText — identifies which question was answered
  • questionType — scale, single_choice, multiple_choice, ranking, or yes_no
  • structuredValue — 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 provided
  • confidence — how confident the analysis is in the extracted answer
  • followUpInsights — 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:

  1. Retrieve the raw request body as a string (before any JSON parsing).
  2. Compute an HMAC-SHA256 of the body using your webhook secret as the key.
  3. Compare the computed hash with the value in the X-Koji-Signature header.
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_id and 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.