{"site":{"name":"Koji","description":"AI-native customer research platform that helps teams conduct, analyze, and synthesize customer interviews at scale.","url":"https://www.koji.so","contentTypes":["blog","documentation"],"lastUpdated":"2026-05-18T13:47:57.767Z"},"content":[{"type":"documentation","id":"41938bf1-ba71-4644-b995-975f1a26a56e","slug":"starting-interviews-via-api","title":"Starting Interviews via API","url":"https://www.koji.so/docs/starting-interviews-via-api","summary":"The POST /api/v1/interviews/start endpoint launches interview sessions programmatically. It accepts a respondent object (with external_id, display_name, and metadata), mode (text/voice), and locale. The response returns interview_id, session_token, and initial_message. API access is available on all plans. Supports structured questions for quantitative data collection.","content":"# Starting Interviews via API\n\nThe `POST /api/v1/interviews/start` endpoint lets you programmatically launch an interview session from your own application. This is the entry point for any headless integration with Koji.\n\n---\n\n## Before You Begin\n\nMake sure you have:\n\n- An API key with the `interview:start` permission. See [API Authentication](/docs/api-authentication) for how to create one.\n- A project with a published research brief.\n- API access is available on all Koji plans, including the free tier.\n\n---\n\n## Endpoint\n\n```\nPOST https://koji.so/api/v1/interviews/start\n```\n\n### Headers\n\n| Header | Value | Required |\n|---|---|---|\n| `Authorization` | `Bearer your_api_key` | Yes |\n| `Content-Type` | `application/json` | Yes |\n\n### Request Body\n\nSend a JSON object with the following fields:\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `respondent` | object | No | Respondent information (see below) |\n| `mode` | string | No | Interview mode: `text` or `voice`. Defaults to the project setting |\n| `locale` | string | No | Language/locale code (e.g., `en`, `es`, `fr`). Defaults to the project setting |\n\n#### Respondent Object\n\nThe `respondent` field accepts an object with these properties:\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `external_id` | string | No | Your own identifier for this respondent, useful for linking back to your system |\n| `display_name` | string | No | Display name for the respondent |\n| `metadata` | object | No | Arbitrary key-value pairs attached to the respondent for your own tracking purposes |\n\nNote that metadata is nested under the `respondent` object, not at the top level of the request body.\n\n### Example Request\n\n```bash\ncurl -X POST https://koji.so/api/v1/interviews/start \\\n  -H \"Authorization: Bearer pk_live_your_key_here\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{'\n    \"respondent\": {\n      \"external_id\": \"user_12345\",\n      \"display_name\": \"Jane Doe\",\n      \"metadata\": {\n        \"segment\": \"power_users\",\n        \"source\": \"onboarding_flow\"\n      }\n    },\n    \"mode\": \"text\",\n    \"locale\": \"en\"\n  }'\n```\n\n---\n\n## Response\n\nA successful request returns a `201 Created` response with a JSON body:\n\n```json\n{\n  \"interview_id\": \"f8e7d6c5-b4a3-2109-8765-432109876543\",\n  \"session_token\": \"st_live_xxxxxxxxxxxxxxxxxxxx\",\n  \"initial_message\": \"Hi Jane! Thanks for taking the time to chat with us today. I'd love to learn about your experience...\"\n}\n```\n\n### Response Fields\n\n| Field | Type | Description |\n|---|---|---|\n| `interview_id` | string | Unique identifier for this interview. Use this for all subsequent API calls. |\n| `session_token` | string | Token required for session-scoped operations like sending messages and completing the interview. Pass it as `X-Session-Token` header. |\n| `initial_message` | string | The first message from the interviewer. Display this to the respondent. |\n\nStore the `interview_id` and `session_token` — you need both for subsequent operations.\n\n**Important:** The response field is `interview_id`, not `conversation_id`. Use `interview_id` consistently across all API calls.\n\n---\n\n## Structured Questions\n\nIf your research brief includes [structured questions](/docs/structured-questions-guide) (scale ratings, multiple choice, ranking, yes/no), the interview will present interactive widgets to the respondent during the conversation. When the interview completes and analysis runs, structured answers are returned alongside qualitative insights.\n\nEach structured answer in the analysis includes:\n\n- `questionId` and `questionText` — identifies which question was answered\n- `questionType` — the type of question (scale, single_choice, multiple_choice, ranking, yes_no)\n- `structuredValue` — the typed response (number for scale, string for single choice, string array for multiple choice or ranking, boolean for yes/no)\n- `qualitativeAnswer` — any additional context the respondent provided\n- `confidence` — how confident the analysis is in the extracted answer\n- `followUpInsights` — insights from follow-up probing\n\nThis enables programmatic aggregation of quantitative data alongside qualitative insights.\n\n---\n\n## Understanding the Response\n\n### interview_id\n\nThis is your primary reference for the interview. Use it to [send messages](/docs/sending-messages-via-api), [complete it](/docs/completing-interviews-via-api), and look it up in your project dashboard.\n\n### session_token\n\nThe session token acts as a secondary authentication layer scoped to this specific interview. It proves that the caller is the same entity that started the interview. You must include it when calling the [message endpoint](/docs/sending-messages-via-api) and the [complete endpoint](/docs/completing-interviews-via-api).\n\n### initial_message\n\nThis is the greeting generated for the respondent based on your research brief, project settings, and any respondent information you provided. Display this message in your interface as the start of the conversation.\n\n---\n\n## Handling Errors\n\n| Status Code | Error | Meaning |\n|---|---|---|\n| 400 | `invalid_request` | Missing required fields or invalid field values |\n| 401 | `unauthorized` | Invalid or missing API key |\n| 403 | `forbidden` | Key lacks `interview:start` permission |\n| 404 | `not_found` | The specified project does not exist |\n| 422 | `unprocessable` | The project has no published brief, or configuration prevents starting |\n| 429 | `rate_limited` | Too many requests. Check [Rate Limits and CORS](/docs/rate-limits-and-cors) |\n\nAll error responses include a JSON body with `error` and `message` fields:\n\n```json\n{\n  \"error\": \"invalid_request\",\n  \"message\": \"The project has no published research brief.\"\n}\n```\n\n---\n\n## Respondent Metadata\n\nThe `metadata` field inside the `respondent` object accepts any flat JSON object. Use it to attach your own tracking data to the respondent. Common use cases include:\n\n- **User segmentation**: `{\"plan\": \"enterprise\", \"tenure_months\": 24}`\n- **Source tracking**: `{\"source\": \"post_purchase_email\", \"campaign_id\": \"camp_123\"}`\n- **A/B testing**: `{\"variant\": \"B\", \"experiment\": \"onboarding_v2\"}`\n\nMetadata is returned when you retrieve the interview and is available in exports and webhooks. It does not affect the interview itself.\n\n---\n\n## Integration Patterns\n\n### Server-to-Server\n\nThe most common pattern is calling the start endpoint from your backend when a user triggers an action (for example, clicking a \"Give Feedback\" button). Your backend starts the interview, receives the response, and passes the `interview_id` and `initial_message` to your frontend.\n\n### Batch Invitations\n\nFor research projects, you might start interviews in batch — for example, iterating through a list of participants and starting an interview for each one. Store the returned `interview_id` and `session_token` for each participant so you can track and complete them later.\n\n### Embedded Experience\n\nCombine the API with the [embed widget](/docs/embed-widget-reference) for a hybrid approach: start the interview server-side for tracking purposes, then hand off the `interview_id` to the embed widget for the conversational UI.\n\n---\n\n## Next Steps\n\n- [Send and receive messages during the interview](/docs/sending-messages-via-api)\n- [Complete the interview and trigger analysis](/docs/completing-interviews-via-api)\n- [Learn about structured questions](/docs/structured-questions-guide)\n- [Explore the headless API overview](/docs/headless-api-overview)\n\n## Further reading on the blog\n\n- [AI-Moderated vs Human-Moderated Interviews: Which Should You Choose?](/blog/ai-moderated-vs-human-moderated-interviews) — AI-moderated and human-moderated interviews each have a time and a place. Here is the honest comparison to help you choose the right approac\n- [Can I Paste User Interviews into ChatGPT? A Guide to GDPR and LLMs](/blog/can-i-paste-user-interviews-into-chatgpt-a-guide-to-gdpr-and-llms) — Every product manager wants to ask an LLM about their user feedback. But pasting customer transcripts into public models is a GDPR nightmare\n- [The Continuous Discovery Handbook: How Product Teams Run Weekly Customer Interviews (2026)](/blog/continuous-discovery-handbook-weekly-customer-interviews) — 64% of software features are rarely or never used. Continuous discovery — weekly customer interviews baked into your product workflow — is t\n\n<!-- further-reading:blog -->\n","category":"API Reference","lastModified":"2026-05-13T00:26:36.807295+00:00","metaTitle":"Starting Interviews via API — Koji Docs","metaDescription":"Learn how to start interviews programmatically using the Koji API POST /start endpoint, including request format, response handling, and integration patterns.","keywords":["start interview api","post start","headless interview","api integration","koji api"],"aiSummary":"The POST /api/v1/interviews/start endpoint launches interview sessions programmatically. It accepts a respondent object (with external_id, display_name, and metadata), mode (text/voice), and locale. The response returns interview_id, session_token, and initial_message. API access is available on all plans. Supports structured questions for quantitative data collection.","aiPrerequisites":["api-authentication"],"aiLearningOutcomes":["Start an interview via the API","Handle the start response correctly","Use metadata for tracking","Choose between text and voice modes"],"aiDifficulty":"intermediate","aiEstimatedTime":"8 min read"}],"pagination":{"total":1,"returned":1,"offset":0}}