{"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-07-14T18:37:36.355Z"},"content":[{"type":"documentation","id":"9b6f96fb-bb72-4925-9149-fee663f4d8f3","slug":"building-with-ai","title":"Building with AI: the Koji API for LLMs and coding assistants","url":"https://www.koji.so/docs/building-with-ai","summary":"A single-page starting point for developers using AI coding assistants (Claude, Cursor, and similar) to build against Koji. Lists the machine-readable resources (llms-full.txt, /api/content), explains the two integration paths (the MCP server for natural-language agentic workflows and the REST Headless API for code), gives a complete one-page REST reference and lifecycle quickstart, and provides a copy-paste context block to hand to an assistant.","content":"# Building with AI: the Koji API for LLMs and coding assistants\n\nThis page is written to be handed straight to an AI coding assistant. Paste its URL (or the context block near the bottom) into Claude, Cursor, or any LLM tool, and it has everything needed to build a working Koji integration. Humans get a fast one-page overview here too, with links to the deeper guides.\n\n---\n\n## Machine-readable resources\n\nPoint your assistant at these first. Each is complete and always current:\n\n- **Full docs as plain text**: `https://www.koji.so/llms-full.txt` (every doc article, including this whole API reference, in one file)\n- **Docs index for LLMs**: `https://www.koji.so/llms.txt` (summary index plus the MCP tool list)\n- **Docs as JSON**: `https://www.koji.so/api/content` (filter with `?type=docs`, `?category=api-reference`, or `?slug=<slug>`)\n\n---\n\n## Two ways to integrate\n\nThere are two supported paths. Pick by what you are building.\n\n| Path | Best for | Auth |\n|---|---|---|\n| **MCP server** | Natural-language and agentic workflows: let Claude, Cursor, or another MCP client run studies, read interviews, and generate reports conversationally | OAuth 2.1 (PKCE) |\n| **REST Headless API** | Code that runs interviews inside your own product or backend | `Bearer` `pk_live_...` API key |\n\n---\n\n## Path 1: the MCP server\n\nKoji ships a Model Context Protocol server, so an AI assistant can manage your research by talking to it. Add this connector URL to your MCP client:\n\n```\nhttps://www.koji.so/api/mcp/mcp\n```\n\n- **Transport**: Streamable HTTP (SSE is a deprecated fallback)\n- **Auth**: Auth is OAuth 2.1 with PKCE (S256). The client is public (no client secret). Discovery is automatic: clients read https://www.koji.so/.well-known/oauth-authorization-server and https://www.koji.so/.well-known/oauth-protected-resource. Dynamic Client Registration (RFC 7591) is supported, so most clients just need the connector URL and will walk you through sign-in. Tokens are Bearer (Authorization header). Access tokens last 1 hour; refresh tokens 30 days.\n- **Scopes**: read-only (`read:studies`, `read:interviews`, `read:account`).\n\nAdd the URL above as a custom MCP server and approve the sign-in. Then ask in plain language, for example \"create a churn study and show me the interviews as they come in.\" Client-specific setup guides: [Claude](/docs/mcp-setup-claude), [Claude Code](/docs/mcp-setup-claude-code), [Cursor](/docs/mcp-setup-cursor), [VS Code](/docs/mcp-setup-vscode), [Windsurf](/docs/mcp-setup-windsurf).\n\n**Available tools** (15):\n\n| Tool | What it does |\n|---|---|\n| `koji_list_studies` | List your studies |\n| `koji_get_study` | Get a study's configuration and status |\n| `koji_get_interviews` | List interviews for a study |\n| `koji_get_transcript` | Get a single interview transcript |\n| `koji_get_account` | Get your account, plan, and credit balance |\n| `koji_create_study` | Create a new study from a research goal |\n| `koji_update_brief` | Iteratively edit a study's research brief |\n| `koji_publish_study` | Publish a study so it starts collecting interviews |\n| `koji_get_study_data` | Get aggregated study data and insights |\n| `koji_generate_report` | Generate an analysis report for a study |\n| `koji_get_report` | Get a study's current report |\n| `koji_publish_report` | Publish a report to a public link |\n| `koji_configure_study` | Configure branding, lead form, interaction modes, URL slug, and Open Graph in one call |\n| `koji_export_data` | Export interviews and transcripts as CSV or JSON |\n| `koji_import_respondents` | Import contacts with personalized interview URLs |\n\n---\n\n## Path 2: the REST Headless API in one page\n\nEverything below is enough to build a full text or voice interview flow.\n\n**Base URL**\n\n```\nhttps://www.koji.so/api/v1\n```\n\n**Authentication**\n\nSend a study-scoped API key as a Bearer token. You never send a project id; the key identifies the study.\n\n```\nAuthorization: Bearer pk_live_wJalrXUtnFEMI4K7MDENGbPxRfiCYz2K\n```\n\nCreate a key from the study's Integrate page. See [API Authentication](/docs/api-authentication) for the full model.\n\n**Endpoints**\n\n| Endpoint | Purpose |\n|---|---|\n| `POST /interviews/start` | Start an interview |\n| `POST /interviews/{interview_id}/message` | Send a message |\n| `POST /interviews/{interview_id}/complete` | Complete an interview |\n| `GET /interviews/{interview_id}` | Get interview results |\n\n**Credentials per endpoint**\n\n| Endpoint | API key | Session token | Permission |\n|---|---|---|---|\n| `POST /interviews/start` | Yes | No | `interview:start` |\n| `POST /interviews/{interview_id}/message` | Yes | Yes | `interview:chat` |\n| `POST /interviews/{interview_id}/complete` | Yes | Yes | `interview:complete` |\n| `GET /interviews/{interview_id}` | Yes | No | `interview:read` |\n| `GET /embed/{project_id}` | Optional | No | None |\n\n**Lifecycle**\n\nStart an interview, stream the AI's replies as the respondent answers, complete it, then read the analysis:\n\n```javascript\n// Full interview lifecycle: start → message → complete → read results.\n// Node 18+ (built-in fetch). Replace the key with your own.\nconst API_KEY = 'pk_live_wJalrXUtnFEMI4K7MDENGbPxRfiCYz2K'\nconst BASE = 'https://www.koji.so/api/v1'\nconst HEADERS = { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }\n\nasync function main() {\n  // 1. Start\n  const started = await fetch(`${BASE}/interviews/start`, {\n    method: 'POST',\n    headers: HEADERS,\n    body: JSON.stringify({ respondent: { external_id: 'user_8271' }, mode: 'text' }),\n  }).then(r => r.json())\n  console.log('AI:', started.initial_message)\n\n  const session = { 'X-Session-Token': started.session_token }\n\n  // 2. One message exchange (SSE)\n  const res = await fetch(`${BASE}/interviews/${started.interview_id}/message`, {\n    method: 'POST',\n    headers: { ...HEADERS, ...session },\n    body: JSON.stringify({ content: 'I found onboarding confusing.' }),\n  })\n  let reply = ''\n  const reader = res.body.getReader()\n  const decoder = new TextDecoder()\n  let buffer = ''\n  while (true) {\n    const { value, done } = await reader.read()\n    if (done) break\n    buffer += decoder.decode(value, { stream: true })\n    const lines = buffer.split('\\n')\n    buffer = lines.pop()\n    for (const line of lines) {\n      if (!line.startsWith('data: ')) continue\n      const frame = JSON.parse(line.slice(6))\n      if (frame.type === 'chunk') reply += frame.content\n    }\n  }\n  console.log('AI:', reply)\n\n  // 3. Complete\n  await fetch(`${BASE}/interviews/${started.interview_id}/complete`, {\n    method: 'POST',\n    headers: { ...HEADERS, ...session },\n    body: JSON.stringify({ reason: 'natural' }),\n  })\n\n  // 4. Read results (analysis lands asynchronously)\n  const result = await fetch(`${BASE}/interviews/${started.interview_id}`, {\n    headers: HEADERS,\n  }).then(r => r.json())\n  console.log('Transcript messages:', result.stats.message_count)\n}\n\nmain()\n```\n\nThe message endpoint streams Server-Sent Events. For the frame-by-frame parser and every field, see [Sending Messages via API](/docs/sending-messages-via-api). For the embed widget instead of code, see [Embed Widget Reference](/docs/embed-widget-reference).\n\n---\n\n## Copy-paste context block\n\nGive this to your AI assistant as a system or context message. It is intentionally compact and complete:\n\n```text\nYou are integrating the Koji Headless API (AI-moderated research interviews).\nBase URL: https://www.koji.so/api/v1\nAuth: header \"Authorization: Bearer pk_live_<key>\" on every request. No project id in bodies; the key identifies the study.\nEndpoints:\n- POST /interviews/start -> { interview_id, session_token, initial_message?, mode }. Body optional: { respondent: { external_id?, display_name?, metadata? }, mode: \"text\"|\"voice\", locale }.\n- POST /interviews/{id}/message -> Server-Sent Events. Headers add \"X-Session-Token: <session_token>\". Body { content }. Frames: {\"type\":\"chunk\",\"content\":...} then {\"type\":\"done\",\"message_id\":...,\"interview_complete\":bool}.\n- POST /interviews/{id}/complete -> { status, stats, analysis, analysis_pending }. Header \"X-Session-Token: <session_token>\". Body { reason? }.\n- GET /interviews/{id} -> transcript, stats, respondent, analysis. API key only.\nErrors are JSON { \"error\": string } (plus retry_after / message / reason on some). No code/details field.\nRate limit: 60/min per key, headers X-RateLimit-*.\nFull spec: https://www.koji.so/llms-full.txt\n```\n\n---\n\n## Where to go next\n\nREST Headless API:\n- [API Authentication](/docs/api-authentication) and [API Key Permissions](/docs/api-permissions)\n- [Starting Interviews via API](/docs/starting-interviews-via-api), [Sending Messages via API](/docs/sending-messages-via-api), [Completing Interviews via API](/docs/completing-interviews-via-api)\n- [Rate Limits and CORS](/docs/rate-limits-and-cors) and [Common Error Codes](/docs/common-error-codes)\n- [Embed Widget Reference](/docs/embed-widget-reference)\n\nMCP server:\n- [MCP Integration Overview](/docs/mcp-overview) and [MCP Tool Reference](/docs/mcp-tool-reference)\n- Client setup: [Claude](/docs/mcp-setup-claude), [Claude Code](/docs/mcp-setup-claude-code), [Cursor](/docs/mcp-setup-cursor), [VS Code](/docs/mcp-setup-vscode), [Windsurf](/docs/mcp-setup-windsurf)\n- [MCP Troubleshooting](/docs/mcp-troubleshooting)\n\n---\n\n## FAQ\n\n### What is the single best link to give an AI assistant?\n\n`https://www.koji.so/llms-full.txt` for the full text of every doc, or this page's URL for a focused API-only starting point. Both are always current.\n\n### Do I need the MCP server and the REST API?\n\nNo. Use the MCP server for conversational and agentic control of your research, or the REST API to build interviews into your own product. They are independent and you can use either alone.\n\n### Does the API need a paid plan?\n\nThe headless API is available on all plans. Usage is governed by interview credits: each interview consumes credits from the study owner's balance (text and voice at different rates), and the start endpoint rejects new interviews when the study is out of quota or the owner has no credits.","category":"API Reference","lastModified":"2026-07-14T13:56:40.708819+00:00","metaTitle":"Building with AI | Koji API for LLMs and coding assistants","metaDescription":"Point your AI coding assistant at the Koji Headless API. Machine-readable specs, a one-page REST reference, the MCP server for agentic workflows, and a paste-ready context block.","aiSummary":"A single-page starting point for developers using AI coding assistants (Claude, Cursor, and similar) to build against Koji. Lists the machine-readable resources (llms-full.txt, /api/content), explains the two integration paths (the MCP server for natural-language agentic workflows and the REST Headless API for code), gives a complete one-page REST reference and lifecycle quickstart, and provides a copy-paste context block to hand to an assistant.","aiLearningOutcomes":["Find the machine-readable Koji API specs to feed an AI assistant","Choose between the MCP server and the REST Headless API","Connect an MCP client (Claude Desktop, Cursor) to Koji","Build a full interview integration from a single reference page","Hand an AI assistant a paste-ready context block for Koji"],"aiDifficulty":"beginner","aiEstimatedTime":"6 min"}],"pagination":{"total":1,"returned":1,"offset":0}}