Projects
Create and list projects for your organisation.
Projects are the top-level container for your research. Each project has one interview (the set of questions asked to participants) and a recruiting record that tracks participant targets and completion.
Automating question generation and project creation
If you'd rather not hand-write your interview questions, use Generate questions with AI to draft them, then create or update a project with the result. The flow differs slightly depending on whether you need stimuli media in the loop:
USER_INTERVIEW or CHURN — generate first, create once
Call POST /projects/generate-questions with your research_objective (and type: "CHURN" if relevant) — no project needs to exist yet. Take the returned questions, suggested_title, intro_message, and end_message straight into POST /projects. One round trip.
STIMULI — create, upload, generate, then apply
Generated questions can only reference stimuli that are already uploaded, so the order flips:
POST /projectswithtype: "STIMULI"and a placeholder question (required at creation time).- Upload your images/videos via Stimuli (
POST /stimuli/presignthenPOST /stimuli/confirm) — captions you set here are what ground the generated questions. POST /projects/generate-questionswithtype: "STIMULI"and theproject_idfrom step 1. The response's questions will reference your uploaded stimuli's captions.PATCH /projects/{project_id}with the returnedquestions(and optionallytitle,intro_message,end_message) to apply them to the draft.POST /stimuli/assignto map each stimulus to the question text that should trigger it — reassign here since step 4 clears any prior assignments when question text changes.
Using Persona MCP instead of the REST API? Its generate_questions tool works the same way conceptually, but the connected AI client drafts the questions itself and can call update_project directly — no separate generate/apply round trip needed.
List projects
Authentication
x-api-key headerHeaders
| Name | Type | Description |
|---|---|---|
x-api-key | string | — |
Responses
| Field | Type | Description |
|---|---|---|
itemsrequired | object[] | — |
↳ idrequired | string | — |
↳ titlerequired | string | — |
↳ statusrequired | DRAFTIN_PROGRESSCOMPLETESTARTEDPAUSED | — |
↳ created_atrequired | string | Created At |
↳ recruitingrequired | object | — |
Example request
curl "https://external-api.prod.insightscompany.io/v1/projects" \
-H "x-api-key: <api_key>"Example response
{
"items": [
{
"created_at": "2026-06-01T10:00:00Z",
"id": "b2c3d4e5-0000-0000-0000-000000000001",
"recruiting": {
"completed_participants": 4,
"has_launched": true,
"target_participants": 10,
"type": "USER_INTERVIEWS"
},
"status": "IN_PROGRESS",
"title": "Customer Onboarding Research"
}
]
}Create a project
Creates a new project, interview, and recruiting record in one call. You supply the questions directly — no AI generation step is required.
Example request
curl -X POST "https://external-api.prod.insightscompany.io/v1/projects" \
-H "x-api-key: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"title": "Customer Onboarding Research",
"type": "USER_INTERVIEW",
"purpose": "Understand pain points in the onboarding flow",
"research_objective": "Identify where users drop off and why",
"intro_message": "Hi! Thanks for joining. This will take around 15 minutes.",
"questions": [
{ "question": "Walk me through your first week using the product.", "probing_level": "high" },
{ "question": "What was the most confusing part of getting started?", "probing_level": "medium" },
{ "question": "What would have made onboarding easier?", "probing_level": "low" }
],
"target_participants": 20,
"recruiting_type": "INTERNAL",
"languages": [
{ "language_name": "English", "accent": "en-US" }
],
"interaction_modes": ["video", "audio"]
}'Example response
Generate questions with AI
Drafts interview questions grounded in a research_objective you supply and your organisation's knowledge hub (company context, product summary, and — for CHURN studies — churn-specific context, pulled in automatically). Returns questions in the exact format POST /projects accepts, plus a suggested title and intro/end messages, so you can review and paste them straight into your create call.
No project needs to exist yet — this only needs your study's research objective. Organisation-level context (company info, product summary) is fetched automatically from your API key; you don't need to pass it.
Example request
curl -X POST "https://external-api.prod.insightscompany.io/v1/projects/generate-questions" \
-H "x-api-key: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"research_objective": "Identify why customers churn within their first 90 days",
"type": "CHURN"
}'Request body
| Field | Type | Required | Description |
|---|---|---|---|
research_objective | string | Yes | What you want to learn from participants. Grounds the generated questions. |
type | string | No | Project type — USER_INTERVIEW (default), STIMULI, or CHURN. CHURN folds your organisation's product context into the prompt as churn-specific framing. |
project_id | string | Only for STIMULI | The project whose already-uploaded stimuli captions (via POST /stimuli/confirm) ground the generated questions. Ignored for other types. |
Example request — STIMULI study
Requires an existing project with stimuli already uploaded (see the STIMULI flow above).
curl -X POST "https://external-api.prod.insightscompany.io/v1/projects/generate-questions" \
-H "x-api-key: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"research_objective": "Understand first reactions to the new homepage design",
"type": "STIMULI",
"project_id": "<project_id>"
}'Example response
{
"end_message": "Thanks so much for sharing your experience with us today.",
"intro_message": "I'm an AI interviewer here to talk with you about your recent onboarding experience. If at any point you need me to repeat something, need more time to think or need to interrupt me - just let me know. Let's get started - can you walk me through the first time you set up your account?",
"questions": [
{
"probing_level": "low",
"question": "Can you walk me through the first time you set up your account?"
},
{
"probing_level": "high",
"question": "Can you tell me about a moment onboarding felt confusing?"
}
],
"suggested_title": "Customer Onboarding Research"
}Notes
- This is synchronous — it calls an LLM and returns the drafted questions directly, typically within a few seconds.
- Nothing is saved automatically. Paste the returned
questions(and optionallysuggested_titleastitle,intro_message,end_message) into Create a project (new project) or Update project questions (existing draft). - Returns
400iftypeisSTIMULIandproject_idis omitted. - Returns
404ifproject_idis provided but doesn't belong to your organisation. - Returns
502if generation fails validation after retries (for example, too few distinct probing levels) — retry the request. - Returns
503if AI question generation isn't configured in this environment. - Using Persona MCP instead? Its
generate_questionstool works against an existing project and returns the same grounding as context for the connected AI client to draft questions with, then apply them by callingupdate_projectdirectly — no separate generate/apply round trip needed.
Update project questions
Applies new questions, title, and/or intro/end messages to a draft project that hasn't launched yet — typically used to apply the output of Generate questions with AI onto a project you already created.
Example request
curl -X PATCH "https://external-api.prod.insightscompany.io/v1/projects/<project_id>" \
-H "x-api-key: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"questions": [
{ "question": "Can you walk me through the first time you set up your account?", "probing_level": "low" },
{ "question": "Can you tell me about a moment onboarding felt confusing?", "probing_level": "high" }
]
}'Request body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | No | Replaces the project's title. |
questions | array | No | Replaces the full question list. At least one required if provided. |
intro_message | string | No | Replaces the opening message shown to participants. |
end_message | string | null | No | Replaces the closing message. Send null to clear it. |
At least one field is required.
Example response
{
"end_message": "Thanks so much for sharing your experience with us today.",
"id": "b2c3d4e5-0000-0000-0000-000000000001",
"interview_id": "c3d4e5f6-0000-0000-0000-000000000002",
"intro_message": "Hi! Thanks for joining. This will take around 15 minutes.",
"questions": [
{
"probing_level": "low",
"question": "Can you walk me through the first time you set up your account?"
}
],
"stimuli_cleared": false,
"title": "Customer Onboarding Research"
}Notes
- Only an unlaunched draft can be updated — returns
409(not_editable) once the project has launched. - If
questionschanges, any existing stimuli-to-question assignments are cleared (stimuli_cleared: truein the response) — re-assign them viaPOST /stimuli/assign. - Returns
409(conflict) if the guide contains survey questions, which must be edited through a different workflow.
Question probing levels
Each question has a probing_level that controls how many AI follow-up questions are asked before moving on:
| Level | Follow-ups | When to use |
|---|---|---|
low | 0 | Quick-answer questions where depth isn't needed |
medium | 1 | Standard depth — good default for most questions |
high | 3 | Topics where you want the participant to really unpack their thinking |
Project types
| Type | Description |
|---|---|
USER_INTERVIEW | Standard conversational research interview |
STIMULI | Participants react to images or videos shown alongside interview questions |
CHURN | Churn-focused interview with adapted AI context |
For STIMULI projects, after creating the project you need to upload your media assets and assign them to questions before the project can be launched. See Stimuli for the upload and assignment workflow.
Interaction modes
interaction_modes controls which interview formats are offered to participants. At least one is required.
| Mode | Participant experience | Best for |
|---|---|---|
video | Camera + microphone. Participant is seen and heard by the AI interviewer. | Observing reactions, body language, facial expressions |
audio | Microphone only, no camera. Voice conversation with the AI. | Lower-friction sessions, sensitive topics, mobile participants |
chat | Text input only. No microphone or camera required. | Highest accessibility, async-friendly, participants who prefer typing |
Single mode: the interview starts immediately in that format — participants see no format picker.
Multiple modes: participants choose their preferred format on the waiting screen before the interview begins.
All three modes use the same AI interviewer and question set — only the input/output channel differs. video and audio are transcribed in real time; chat is typed.
Recruiting types
| Type | Description |
|---|---|
INTERNAL | You share the call_url yourself (default) |
USER_INTERVIEWS | Persona handles participant recruitment via UserInterviews panel |
Notes
idis the project ID — needed to fetch completed Interviews, to launch the project, and to get embed snippets.interview_idis returned in the response for reference.target_participantssets a soft cap on completed interviews. It can be overridden at launch.recruiting_typedefaults toINTERNALif omitted.intro_messageis required and shown to participants before the interview starts.end_messageis optional and shown after the interview ends.languagesis required and must contain at least one entry. Each entry takeslanguage_nameandaccent— voice is assigned automatically.interaction_modesis required. Controls which interview formats participants can choose from.- The project starts in
STARTEDstatus. Call Launch Project to make it live.