Completing Interviews via API
Use the POST /complete endpoint to finish an interview session and trigger automatic analysis.
Completing Interviews via API
The POST /api/v1/interviews/:id/complete endpoint marks an interview as finished and triggers Koji's automatic analysis pipeline. This is the final step in the API interview lifecycle.
When to Complete an Interview
There are several scenarios where you should call the complete endpoint:
- 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 /api/v1/interviews/:interview_id/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 is optional. You can send an empty object or include:
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Why the interview ended. Options: natural, respondent_left, timeout, manual. Defaults to manual. |
feedback | object | No | Optional respondent feedback collected at the end (e.g., satisfaction rating) |
Example Request
curl -X POST https://app.getkoji.com/api/v1/interviews/f8e7d6c5-b4a3-2109-8765-432109876543/complete \
-H "Authorization: Bearer koji_sk_your_key_here" \
-H "X-Session-Token: st_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"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. Interviews that do not meet the quality threshold may not count toward your usage. See How the Quality Gate Works for details.
- Automatic analysis. Koji's analysis engine processes the transcript, extracting themes, insights, and patterns.
- 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 /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
},
"stats": {
"duration_seconds": 1530,
"respondent_messages": 18,
"interviewer_messages": 19
}
}
The analysis object contains the themes and insights extracted from the conversation, as well as the quality score assigned to this interview.
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://app.getkoji.com/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
Related Articles
API Authentication
Learn how to authenticate with the Koji API using API keys and Bearer tokens.
Starting Interviews via API
Use the POST /start endpoint to programmatically launch interviews from your application.
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.
Embed Widget Reference
Technical reference for the Koji embed widget including iframe parameters and PostMessage API.
Rate Limits and CORS
Understand how Koji's API rate limiting works and how to configure CORS origins for your integration.