Completing Interviews via API
Use the POST /complete endpoint to finish an interview session and trigger automatic analysis.
Completing Interviews via API
Marking an interview as complete triggers Koji's automatic analysis pipeline, which extracts themes, insights, structured answers, and quality scores from the conversation. This is the final step in the API interview lifecycle.
When to Complete an Interview
There are several scenarios where you should complete an interview:
- The respondent finishes naturally. The interview status changes to indicate the conversation has reached its conclusion. Your application should detect this and call complete.
- The respondent leaves early. If the respondent closes their browser or navigates away, complete the interview so that whatever data was collected gets analyzed.
- You want to end it manually. For testing or operational reasons, you might need to end an interview before the conversation naturally concludes.
- A timeout is reached. If your application enforces a maximum interview duration, call complete when the timer expires.
Completing an interview is idempotent — calling it on an already-completed interview returns the same response without re-triggering analysis.
Endpoint
POST https://koji.so/api/interview/complete
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer your_api_key | Yes |
X-Session-Token | session_token_from_start | Yes |
Content-Type | application/json | Yes |
Both the API key and the session token are required. The API key authenticates your application, and the session token verifies that you are the same entity that started this specific interview. See API Authentication for details on both.
Request Body
The request body should include the interview identifier:
| Field | Type | Required | Description |
|---|---|---|---|
interview_id | string | Yes | The interview ID returned from the start endpoint |
reason | string | No | Why the interview ended. Options: natural, respondent_left, timeout, manual. Defaults to manual. |
Example Request
curl -X POST https://koji.so/api/interview/complete \
-H "Authorization: Bearer pk_live_your_key_here" \
-H "X-Session-Token: st_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{'
"interview_id": "f8e7d6c5-b4a3-2109-8765-432109876543",
"reason": "natural"
}'
Response
A successful request returns 200 OK with a summary of the completed interview:
{
"interview_id": "f8e7d6c5-b4a3-2109-8765-432109876543",
"status": "completed",
"completed_at": "2025-01-15T10:25:30Z",
"analysis_status": "processing",
"stats": {
"duration_seconds": 1530,
"respondent_messages": 18,
"interviewer_messages": 19,
"total_messages": 37
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
interview_id | string | The interview identifier |
status | string | Always completed on success |
completed_at | string (ISO 8601) | Timestamp when the interview was marked complete |
analysis_status | string | Status of the automatic analysis: processing, completed, or failed |
stats | object | Summary statistics for the interview |
What Happens After Completion
Completing an interview triggers several automatic processes:
- Transcript finalization. The full conversation is finalized and stored.
- Quality scoring. Koji evaluates the interview quality based on the depth of responses, topic coverage, and respondent engagement.
- Automatic analysis. Koji's analysis engine processes the transcript, extracting themes, insights, and patterns.
- Structured answer extraction. If the interview used structured questions, the analysis extracts typed answers (scale ratings, choices, rankings, yes/no responses) alongside qualitative context.
- Webhook delivery. If you have webhooks configured, Koji sends an event notification when analysis completes.
Analysis typically takes a few seconds to a couple of minutes, depending on the interview length. Poll the interview endpoint or use webhooks to know when results are ready.
Retrieving Results After Completion
Once analysis_status is completed, retrieve the full results:
GET https://koji.so/api/v1/interviews/:interview_id
The response now includes the analysis payload alongside the transcript:
{
"interview_id": "f8e7d6c5-b4a3-2109-8765-432109876543",
"status": "completed",
"transcript": [...],
"analysis": {
"themes": [...],
"insights": [...],
"quality_score": 4.2,
"structured_answers": [
{
"questionId": "q_1",
"questionText": "How likely are you to recommend us?",
"questionType": "scale",
"structuredValue": 8,
"qualitativeAnswer": "Very likely, the product has been transformative.",
"confidence": "high",
"followUpInsights": ["Values the onboarding experience"]
}
]
},
"stats": {
"duration_seconds": 1530,
"respondent_messages": 18,
"interviewer_messages": 19
}
}
The structured_answers array is present when the interview used structured questions. Each entry contains the typed value alongside qualitative context, enabling programmatic aggregation of quantitative data.
Polling for Analysis Completion
If you do not use webhooks, poll the interview endpoint to check when analysis finishes:
async function waitForAnalysis(interviewId, apiKey) {
const maxAttempts = 30;
const delayMs = 2000;
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(
`https://koji.so/api/v1/interviews/${interviewId}`,
{ headers: { 'Authorization': `Bearer ${apiKey}` } }
);
const data = await response.json();
if (data.analysis_status === 'completed') {
return data;
}
if (data.analysis_status === 'failed') {
throw new Error('Analysis failed');
}
await new Promise(resolve => setTimeout(resolve, delayMs));
}
throw new Error('Analysis timed out');
}
Start with a 2-second interval and increase it if analysis takes longer. Most interviews complete analysis within 30 seconds.
Error Handling
| Status Code | Error | Meaning |
|---|---|---|
| 401 | unauthorized | Invalid API key or session token |
| 403 | forbidden | Key lacks interview:complete permission |
| 404 | not_found | Interview does not exist |
| 409 | already_completed | Interview was already completed (response still returns the interview data) |
| 429 | rate_limited | Too many requests |
The 409 response is not an error in the traditional sense — it simply tells you the interview was already finished. The response body contains the same data as a successful completion.
Session Token Requirement
The X-Session-Token header is mandatory for the complete endpoint. This prevents unauthorized parties who might have your API key from completing interviews they did not start.
If you have lost the session token, the interview can still be completed from the Koji dashboard by a team member with appropriate access.
Next Steps
- Set up webhooks to be notified when analysis completes
- Review the authentication model
- Start your integration with the start endpoint
- Learn about structured questions
- Explore the headless API overview
Further reading on the blog
- How to Analyze User Interview Data: A Complete Guide (2026) — You ran the interviews. Now what? This step-by-step guide covers how to turn raw interview data into clear, actionable insights — with and w
Related Articles
Understanding Quality Scores
Learn how Koji evaluates interview quality on a 0-5 scale and why it matters for your research and billing.
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.
Sending Messages via API
Understand how messages flow between your application and Koji during an API-started interview.
Webhook Setup
Receive real-time notifications when interviews complete and analysis finishes using webhooks.
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.