{"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:31:48.692Z"},"content":[{"type":"documentation","id":"f3d478ec-3b24-44b7-bf0e-9be3d37b2275","slug":"headless-api-overview","title":"Headless API Overview","url":"https://www.koji.so/docs/headless-api-overview","summary":"The Headless API lets you manage Koji interviews programmatically via REST endpoints. Start conversations, exchange messages, and complete interviews from your own backend. Available on all plans with credit-based usage. Rate limited to 60 requests per minute.","content":"The Headless API lets you run Koji interviews entirely from your own backend. Instead of sending participants to a link or embedding an iframe, you make REST API calls to start conversations, send messages, and mark interviews as complete. This is ideal for building fully custom interview experiences or integrating Koji into existing workflows.\n\n## What Is the Headless API?\n\nThink of it as Koji without the front end. Your application controls the entire flow:\n\n1. **Start an interview** by calling the start endpoint. Koji returns an interview ID, a session token, and the first message.\n2. **Exchange messages** by sending participant responses to the message endpoint. Koji replies with follow-up questions.\n3. **Complete the interview** by calling the complete endpoint. Koji triggers its analysis pipeline and generates insights.\n\nYour participants never interact with Koji's interface directly — they interact with whatever UI you build.\n\n## Plan Availability\n\nThe Headless API is available on all Koji plans. Usage is controlled by your credit balance — each interview started via the API consumes credits just like any other interview. See your account settings for current credit balance and usage.\n\n## Getting Started\n\n### Authentication\n\nAll API requests require a Bearer token in the `Authorization` header. You can generate API keys from your project settings.\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\nYour API key must have the appropriate permissions for the endpoints you want to use. See [API Authentication](/docs/api-authentication) for setup instructions.\n\n### Base URL\n\nAll endpoints are available at:\n\n```\nhttps://yourdomain.com/api/v1/interviews\n```\n\n## Core Endpoints\n\n### Start an Interview\n\n```\nPOST /api/v1/interviews/start\n```\n\nCreates a new interview and returns the opening message.\n\n**Request body:**\n\n```json\n{\n  \"respondent\": {\n    \"external_id\": \"crm-contact-456\",\n    \"display_name\": \"Jane Smith\",\n    \"metadata\": {\n      \"source\": \"crm-integration\",\n      \"segment\": \"enterprise\"\n    }\n  },\n  \"mode\": \"text\",\n  \"locale\": \"en\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"interview_id\": \"int_abc123\",\n  \"session_token\": \"stk_xyz789\",\n  \"initial_message\": \"Hi Jane! Thanks for taking the time...\"\n}\n```\n\nThe `respondent` object is optional. If provided, it accepts these fields:\n\n| Field | Purpose |\n|---|---|\n| `external_id` | Your own identifier for matching against your CRM or database |\n| `display_name` | Used to greet the participant and shown in your results |\n| `metadata` | Flexible key-value pairs for segmentation and tracking |\n\nThe `mode` field is optional and defaults to text. The `locale` field is optional and defaults to the study's configured language.\n\n### Send a Message\n\n```\nPOST /api/v1/interviews/:id/message\n```\n\nSends the participant's response and receives the next question.\n\n**Request body:**\n\n```json\n{\n  \"message\": \"I've been using the product for about six months now...\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"message\": {\n    \"role\": \"assistant\",\n    \"content\": \"That's great to hear. What was your initial impression when you first started using it?\"\n  },\n  \"turn_count\": 3,\n  \"is_complete\": false\n}\n```\n\nThe `is_complete` flag tells you whether the interviewer has gathered enough information and is ready to wrap up. You can use this to decide when to call the complete endpoint.\n\n### Complete an Interview\n\n```\nPOST /api/v1/interviews/:id/complete\n```\n\nMarks the interview as finished and triggers Koji's analysis pipeline.\n\n**Response:**\n\n```json\n{\n  \"status\": \"completed\",\n  \"quality_score\": 4.2\n}\n```\n\nOnce completed, the interview appears in your project dashboard with a full transcript, quality score, and generated insights.\n\n### Get Interview Details\n\n```\nGET /api/v1/interviews/:id\n```\n\nRetrieve the full transcript and metadata for a specific interview.\n\n## Structured Questions via API\n\nIf your study includes [structured questions](/docs/structured-questions-guide) (scales, multiple choice, ranking, or yes/no), the AI interviewer will present these during the conversation. When using the Headless API, structured question prompts appear in the assistant's message content. Your UI should handle rendering appropriate input widgets based on the question type indicated in the response.\n\n## Common Use Cases\n\n### In-App Feedback\n\nEmbed a feedback flow inside your own product. When a user triggers a feedback prompt, your backend starts a Koji interview, then your front end presents the conversation in your own UI components.\n\n### CRM Integration\n\nConnect Koji to your CRM pipeline. When a deal reaches a certain stage, automatically trigger an interview with the contact. Responses flow back into the CRM record.\n\n### Chatbot Handoff\n\nRoute specific conversation topics from your existing chatbot to a Koji interview. The participant continues the conversation naturally while Koji handles the research-quality follow-up questions.\n\n### Batch Research\n\nCombine CSV import with the Headless API for large-scale studies. Import your participant list, then programmatically start and manage interviews for each person.\n\n## Rate Limiting\n\nThe API enforces a rate limit of 60 requests per minute to ensure fair usage across all customers. If you exceed the limit, you will receive a `429 Too Many Requests` response. Rate limit information is included in response headers:\n\n| Header | Description |\n|---|---|\n| `X-RateLimit-Limit` | Maximum requests allowed per window |\n| `X-RateLimit-Remaining` | Requests remaining in the current window |\n| `X-RateLimit-Reset` | Unix timestamp when the window resets |\n\nBuild retry logic into your integration to handle rate limit responses gracefully.\n\n## Error Handling\n\nAll error responses follow a consistent format:\n\n```json\n{\n  \"error\": \"Description of what went wrong\"\n}\n```\n\nCommon status codes:\n\n| Code | Meaning |\n|---|---|\n| 401 | Missing or invalid API key |\n| 403 | API key lacks the required permission, or origin not allowed |\n| 404 | Interview not found |\n| 429 | Rate limit exceeded |\n\n## Best Practices\n\n1. **Store interview IDs.** Save the `interview_id` returned by the start endpoint so you can continue the conversation and retrieve results later.\n2. **Respect the is_complete flag.** When the response indicates the interview is ready to wrap up, call the complete endpoint to trigger analysis.\n3. **Handle errors gracefully.** Implement retry logic for transient failures and surface clear error messages to your users.\n4. **Secure your API key.** Never expose your API key in client-side code. All API calls should go through your backend.\n\n## Next Steps\n\n- [API Authentication](/docs/api-authentication) — generate and manage API keys\n- [Sharing Your Interview Link](/docs/sharing-your-interview-link) — alternative ways to collect responses\n- [Structured Questions Guide](/docs/structured-questions-guide) — add interactive question types to your study","category":"Collecting Responses","lastModified":"2026-05-12T03:20:57.112045+00:00","metaTitle":"Headless API Overview — Koji Docs","metaDescription":"Use the Koji REST API to start, manage, and complete interviews programmatically from your own backend code.","keywords":["headless API","REST API","programmatic interviews","API integration","Scale plan","backend integration"],"aiSummary":"The Headless API lets you manage Koji interviews programmatically via REST endpoints. Start conversations, exchange messages, and complete interviews from your own backend. Available on all plans with credit-based usage. Rate limited to 60 requests per minute.","aiPrerequisites":["api-authentication"],"aiLearningOutcomes":["Understand the Headless API architecture","Authenticate API requests","Start, message, and complete interviews via REST","Handle errors and rate limits"],"aiDifficulty":"advanced","aiEstimatedTime":"8 min read"}],"pagination":{"total":1,"returned":1,"offset":0}}