# Getting the most from AI tests
Source: https://docs.getversive.com/ai-tests/best-practices
Features worth turning on, and how experienced teams run their tests
## Set up personas like a qual study
* **Build personas from real research data.** Upload interview transcripts, survey exports, or research docs and let Versive [distill them](/ai-tests/personas) — a persona grounded in real quotes and numbers behaves far more specifically than one written from imagination.
* **Treat personas like human qualitative research.** You can learn from a sample size of one — a single run will surface real issues. But aim for **3–5 executions per persona** so the aggregated summary can group findings and show you which ones are stable versus one-off.
* **Test with more than one persona.** Results are attributed per persona, so running your skeptical novice alongside your power user shows you where their experiences diverge.
## Scope the test tightly
* **Test small flows and tasks, not open-ended tours.** "Sign up and invite a teammate" produces attributable findings; "explore the app" produces noise. Run several small tests instead of one big one.
* **Keep Figma files clean.** Import only the frames you actually want tested, in the order you want them seen — stray exploration screens and dead-end frames read as usability failures.
* **Have placeholder content? Turn on the content-accuracy flag.** The [*ignore content accuracy*](/ai-tests/figma-and-image-tests#test-configuration) setting tells the AI to disregard lorem ipsum and dummy data and focus on structure and flow — without it, placeholder content gets flagged as confusing.
## Pick the right mode
* **Conversational tests simulate real user interviews.** Use them when you want reactions, expectations, and the *why* behind problems — and add a per-screen interview script for the screens you're most worried about.
* **Expert audits give design-review-style feedback.** A systematic pass against Nielsen's heuristics (or your own design-system rules as [custom heuristics](/ai-tests/test-modes#expert-audit-heuristic-evaluation)) — great before design reviews.
* **Use SUS to compare across concepts.** Enable the [SUS questionnaire](/ai-tests/test-modes#sus-questionnaires) on a fixed test setup and re-run it per concept or design iteration — the 0–100 score gives you a consistent yardstick. Read it relatively (A vs. B), not as an absolute benchmark.
## Iterate inside the project
* **Add more test runs anytime.** A project isn't one-and-done — after reading the first results, add runs with new personas or more executions to the same project and regenerate the summary.
* **Test iterations in the same project.** When the design changes, run a new round of tests in the same project with the same personas — comparing rounds shows you whether the fixes actually landed.
## Know what AI tests are best at
AI tests excel at uncovering **usability, product, and design improvements** — confusing flows, unclear copy, missing affordances, heuristic violations — in minutes instead of weeks. Treat findings as hypotheses ranked by likelihood: for higher-risk decisions, or research into real-world behavior, attitudes, and willingness to pay, validate with real participants in a [study](/studies/overview).
# Figma prototype & image tests
Source: https://docs.getversive.com/ai-tests/figma-and-image-tests
Test interactive prototypes and static designs with AI users
Prototype and image tests share the same engine: AI personas review a sequence of **screens** and respond to each according to the [test mode](/ai-tests/test-modes) you choose.
## Figma prototype tests
Import a prototype in one of two ways:
* **Paste a Figma URL** — Versive reads the file, detects the prototype's defined interactions, and imports your frames as screens. The file needs link sharing enabled ("Anyone with the link can view").
* **The Figma plugin** — *Versive: Instant Usability Tests* in the Figma Community. Select pages and frames inside Figma, authenticate with your Versive account (OAuth — reconnect anytime), and create a test without leaving the design file.
After import, you choose which frames to include and their order, so you can test a single flow out of a larger file.
## Image tests
Upload static screenshots or mockups (multiple images per test) and arrange them in the order the AI should see them. Ideal for early concepts, landing pages, emails, and ad creative — anything where you want reactions to a design that isn't clickable yet.
## Test configuration
| Setting | Description |
| - | - |
| **Goal** | The context and objective for the test — what the design is, who it's for, and what you want to learn. |
| **Test mode** | Conversational interview or expert heuristic audit — see [Test modes](/ai-tests/test-modes). |
| **Test sections** | The dimensions each screen is evaluated on. Defaults: *Initial Impressions, User Actions & Behavior, Usability Issues,* and *Recommendations* — fully editable. |
| **Per-screen notes & scripts** | Add notes to individual screens, and (in conversational mode) custom interview questions per screen. |
| **Personas** | One or more [personas](/ai-tests/personas), each with its own execution count. |
| **SUS questionnaire** | Optionally have each persona fill out a System Usability Scale questionnaire — see [Test modes](/ai-tests/test-modes#sus-questionnaires). |
| **Ignore content accuracy** | Tell the AI to disregard placeholder content (lorem ipsum, dummy data) and focus on structure and flow, with optional notes about what to ignore. |
## Tips
* **Test one flow at a time.** Ten focused screens beat forty mixed ones — findings stay attributable, and runs are cheaper to repeat as the design iterates.
* **Write the goal like a research brief**: "First-time user setting up a workspace; we want to know if the invite step is discoverable" beats "test my app."
* **Test iterations in the same project** — when the design changes, run a new round with the same personas and compare rounds to see whether the fixes landed.
# AI tests overview
Source: https://docs.getversive.com/ai-tests/overview
Instant usability testing with AI personas — no recruiting required
AI tests let you test designs and websites with **AI personas** instead of recruited participants. Import a Figma prototype, paste a website URL, or upload design images, and get a detailed usability report — transcripts, screenshots, findings, and prioritized recommendations — in minutes.
## Test types
Import an interactive prototype by URL or via the Figma plugin. AI users move through your selected frames and react screen by screen.
Upload static screenshots or mockups and get feedback on visual design, layout, and information hierarchy.
An AI user operates a real browser on your live site, working toward a task you define — with a step-by-step action log, screenshots, and a full session recording.
Reusable, richly detailed AI participants — hand-written or distilled from your own research data.
## How a test comes together
1. **Create a project** from a Figma prototype, image upload, or website URL. Projects organize all the tests you run against one design.
2. **Configure the test** — the goal or task, the [test mode](/ai-tests/test-modes) (conversational, expert audit), the questions each screen is evaluated on, and optional extras like SUS questionnaires.
3. **Pick personas** — one or many, each with its own run count, from your [persona library](/ai-tests/personas) or written inline.
4. **Run it.** Each persona execution is one test run, and a single launch can include up to 50 runs across all selected personas. Runs complete in minutes; website tests can be watched live.
5. **Read the results** — per-run transcripts and screenshots, plus an aggregated summary with key takeaways and prioritized recommendations. See [Results & reports](/ai-tests/results).
## Projects & lifecycle
Projects live in folders alongside your studies and move through **Draft → Active → Completed / Archived** (a draft becomes active on its first run). You can duplicate a project to iterate on a new version of a design, and every run keeps a snapshot of the exact configuration and screens it tested — so old results stay meaningful as the design evolves.
Test runs themselves are **running → completed** (or *failed* — retryable once, free unless the retry succeeds; prototype runs can be *partially successful* if only some screens complete).
## Credits
| Run type | Credits |
| - | - |
| Figma prototype / image test run (per persona execution) | 1 |
| Website test run (up to 50 browser steps) | 1 |
| Website test run with extended limit (up to 100 steps) | up to 2 |
Credits are only charged for runs that **succeed** (including partially successful prototype runs) and come from the same allowance as study completions.
# AI personas
Source: https://docs.getversive.com/ai-tests/personas
Build reusable AI participants from scratch or from your own research data
Personas are the AI participants in your tests. They live in an organization-wide **persona library**, organized into folders, and are reusable across every test and [study simulation](/studies/launch-and-sharing#simulate-ai-test-participants).
## Creating personas
There are three ways to create a persona:
Describe the persona in free text — up to 500,000 characters, so you can be as detailed as you like.
Attach real research files — interview transcripts, survey exports, research reports — as PDF, DOCX, TXT, or Markdown (up to 10 MB per file, 50 MB per persona).
Versive's AI distills your text and files into a structured persona, preserving specific details, numbers, and quotes from the source data.
You can also write a quick **custom persona inline** while configuring a test, without saving it to the library.
## What's in a distilled persona
| Field | What it captures |
| - | - |
| **Summary** | A 20–120 word portrait of who this is. |
| **Identity** | Demographics and background — age, location, education, income, family, role, lifestyle. |
| **Context** | Why they're looking for a solution right now. |
| **Goals & outcomes** | What success looks like for them, including concrete KPIs. |
| **Friction points** | Known pain points and obstacles. |
| **Behavioral patterns** | Habits and typical workflows. |
| **Interaction style** | Communication style, technology comfort level, and decision-making process. |
| **Psychometric profile** | Big Five traits — openness, conscientiousness, extraversion, agreeableness, neuroticism. |
| **Unique factors** | Distinctive details, real quotes, and behavioral instructions. |
Everything is editable after distillation.
## Using personas in tests
* Add any number of personas to a test; each has its own **execution count** (how many independent runs it performs).
* Each persona execution is a separate test run and consumes one credit (website runs with the extended step limit can cost up to two).
* Results are attributed to their persona, so you can compare how different user types experience the same design.
## Best practices
* **Source personas from real research.** A persona distilled from ten actual interview transcripts behaves far more specifically than one written from imagination. The distiller keeps real quotes and numbers — feed it real data.
* **One persona, one segment.** Don't average two audiences into one persona ("busy parents and enterprise admins") — make two, and run both.
* **Use execution counts for consistency.** Running the same persona 3–5 times shows which findings are stable and which were one-off.
* **Maintain the library like a team asset.** Name personas by segment, keep them in folders, and update them as new research comes in — your plan includes a persona limit, so prune stale ones.
# Results & reports
Source: https://docs.getversive.com/ai-tests/results
What AI test runs produce and how to read them
## Per-run results
Every persona execution is a **test run** with its own detailed record:
* **Conversational tests** — a full interview transcript per screen (moderator and persona turns), alongside the screen image.
* **Expert audits** — heuristic-by-heuristic ratings (*Good / Fair / Poor / Not Applicable*) with the specific issues found.
* **Website tests** — the step-by-step action log with screenshots and reasoning, task completion status with a confidence score, abandonment reason if the persona gave up, and the session video replay.
* **SUS score** (if enabled) — the persona's questionnaire answers and computed 0–100 score.
* **Run summary** — key findings plus recommendations prioritized as **P0 (critical), P1 (important), P2 (nice to have)**.
* **Accessibility analysis** (website tests) — WCAG-based compliance check with an impact breakdown.
Runs progress from *running* to *completed* (or *failed* — a failed run can be retried once, free unless the retry succeeds; prototype runs may be *partially successful* if only some screens complete).
## Aggregated test summary
Above individual runs, each test gets an **aggregated summary** across all personas and executions:
* **Test overview** and an overall **results rating** — *Excellent, Good, Fair, Poor,* or *Critical* — with an explanation.
* **Key takeaways**, each tagged with sentiment (positive / negative / neutral).
* **Prioritized recommendations**, linked to the pages or screens they concern and to the supporting runs and quotes — so every recommendation has receipts.
Summaries generate on demand and can be regenerated after you add more runs.
## Sharing & feedback
* **Public result links** — share a read-only view of a test with anyone, no Versive account needed; revocable at any time.
* **Word & Markdown export** — formatted reports for stakeholders.
* **Rate the run** — leave a 1–5 star rating and comment on any run; this feedback goes straight to the Versive team.
## Reading AI test results well
* **Treat findings as hypotheses ranked by likelihood, not verdicts.** AI tests are exceptional at surfacing *where* flows confuse and *what* to look at; confirm the highest-stakes findings with a small real-user [study](/studies/overview).
* **Look for repetition across personas and executions.** An issue that appears in four of five runs is signal; a one-off is a maybe.
* **Treat priorities as guidelines.** The P0/P1/P2 rankings are the AI's read on severity — read each recommendation and decide whether it matches your own understanding before acting on it.
* **Read the abandonment reasons.** Where and why the AI gave up on a task is often the single most actionable data point in a website test.
# Test modes
Source: https://docs.getversive.com/ai-tests/test-modes
Conversational interviews, expert heuristic audits, and SUS questionnaires
Prototype and image tests run in one of two modes, and either can add a SUS questionnaire on top.
## Conversational test (dynamic interview)
The default mode. An AI moderator interviews the AI persona about each screen, producing a natural back-and-forth transcript — first impressions, expectations, confusion, and what they'd do next.
* The interview covers your **test sections** (e.g. *Initial Impressions, User Actions & Behavior, Usability Issues, Recommendations*).
* You can add a **custom interview script per screen** to make sure specific questions get asked.
* Every persona execution produces its own transcript, so five personas give you five distinct perspectives on the same flow.
**Use it when** you want qualitative reactions and the *why* behind usability problems — the closest thing to a moderated usability session, minutes instead of weeks.
## Expert audit (heuristic evaluation)
A single AI expert reviews the entire flow against usability heuristics — by default **Nielsen's 10 usability heuristics**:
1. Visibility of system status
2. Match between system and the real world
3. User control and freedom
4. Consistency and standards
5. Error prevention
6. Recognition rather than recall
7. Flexibility and efficiency of use
8. Aesthetic and minimalist design
9. Help users recognize, diagnose, and recover from errors
10. Help and documentation
You can replace or extend these with **custom heuristics** — each is just a name and a definition, so you can audit against your own design system rules or accessibility criteria.
Results rate each heuristic (**Good / Fair / Poor / Not Applicable**), list the specific issues found, and produce per-screen recommendations.
**Use it when** you want a fast, systematic design QA pass rather than simulated user reactions — great before design reviews or as a pre-launch checklist.
## SUS questionnaires
Optionally, every persona fills in a **System Usability Scale** questionnaire after its run:
* Starts from the 10 standard SUS statements (alternating positive/negative), each answered on a 1–5 scale.
* Statements are editable, and you can use 1–20 of them — polarity is tracked per statement so scoring stays correct.
* Produces the standard **0–100 SUS score** per run, comparable across design iterations.
SUS scores from AI personas are best used **relatively** — comparing design A to design B, or v1 to v2 — rather than as absolute benchmarks against human-normed scales.
## Choosing a mode
| You want… | Mode |
| - | - |
| User reactions, confusion points, and quotes | Conversational |
| A systematic design-quality audit | Expert audit |
| A trackable usability metric across iterations | Either + SUS |
| Both perspectives | Run one test in each mode — same project, same screens |
# Website tests
Source: https://docs.getversive.com/ai-tests/website-tests
AI users operate a real browser on your live site
In a website test, an AI persona drives a **real browser** on your live, publicly accessible website, working toward a task you define. You get a step-by-step action log with a screenshot and reasoning for every step, plus a full session recording.
## Configuration
| Setting | Description |
| - | - |
| **Website URL** | The page where the AI user starts. The site must be publicly reachable. |
| **Task** | What the user should accomplish — e.g. "Find a two-bedroom apartment in Austin under \$2,000 and start an application." |
| **Viewport** | Desktop sizes 1920×1080, 1536×864, 1366×768 (default), 1280×720, 1024×768 — or 500×1080 to simulate mobile. |
| **Test sections** | The dimensions the run is evaluated on. Defaults: *Initial Impressions, User Action & Behavior, Recommendations.* |
| **Personas** | One or more [personas](/ai-tests/personas), each with an execution count. |
| **Extended limit** | Raises the per-run cap from 50 to 100 browser steps for longer journeys (may cost up to 2 credits). |
## While it runs
* **Live view** — watch the AI user navigate in real time.
* Each step logs the action (navigate, click, type, scroll), the element involved, a screenshot, and the AI's reasoning for taking it.
## What you get
* **Task completion status** with a confidence score — and if the AI gave up, the abandonment reason.
* **Step-by-step replay**: the full click path with screenshots, plus a session video recording.
* **Findings per test section**, and an aggregated summary with key takeaways and recommendations linked back to the runs that produced them.
* Optional **accessibility analysis** — WCAG-based checks with an impact breakdown and recommendations.
## Tips
* **Write tasks with a verifiable end state.** "Add the cheapest annual plan to the cart" gives a clean success/failure signal; "explore the pricing page" doesn't.
* **Start narrow.** Test the critical path (sign-up, checkout, key search) before broad "look around" tests.
* **Match the viewport to your traffic.** If most visitors are on phones, run the mobile viewport — layouts fail differently at 500px.
* **Staging environments** work as long as they're publicly reachable (no VPN or login walls the AI can't pass).
# Create folder
Source: https://docs.getversive.com/api-reference/folders/create-folder
POST /folders
Create a folder for organizing studies
Creates a folder. Returns `201`.
The folder name.
`FULL_ACCESS`, `CAN_EDIT`, `CAN_VIEW`, `INVITE_ONLY`, or `CAN_EDIT_SURVEY_ONLY`.
Days to keep interview transcripts in this folder's studies, from 1 to 36500, counted from each interview's last message. After that the transcript and the study memory learned from it are deleted. `null` keeps transcripts indefinitely. Over an MCP connection, only the organization owner can set it. See [Transcript retention](/platform/folders-and-permissions#transcript-retention).
### Response
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/folders \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Q3 churn research", "retention_policy_days": 30 }'
```
# List folders
Source: https://docs.getversive.com/api-reference/folders/list-folders
GET /folders
List your organization's folders
Returns all folders in your organization.
### Response
An array of `{ id, name, created_at, retention_policy_days }`. `retention_policy_days` is `null` when the folder has no [retention policy](/platform/folders-and-permissions#transcript-retention).
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/folders \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Update folder
Source: https://docs.getversive.com/api-reference/folders/update-folder
PATCH /folders/{id}
Rename a folder or set its transcript retention policy
Updates only the fields you send.
The folder ID.
New folder name.
Days to keep interview transcripts in this folder's studies, from 1 to 36500, counted from each interview's last message. Send `null` to turn retention off. Setting it on a folder with existing studies deletes their transcripts older than the window at the next hourly check. See [Transcript retention](/platform/folders-and-permissions#transcript-retention) for what is deleted and kept.
Organization API keys can change this field. Over an MCP connection, only the organization owner can.
### Response
```bash cURL theme={null}
curl -X PATCH https://api.getversive.com/api/v1/folders/5c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "retention_policy_days": 30 }'
```
# Get interview insights
Source: https://docs.getversive.com/api-reference/insights/get-insights
GET /insights
Fetch the AI-generated summary for an interview
Returns the AI-generated transcript summary insight(s) for a completed interview.
The interview ID.
### Response
An array of insight objects:
Currently `TRANSCRIPT_SUMMARY`.
The structured summary content.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/insights?interview_id=5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Create interview
Source: https://docs.getversive.com/api-reference/interviews/create-interview
POST /interviews
Create an interview and get a personal participant link
Creates an interview for a study and returns a unique **participant link**. This is the main integration point for inviting participants from your own systems — each interview gets its own `vid` token, so you can track exactly who responded.
The study to create the interview in.
Arbitrary key/value data stored with the interview (e.g. your internal user ID, cohort, source). Available in results, filters, and exports.
A label for the interview (e.g. the participant's reference).
Currently only `English` is accepted.
### Response
The interview ID.
The personal participant URL — send this to your participant.
The study.
Starts as `open`.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/interviews \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"title": "Participant #1042",
"metadata": { "userId": "u_1042", "cohort": "churned-q2" }
}'
```
```json 200 theme={null}
{
"id": "5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f",
"title": "Participant #1042",
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"metadata": { "userId": "u_1042", "cohort": "churned-q2" },
"link": "https://getversive.com/s/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b?vid=Xy3...",
"status": "open",
"created_at": "2026-07-13T10:30:00Z"
}
```
# Get interview
Source: https://docs.getversive.com/api-reference/interviews/get-interview
GET /interviews/{id}
Fetch an interview, including transcript and status
Fetches an interview created via the API.
The interview ID.
### Response
`open`, `in_progress`, `paused`, `processing`, `closed` (complete), `screened_out`, or `canceled`.
The participant link (empty if none).
The participant link token.
Your metadata from creation.
The interview transcript.
The conversation as `{ role, content }` messages.
Structured per-question responses.
Completion progress.
Timestamp of the first message.
Timestamp of the last message.
Active participation time.
Always `VERSIVE` for API-accessible interviews.
Whether this is a simulated interview.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/interviews/5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Get interview by link token
Source: https://docs.getversive.com/api-reference/interviews/get-interview-by-vid
GET /interviews
Look up an interview by its participant link token (vid)
Fetches an interview by the `vid` token from its participant link — useful when your system knows the link but not the interview ID (e.g. handling a redirect back from the study).
The participant link token.
### Response
The same interview object as [Get interview](/api-reference/interviews/get-interview).
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/interviews?vid=Xy3AbC..." \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Get interview media
Source: https://docs.getversive.com/api-reference/interviews/get-interview-media
GET /interviews/{id}/media
List a participant's recordings and uploaded files, each with a time-limited access link
Lists the media captured during an interview: participant audio, screen recordings, camera video, and files uploaded in media-upload questions. Each item carries a link you can open or download from.
Links point back at the Versive API (`/api/v1/media/{token}`) rather than at storage. Opening one re-checks that the key that requested it is still active and still has access to the study, then redirects to a short-lived download URL. Each link expires after 24 hours, stops working after about 500 opens, and dies as soon as the key is deactivated. Links carry no readable information, so they are safe to pass to other tools, but treat them like any other credential and do not post them publicly.
Organization API keys can call this endpoint with no extra setup. Apps connected over [MCP](/mcp/overview) cannot use it yet: it requires the `media:read` scope, which the MCP server does not issue today.
The interview ID.
Comma-separated subset of `audio`, `screen`, `video`, `uploaded`. Defaults to all.
### Response
Item counts keyed by `media_type`.
The media ID.
`audio`, `screen`, `video`, `uploaded_image`, or `uploaded_video`.
The question the media was captured for.
1-based position of that question in the study.
Short label derived from the question text.
The transcript message it belongs to, when linked.
Seconds. Only set for audio recordings.
Only set for uploaded files.
Only set for uploaded files.
Bytes. Only set for uploaded files.
Whether streaming playback has finished processing. The link works either way.
Time-limited access link. Answers with a redirect to the file.
When the link stops working.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/interviews/5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f/media?types=audio,uploaded" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json Response theme={null}
{
"interview_id": "5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f",
"study_id": "0f1e2d3c-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
"counts": { "audio": 2, "uploaded_image": 1 },
"items": [
{
"id": "8d2a1c0e-3f4b-4a5c-9d6e-7f8a9b0c1d2e",
"media_type": "audio",
"question_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"question_index": 1,
"question_title": "How did you first hear about the product?",
"message_id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"duration": 42.7,
"mime_type": null,
"file_name": null,
"file_size": null,
"ready": true,
"created_at": "2026-09-10T14:03:11.402Z",
"url": "https://api.getversive.com/api/v1/media/Zk3f...",
"expires_at": "2026-09-11T14:05:00.118Z"
}
]
}
```
# Update interview
Source: https://docs.getversive.com/api-reference/interviews/update-interview
PUT /interviews/{id}
Update an interview's status
Updates an interview's status — for example, to cancel a link you no longer want used.
The interview ID.
One of `open`, `in_progress`, `paused`, `processing`, `closed`, `screened_out`, `canceled`. Omitting it makes the request a no-op.
### Response
```json theme={null}
{ "message": "Interview updated successfully" }
```
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/interviews/5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "canceled" }'
```
# API introduction
Source: https://docs.getversive.com/api-reference/introduction
Authentication, conventions, and errors for the Versive public API
The Versive public API (v1) lets you manage studies, questions, logic, interviews, translations, and insights programmatically. Typical uses: creating interviews with tracked links from your own app, syncing study content from your systems, building studies with the AI agent, and pulling interview transcripts and summaries into your data warehouse.
## Base URL
```
https://api.getversive.com/api/v1
```
The machine-readable OpenAPI document is available at:
```
https://api.getversive.com/api/v1/openapi.json
```
Use the OpenAPI document for code generation and agent tool discovery. The pages in this reference add examples,
authorization context, and product guidance that are not represented fully in the schema.
## Authentication
Public REST integrations use an organization **API key** passed as a Bearer token:
```bash theme={null}
curl https://api.getversive.com/api/v1/studies \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
API keys are created in your organization settings (**Organization → API keys**) by an owner or admin. Each key is scoped to one organization and grants full API access to that organization's data — there are no per-key scopes, so treat keys like passwords: store them in a secrets manager, never in client-side code, and deactivate keys you no longer use.
A missing or invalid bearer credential returns `401` with `{"detail": "Invalid authentication credentials"}`.
The same public API routes also accept short-lived, scoped JWTs issued for authenticated
[Versive MCP server](/mcp/overview) sessions. Each MCP connection is granted `studies:read`, `interviews:read`, and
`studies:write` at consent time (or a narrower set if the client requests one). Those scopes are an upper bound:
organization roles and study access policies are still checked on every request. MCP clients manage these credentials
automatically; do not copy MCP access tokens into direct REST API integrations.
## Conventions
* **JSON everywhere** — request bodies are JSON (`Content-Type: application/json`); one endpoint ([Update question](/api-reference/questions/update-question)) also accepts `multipart/form-data` for file uploads.
* **IDs are UUID strings.**
* **Organization scoping is automatic** — the key determines the organization; requesting a resource that belongs to another organization returns `403`.
* **Partial updates** — `PUT` endpoints only change the fields you send. On studies, the `config` object is *merged* into the existing config rather than replaced.
* **Pagination is endpoint-specific** — list studies currently returns all matching records, while `GET /interviews?study_id=...` supports `page` and `page_size`. Check each endpoint's parameters before assuming either behavior.
## Rate limits and retries
Versive does not currently publish numeric request-rate limits for the public API. Clients should keep concurrency
bounded and retry transient `5xx` responses with exponential backoff and jitter. If the API edge returns `429`, treat it
as transient and honor `Retry-After` when present. Do not retry validation, authentication, or authorization failures
without changing the request.
See [Versioning and compatibility](/api-reference/versioning) for the public API lifecycle and deprecation signals.
## Errors
Errors use conventional HTTP status codes with a JSON body:
```json theme={null}
{ "detail": "Study not found" }
```
| Status | Meaning |
| - | - |
| `400` | Invalid request — missing/invalid parameters or values. |
| `401` | Missing or invalid bearer credential. |
| `403` | The resource belongs to a different organization. |
| `404` | Resource not found. |
| `429` | The API edge rejected excess traffic — retry with backoff and honor `Retry-After` when present. |
| `422` | Validation failed — e.g. invalid `{{Q:...}}` question references; the body includes an `errors` array. |
| `500` | Internal server error. |
## Resources
Create, list, update, translate, and AI-edit studies; read response metrics.
Read, batch-create/update, and delete a study's questions.
Manage conditional branching rules.
Create tracked participant links and read interview transcripts and status.
Fetch AI-generated interview summaries.
Trigger and manage study translations.
Create and list folders for organizing studies.
Receive an event after an interview is completed.
Understand compatibility guarantees and deprecation signals.
# Create question logic
Source: https://docs.getversive.com/api-reference/question-logic/create-question-logic
POST /question-logic
Add a branching rule to a question
Creates a logic rule. Rules on a question are evaluated top to bottom; the first match wins. Returns `201`.
The study.
The question the rule attaches to (must belong to the study).
`==`, `!=`, `<`, `<=`, `>`, `>=`, `COUNT_LT`, `INCLUDES`, `NOT_INCLUDES`, `ALWAYS`, or `SMART_CONDITION`. (`INCLUDE_RESPONSE_IN_NEXT_QUESTION` is accepted for backwards compatibility but is legacy — use question mentions instead.)
`string`, `int`, or `smart_condition`.
`next_question_id`, `move_to_question_group`, `end_interview`, `redirect_url`, or `screen_out`.
The comparison value — or, for `SMART_CONDITION`, the natural-language condition (e.g. "the participant mentions pricing").
Required for `next_question_id` actions; must be a question in the same study. Cannot be the rule's own question, or a question inside a randomized group (directly or nested) — target the group with `move_to_question_group` instead.
Required for `move_to_question_group` actions; the interview enters at the group's first question (respecting per-participant randomization). Question groups must be enabled for the study. Must be a group in the same study that contains at least one question. Cannot be the question's own group or an ancestor of it, or a group nested inside a randomized group.
Required for `redirect_url` actions.
Set for `end_interview` actions.
The language this rule applies to.
### Response
The created logic rule — same shape as [List question logic](/api-reference/question-logic/list-question-logic).
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/question-logic \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"question_id": "q-123",
"operation": "<",
"comparison_value": "3",
"comparison_value_type": "int",
"action_type": "screen_out"
}'
```
# Delete question logic
Source: https://docs.getversive.com/api-reference/question-logic/delete-question-logic
DELETE /question-logic/{logic_id}
Remove a branching rule
Deletes a logic rule (soft delete). Returns `204 No Content`.
The rule ID.
```bash cURL theme={null}
curl -X DELETE https://api.getversive.com/api/v1/question-logic/lr-42 \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# List question logic
Source: https://docs.getversive.com/api-reference/question-logic/list-question-logic
GET /question-logic
List logic rules for a question or study
Lists logic rules. Provide at least one of `question_id` or `study_id`.
All rules in a study.
Rules attached to one question.
Filter by language.
### Response
An array of logic rules:
Rule ID.
The study.
The question the rule belongs to.
Condition operator: `==`, `!=`, `<`, `<=`, `>`, `>=`, `COUNT_LT`, `INCLUDES`, `NOT_INCLUDES`, `ALWAYS`, or `SMART_CONDITION` (AI-evaluated natural-language rule). `INCLUDE_RESPONSE_IN_NEXT_QUESTION` is a legacy operator that may appear on older studies — use question mentions instead.
The value to compare against — or the natural-language condition for `SMART_CONDITION`.
`string`, `int`, or `smart_condition`.
`next_question_id`, `move_to_question_group`, `end_interview`, `redirect_url`, or `screen_out`.
Jump target for `next_question_id` actions.
Jump target for `move_to_question_group` actions; the interview enters at the group's first question.
Target URL for `redirect_url` actions.
Whether the rule ends the interview.
The language the rule applies to.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/question-logic?study_id=9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Update question logic
Source: https://docs.getversive.com/api-reference/question-logic/update-question-logic
PUT /question-logic/{logic_id}
Modify a branching rule
Updates a logic rule; only the fields you send change. Returns `204 No Content`.
The rule ID.
Body fields (all optional): `operation`, `comparison_value`, `comparison_value_type`, `next_question_id`, `next_question_group_id`, `redirect_url`, `end_interview`, `action_type`, `language` — same semantics and target validation as [Create question logic](/api-reference/question-logic/create-question-logic).
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/question-logic/lr-42 \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "comparison_value": "4" }'
```
# Batch create/update questions
Source: https://docs.getversive.com/api-reference/questions/batch-questions
POST /questions/batch
Create and update questions in one call
Creates and/or updates questions in a single study in one request. Items **with** an `id` are updated; items **without** an `id` are created (appended after the existing questions in the order given). Returns `201`.
The questions to create or update. Every item must include the same `study_id`. Recognized fields per item:
* `id` — include to update an existing question; omit to create.
* `study_id` — **required** on every item.
* `content` — question text; may include `{{Q:...}}` references.
* `type` — question type (see [List questions](/api-reference/questions/list-questions) for values).
* `props` — type-specific settings object. On updates it is merged with the existing props, with the same handling of multiple-choice `exclusiveOptions` as [Update question](/api-reference/questions/update-question#editing-multiple-choice-options) and the same validation of `earlierAnswerChecks` ([checks against earlier answers](/api-reference/questions/update-question#checks-against-earlier-answers)).
* `interviewer_notes` — private AI guidance.
* `assets` — media assets array.
* `display_order` — position (new questions are auto-ordered if omitted).
### Question references (mentions)
`content` can reference an earlier answer with either:
* `{{Q:}}` — the complete answer.
* A type-specific property token — one option response from a structured answer, such as:
* `{{Q:.ratingForItem[0]}}`
* `{{Q:.rankOfOption[0]}}`
* `{{Q:.optionAtRank[0]}}`
* `{{Q:.allocationForItem[0]}}`
Property indices are zero-based. Do not construct property tokens with a generic `.option[index]` selector; it is not supported.
Call [List available references](/api-reference/studies/available-references) for the destination question's position and copy the returned `template` verbatim. References are validated on write, and invalid property names, indices, missing questions, or forward references fail with `422` and an `errors` array.
### Response
IDs of newly created questions, in input order.
IDs of updated questions.
The example below creates one new question and updates an existing one (`8d3b6a2f-1c4e-4f7a-b5d9-2e6c8a0f4b1d`), piping that existing question's answer into the new question's text. References must point at questions that already exist in the study — use [List available references](/api-reference/studies/available-references) to discover valid templates.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/questions/batch \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"questions": [
{
"id": "8d3b6a2f-1c4e-4f7a-b5d9-2e6c8a0f4b1d",
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"content": "Which plan are you currently on?"
},
{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"type": "question",
"content": "Why did you choose the {{Q:8d3b6a2f-1c4e-4f7a-b5d9-2e6c8a0f4b1d}} plan?",
"props": { "required": true, "maxFollowupQuestions": 3 }
}
]
}'
```
```json 201 theme={null}
{
"created_question_ids": ["4f9c1e7a-6b2d-4a8e-9c3f-1d5b7e9a2c4f"],
"updated_question_ids": ["8d3b6a2f-1c4e-4f7a-b5d9-2e6c8a0f4b1d"]
}
```
# Delete question
Source: https://docs.getversive.com/api-reference/questions/delete-question
DELETE /questions/{question_id}
Remove a question from its study
Deletes a question (soft delete) and recalculates the study's estimated length. Returns `204 No Content`.
The question ID.
```bash cURL theme={null}
curl -X DELETE https://api.getversive.com/api/v1/questions/q-456 \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# List questions
Source: https://docs.getversive.com/api-reference/questions/list-questions
GET /questions
List a study's questions with logic and mentions
Returns all questions in a study, ordered by `display_order`, each with its logic rules and resolved mentions.
The study whose questions to list.
### Response
An array of question objects:
Question ID.
The question text (may include `{{Q:...}}` reference placeholders).
Question type — e.g. `question` (AI Question), `textInput`, `shortText`, `message`, `email`, `multipleChoice`, `ratingScale`, `matrixRatingScale`, `starRating`, `nps`, `number`, `ranking`, `rankingWithMatrix`, `cardSort`, `allocation`, `allocationWithMatrix`, `conjoint`, `treeTest`, `prototypeTask`, `websiteTest`, `externalLink`, `calendar`, `mediaUpload`, `exploratory`. Write endpoints accept `type` as a free-form string; these are the types the Versive app uses.
Private notes guiding the AI interviewer.
Position in the study.
Type-specific settings (options, scales, limits, and so on).
Attached media assets. Each asset keeps its stable `url` identifier and includes `download_url` for viewing
or downloading it. Private storage links last one hour; `download_url_expires_at` is their UTC expiry time.
Request this endpoint again for a fresh link. External URLs are passed through and have no expiry time.
If a private file cannot be signed, both download fields are `null`; the rest of the response remains available.
Use `download_url` to fetch the file. When updating a question, retain the asset's `url` identifier and omit
the read-only `download_url` and `download_url_expires_at` fields. A private asset's identifier may contain
`/object/public/`; it identifies the stored file but cannot be used as a public download link.
The question's logic rules — same shape as [question logic](/api-reference/question-logic/list-question-logic).
Resolved `{{Q:...}}` references in the content: `placeholder`, `referenced_question_id`, `label`, `type` (`question` | `propertyAnswer`), `property_name`, `property_index`, `valid`, `error`.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/questions?study_id=9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Update question
Source: https://docs.getversive.com/api-reference/questions/update-question
PUT /questions/{question_id}
Update a single question
Updates a question. Only the fields you send change, and `props` is **merged** with the existing props. Returns `204 No Content`.
The question ID.
New question text. `{{Q:...}}` references are validated (`422` on invalid references).
Private AI guidance.
New position.
Settings to merge into the existing props. See [Editing multiple-choice options](#editing-multiple-choice-options) for how exclusive options are kept in sync, and [Checks against earlier answers](#checks-against-earlier-answers) for `number` and `allocation` validation against an earlier answer.
Replaces the media assets array. Keep each asset's stable `url` from [List questions](/api-reference/questions/list-questions).
`download_url` and `download_url_expires_at` are read-only and are discarded if sent back.
### Adding an earlier answer
Mentions are stored directly in `content`. Use `{{Q:}}` for the complete earlier answer. For one response from a matrix, ranking, allocation, or card-sort question, first call [List available references](/api-reference/studies/available-references) with `before_question_id` set to this question, then copy the returned property `template` verbatim.
For example, this inserts the rating for the first matrix item:
```json theme={null}
{
"content": "You rated speed {{Q:matrix-q-123.ratingForItem[0]}}. What influenced that rating?"
}
```
Property indices are zero-based. Invalid property names or indices return `422`.
### Editing multiple-choice options
Multi-select `multipleChoice` questions can mark options such as "None of the above" as **exclusive** in `props.exclusiveOptions`. Entries are the option *text* and must exactly match an entry in `props.options` (case-sensitive), otherwise the request is rejected with `400`.
You don't need to resend `exclusiveOptions` when you edit `options`. If you omit it, or send it unchanged, the API keeps it in sync for you:
* Renaming one option keeps its exclusive marker (the marker follows the new text).
* Removing an option drops its marker.
* Setting `isMultiSelect` to `false` clears all markers, since exclusivity only applies to multi-select.
To change which options are exclusive, send the new `exclusiveOptions` list explicitly, matching the final `options`.
```json theme={null}
{
"props": {
"options": ["Red", "Blue", "None of the above"],
"exclusiveOptions": ["None of the above"]
}
}
```
### Checks against earlier answers
`number` and `allocation` questions can carry checks of the answer against an earlier answer in `props.earlierAnswerChecks`. Each check has an `operation` (`<`, `<=`, `==`, `>=`, or `>`) and a `source`: the earlier question's `questionId`, plus `option` (the exact option text) when the earlier question is an `allocation`.
* A `number` question holds a list of checks.
* An `allocation` question holds either `{"target": "total", "checks": [...]}` — the total is compared, and the fixed limit (`hasLimit`) no longer applies — or `{"target": "options", "checks": {"": [...]}}` with one list per option of this question. Keys must exactly match entries in `props.options`.
The earlier question must be a `number` or `allocation` question that comes before this one on every path a participant can take, and it must still have the option named; otherwise the request is rejected with `422` and an `errors` array. Renaming an option of the earlier question that a check names is rejected the same way — update the check first. When you edit this question's own `options`, per-option checks follow a renamed option and are dropped for a removed one, like `exclusiveOptions`.
```json theme={null}
{
"props": {
"earlierAnswerChecks": {
"target": "total",
"checks": [{ "operation": "==", "source": { "questionId": "8d3b6a2f-1c4e-4f7a-b5d9-2e6c8a0f4b1d" } }]
}
}
}
```
### Uploading an asset
Supported uploads are JPEG, PNG, GIF, WebP, and BMP images; MP4, WebM, and QuickTime videos; and PDFs, up to 50 MB per file. BMP uploads accept `image/bmp` and `image/x-ms-bmp`.
This endpoint also accepts `multipart/form-data` to attach a media file directly:
* `file` — the media file.
* `asset_layout` — `fullScreen` (default) or `inline`.
* `asset_sizing` — optional sizing mode.
* `asset_max_width_percent` — optional, integer from 1 to 100 capping the width at that percent of the question column. Requires `asset_layout=inline` and an image or video. Omit or send `100` for full width.
* Other fields (`content`, `props` as JSON strings, etc.) may be sent as form fields.
```bash cURL (JSON) theme={null}
curl -X PUT https://api.getversive.com/api/v1/questions/q-456 \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "props": { "randomizeOrder": true } }'
```
```bash cURL (file upload) theme={null}
curl -X PUT https://api.getversive.com/api/v1/questions/q-456 \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-F "file=@concept.png" \
-F "asset_layout=inline"
```
# Get quota progress
Source: https://docs.getversive.com/api-reference/quotas/get-quota-progress
GET /studies/{id}/quotas/progress
Completes versus limit for every quota bucket
Returns the study's quota configuration together with the current number of completes per bucket. Only completed, real interviews count: in-progress, screened-out, archived, mock, and AI-simulated interviews are excluded.
The study ID.
### Response
`off`, `fixed`, or `url_param`.
`{ limit, complete }` in `fixed` mode.
The URL parameter in `url_param` mode.
One `{ value, limit, complete }` per link value in `url_param` mode.
`allow` or `reject`.
One `{ question_id, kind, match, value, limit, complete }` per [question quota](/studies/question-quotas), included in every mode.
`complete` can exceed `limit` by a small amount when several participants finish at the same time.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/quotas/progress \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
{
"mode": "fixed",
"fixed": { "limit": 100, "complete": 42 },
"param_name": null,
"buckets": [],
"unmatched_param_policy": "allow",
"question_buckets": [
{
"question_id": "3f1c2a9e-8d4b-4c7a-9e21-5b6d7c8e9f01",
"kind": "choice",
"match": "equals",
"value": "iPhone",
"limit": 25,
"complete": 19
}
]
}
```
# Get study quotas
Source: https://docs.getversive.com/api-reference/quotas/get-study-quotas
GET /studies/{id}/quotas
The study-level quota configuration
Returns the study's quota configuration. See [Quotas](/studies/settings#quotas) for how each mode behaves.
The study ID.
### Response
`off`, `fixed` (total completes), or `url_param` (per link parameter).
Completes allowed in `fixed` mode. `0` closes the study to new participants.
The URL parameter in `url_param` mode.
One `{ value, limit }` per link value in `url_param` mode. A `limit` of `0` closes that value.
`allow` or `reject`: what happens to participants whose link has no matching value.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/quotas \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
{
"mode": "url_param",
"fixed_limit": null,
"param_name": "group",
"buckets": [
{ "value": "1", "limit": 50 },
{ "value": "2", "limit": 50 }
],
"unmatched_param_policy": "allow"
}
```
# List question quotas
Source: https://docs.getversive.com/api-reference/quotas/list-question-quotas
GET /studies/{id}/question-quotas
Every question in a study that has quota buckets
Lists the [question quotas](/studies/question-quotas) of a study, grouped by question. Questions without quotas are omitted. To read one question, use `GET /studies/{id}/questions/{question_id}/quotas`, which returns a single entry (with an empty `buckets` list when the question has none).
The study ID.
### Response
An array of:
The Multiple Choice question.
The question's quota buckets, each `{ kind, match, value, limit }`. `kind` is always `choice`; `match` is `equals` or `includes`; `value` is the option text in the study's default language.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/question-quotas \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
[
{
"question_id": "3f1c2a9e-8d4b-4c7a-9e21-5b6d7c8e9f01",
"buckets": [
{ "kind": "choice", "match": "equals", "value": "iPhone", "limit": 25 },
{ "kind": "choice", "match": "equals", "value": "Android", "limit": 25 }
]
}
]
```
# Update question quotas
Source: https://docs.getversive.com/api-reference/quotas/update-question-quotas
PUT /studies/{id}/questions/{question_id}/quotas
Replace the quota buckets of one Multiple Choice question
Replaces the [question quotas](/studies/question-quotas) of one question. Send the full list you want to keep; an empty array removes every quota on the question. Other questions and the study-level quota are not affected.
The study ID.
A Multiple Choice question in the study.
The request body is a JSON array of buckets, up to 50, unique per `match` and `value`:
`equals` (exactly that one option selected) or `includes` (the option is among the selected options). `includes` is only accepted on multi-select questions.
The exact option text in the study's default language. A value that matches no option is saved but never fills.
Completes allowed for this option. `0` closes the option: the next participant who chooses it is screened out.
Always `choice`.
### Response
The saved configuration: `{ question_id, buckets }`, same shape as one entry of [List question quotas](/api-reference/quotas/list-question-quotas).
Returns `404` for an unknown question and `422` when the question is not Multiple Choice or an `includes` bucket targets a single-select question.
`POST /studies/{id}/questions/{question_id}/quotas/evaluate` with `{ "values": ["iPhone"], "others": [] }` tells you whether that answer would be screened out right now, without recording anything.
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/questions/3f1c2a9e-8d4b-4c7a-9e21-5b6d7c8e9f01/quotas \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{ "match": "equals", "value": "iPhone", "limit": 25 },
{ "match": "equals", "value": "Android", "limit": 25 }
]'
```
# Update study quotas
Source: https://docs.getversive.com/api-reference/quotas/update-study-quotas
PUT /studies/{id}/quotas
Replace the study-level quota configuration
Replaces the study's quota configuration. Modes are mutually exclusive: send the full configuration for the mode you want, and any previous configuration is discarded. Question quotas are not affected.
The study ID.
`off`, `fixed`, or `url_param`.
Required in `fixed` mode, not allowed otherwise. `0` closes the study to new participants.
Required in `url_param` mode, not allowed otherwise. Letters, digits, underscores, and hyphens only; up to 64 characters.
Required in `url_param` mode, not allowed otherwise. One `{ value, limit }` per link value, up to 50, with unique values. Matching is exact and case-sensitive. A `limit` of `0` closes that value.
`allow` lets in participants whose link has no matching value (they don't count toward any bucket); `reject` turns them away.
### Response
The saved configuration, same shape as [Get study quotas](/api-reference/quotas/get-study-quotas).
To check what a given link would do before sharing it, `POST /studies/{id}/quotas/evaluate` with `{ "entry_params": { "group": "1" } }` returns `{ allowed, reason, bucket }` without recording anything.
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/quotas \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "url_param",
"param_name": "group",
"buckets": [
{ "value": "1", "limit": 50 },
{ "value": "2", "limit": 50 }
],
"unmatched_param_policy": "reject"
}'
```
# Create randomizer
Source: https://docs.getversive.com/api-reference/randomizers/create-randomizer
POST /randomizers
Create a weighted split test over existing questions or groups
Creates a randomizer from content that already exists in the study. Each arm shows one question or one existing question group; when an arm lists several `question_ids`, they are moved into a new group for that arm automatically. An arm may be left empty as a placeholder, but every arm needs a target before participants can be routed to it.
The study ID.
Internal name, e.g. `"Concept test"`.
2 to 12 arms. Each arm: `label` (string), `weight_basis_points` (integer, 1–10000; all arms must total exactly 10000), and one of `question_ids` (array of question IDs), `question_id` (a single question), or `question_group_id` (an existing group), or none of them for an empty arm.
Top-level position after the arm content is moved into the arms. Omit to append.
### Response
`201` with the created randomizer, same shape as [List randomizers](/api-reference/randomizers/list-randomizers).
A question or group can belong to only one arm, and logic rules must never jump between arms — a participant only ever sees one.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/randomizers \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"name": "Concept test",
"arms": [
{ "label": "Concept A", "weight_basis_points": 5000, "question_ids": ["c1d2e3f4-0000-4000-8000-000000000001"] },
{ "label": "Concept B", "weight_basis_points": 5000, "question_group_id": "d4e5f6a7-0000-4000-8000-000000000002" }
]
}'
```
# List randomizers
Source: https://docs.getversive.com/api-reference/randomizers/list-randomizers
GET /randomizers
A study's randomizers (weighted split tests) with their arms
Returns every randomizer in a study. A randomizer routes each participant to exactly one arm; an arm shows one question or one question group. Groups owned by an arm also carry that arm's id as `routing_branch_id` in the question-groups endpoints.
The study ID.
### Response
An array of randomizers.
The randomizer ID.
Internal name; never shown to participants.
The group the randomizer sits in, or `null` at the top level.
Position among its siblings.
In arm order. Each arm has `id`, `label`, `weight_basis_points`, `display_order`, and exactly one of `question_id` or `question_group_id` (both `null` for an empty placeholder arm).
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/randomizers?study_id=9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
[
{
"id": "5f1c2d3e-0000-4000-8000-000000000001",
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"name": "Concept test",
"parent_question_group_id": null,
"display_order": 2,
"arms": [
{
"id": "7a0b1c2d-0000-4000-8000-000000000001",
"label": "Concept A",
"weight_basis_points": 5000,
"display_order": 0,
"question_id": "c1d2e3f4-0000-4000-8000-000000000001",
"question_group_id": null
},
{
"id": "7a0b1c2d-0000-4000-8000-000000000002",
"label": "Concept B",
"weight_basis_points": 5000,
"display_order": 1,
"question_id": null,
"question_group_id": "d4e5f6a7-0000-4000-8000-000000000002"
}
]
}
]
```
# Remove randomizer
Source: https://docs.getversive.com/api-reference/randomizers/remove-randomizer
POST /randomizers/{id}/remove
Dissolve a randomizer keeping its content, or delete it with its arms
Removes a randomizer in one of two modes:
* **`ungroup`** (default) dissolves the randomizer: each arm's question or group moves back into the study at the randomizer's position, in arm order, and every participant sees all of it. Nothing is deleted.
* **`delete`** removes the randomizer and everything inside its arms — questions, groups, nested randomizers, and logic rules that pointed at them.
Once participants have been assigned to a randomizer's arms, its arms can't be removed or retargeted, so both modes return `409 Conflict`. The same applies to removing or retargeting an assigned arm with [Update randomizer](/api-reference/randomizers/update-randomizer).
The randomizer ID.
The study ID.
`ungroup` or `delete`.
### Response
The mode that was applied.
`ungroup` only: questions moved back into the study directly.
`ungroup` only: arm groups moved back into the study (their questions stay inside them).
`delete` only.
`delete` only.
Logic rules removed because their target was deleted.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/randomizers/5f1c2d3e-0000-4000-8000-000000000001/remove \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b", "mode": "ungroup" }'
```
```json 200 theme={null}
{ "mode": "ungroup", "lifted_questions": 1, "lifted_groups": 1, "deleted_logic_rules": 0 }
```
# Update randomizer
Source: https://docs.getversive.com/api-reference/randomizers/update-randomizer
PUT /randomizers/{id}
Replace a randomizer's name, arms, weights, and targets
Replaces the randomizer's complete arm configuration. Pass every arm that should survive: an existing arm is matched by `branch_id`, an arm without one is added, and any existing arm you leave out is removed **together with its content**. A kept arm sent without a target is emptied the same way, so pass its current `question_id` or `question_group_id` back to keep what it shows. To take content out of a randomizer without deleting it, use [Remove randomizer](/api-reference/randomizers/remove-randomizer) with `mode: "ungroup"` instead.
The randomizer ID.
The study ID.
The randomizer name (send the current name to keep it).
2 to 12 arms, the full final set. Each arm: optional `branch_id` (existing arm to keep; the arm's `id` from [List randomizers](/api-reference/randomizers/list-randomizers) is accepted in its place), `label`, `weight_basis_points` (all arms total exactly 10000), and one of `question_ids`, `question_id` (a single question, the shape [List randomizers](/api-reference/randomizers/list-randomizers) returns), or `question_group_id`, or none of them for an empty arm.
New position in the parent. Omit to keep the current position.
### Response
The updated randomizer, same shape as [List randomizers](/api-reference/randomizers/list-randomizers).
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/randomizers/5f1c2d3e-0000-4000-8000-000000000001 \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"name": "Concept test",
"arms": [
{ "branch_id": "7a0b1c2d-0000-4000-8000-000000000001", "label": "Concept A", "weight_basis_points": 7000, "question_ids": ["c1d2e3f4-0000-4000-8000-000000000001"] },
{ "branch_id": "7a0b1c2d-0000-4000-8000-000000000002", "label": "Concept B", "weight_basis_points": 3000, "question_group_id": "d4e5f6a7-0000-4000-8000-000000000002" }
]
}'
```
# Apply agent mutations
Source: https://docs.getversive.com/api-reference/studies/agent-apply
POST /studies/{study_id}/agent/apply
Persist mutations from a previewed agent edit
Applies a `mutations` list previously returned by [Edit study with AI agent](/api-reference/studies/agent-edit) with `auto_save: false`. All mutations are applied transactionally — if any fail, everything rolls back.
The study ID.
The mutations array from the agent response, unchanged.
### Response
Same shape as the agent edit response — the applied `mutations`, resulting `questions` and `logic`, `study_settings`, and any `broken_mentions`.
```bash cURL theme={null}
# Save the preview response's mutations array to mutations.json first:
# { "mutations": [ ... ] }
curl -X POST https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/agent/apply \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d @mutations.json
```
# Edit study with AI agent
Source: https://docs.getversive.com/api-reference/studies/agent-edit
POST /studies/{study_id}/agent
Edit a study with natural-language instructions
Sends a natural-language instruction to Versive's study-editing agent. The agent can add, edit, delete, and reorder questions, change logic rules, and update study settings and messages. By default changes are **saved immediately** (with automatic rollback if anything fails); set `auto_save: false` to preview the mutations and [apply them separately](/api-reference/studies/agent-apply).
For both default JSON and streaming requests, a detected disconnect cancels
pending work and rolls back an in-progress save. JSON edits no longer continue
in the background after the client or proxy disconnects. Set your client timeout
above the expected edit duration, or use [streaming](#streaming) for long edits.
If the save completed before the connection was lost, its acknowledgement may
be missing; inspect the study before retrying.
The study ID.
Set `text/event-stream` to stream progress and keepalives while the agent runs.
The URL, request body, authentication, and final response fields are unchanged.
The editing instruction, e.g. "Add an NPS question after the intro and screen out anyone who scores under 3 on Q2."
Persist changes before returning. Set `false` to preview.
`smart` (higher quality) or `fast` (lower latency).
Language context for the edit.
### Response
The agent's natural-language summary of what it did.
The structured change list. Each mutation has `id`, `entity_type` (`question` | `logic_rule` | `study_settings` | `study_messages`), `operation` (`create` | `update` | `delete` | `reorder`), `entity_id`, `before`, `after`, and `timestamp`.
The study's questions after the edit, each including a resolved `mentions` array.
The study's logic rules after the edit.
Updated study settings, when changed.
Any `{{Q:...}}` references broken by the edit: `question_id`, `placeholder`, `error`, `newly_broken`.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/agent \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Add a screener asking how often they cook at home; screen out people who never cook.",
"auto_save": false
}'
```
### Streaming
For long edits, send `Accept: text/event-stream`. The server responds with
`Content-Type: text/event-stream`, `Cache-Control: no-cache`, and
`X-Accel-Buffering: no`. After authorization and setup, it immediately sends
`started`, then SSE keepalive comments approximately every 15 seconds while
waiting, including during saving.
```text theme={null}
event: started
data: {"study_id":"9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b"}
: keepalive
event: progress
data: {"tool":"edit_question","status":"completed","entity_id":"q_8f2"}
event: result
data: {"message":"Updated the question.","mutations":[],"questions":[],"logic":[],"study_settings":null,"broken_mentions":[],"question_groups":[],"question_quotas":[],"routing_nodes":[],"routing_branches":[]}
```
| Event | Data |
| - | - |
| `started` | `{"study_id":"..."}` |
| `progress` | `{"tool":"...","status":"completed","entity_id":"..."}`. The entity ID is omitted when the tool has no single affected entity. Progress is advisory and may be skipped for slow clients. |
| `result` | The complete `AgentEditResponseV1` JSON, with the same encoding and fields as the default JSON response, including `broken_mentions`. There is no extra wrapper. |
| `error` | `{"code":"...","message":"..."}`; for example `{"code":"agent_execution_failed","message":"Agent execution failed: The request took too long. Please try again."}`. Structured save rejections preserve their public `code` (such as `question_limit_exceeded`) and `message`. Client validation failures also include an `errors` array when rule-level error strings are available, matching the reasons in the JSON response. If no code is provided, HTTP failures use codes such as `http_400`. Unexpected failures use `internal_error`. |
Each connected stream ends with **exactly one** terminal event: `result` or
`error`, followed by connection close. A client can ignore all other events and
parse the single `data:` line on `result`. Tool progress indicates completed
in-memory work; with `auto_save: true`, mutations are saved **before** `result`.
With `auto_save: false`, `result` is a preview you can
[apply separately](/api-reference/studies/agent-apply).
Authentication, access, entitlement, and request/setup validation failures still
return normal HTTP errors before streaming begins. After streaming starts, the
HTTP status is already `200`, so clients must handle the terminal `error` event.
When the server detects a disconnect, it cancels pending agent work. A cancelled
save rolls back changes already applied in that batch. If the connection is lost
just after a save completes, the client may miss its `result`; inspect the study
before retrying. This endpoint does not deduplicate retries or resume streams.
Treat EOF without a terminal event as an interrupted request with an unknown
outcome, and disable automatic retries of this POST.
#### cURL
Use `-N` (`--no-buffer`) to display events as they arrive. Use your regional API
host (`api-eu.getversive.com` for EU studies).
```bash theme={null}
curl -N --fail-with-body --max-time 900 \
-X POST "https://api-eu.getversive.com/api/v1/studies/$STUDY_ID/agent" \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{"message":"Add a question about the biggest frustration with onboarding.","auto_save":false}'
```
#### Python
This example uses `requests`. The read timeout limits idle time between received
bytes, rather than the total duration of the edit. The small `chunk_size` lets
short keepalives and events reach the parser immediately.
```python theme={null}
import json
import os
import requests
url = f"https://api-eu.getversive.com/api/v1/studies/{os.environ['STUDY_ID']}/agent"
with requests.post(
url,
headers={
"Authorization": f"Bearer {os.environ['VERSIVE_API_KEY']}",
"Accept": "text/event-stream",
},
json={"message": "Add a question about onboarding frustrations.", "auto_save": False},
stream=True,
timeout=(10, 60),
) as response:
response.raise_for_status()
response.encoding = "utf-8"
event, data = None, []
for line in response.iter_lines(chunk_size=1, decode_unicode=True):
if line.startswith(":"):
continue # Keepalive comment
if line.startswith("event:"):
event = line[6:].strip()
elif line.startswith("data:"):
data.append(line[5:].lstrip())
elif line == "":
if event in ("result", "error"):
payload = json.loads("\n".join(data))
if event == "error":
raise RuntimeError(f"{payload['code']}: {payload['message']}")
print(json.dumps(payload, ensure_ascii=False, indent=2))
break
event, data = None, []
else:
raise RuntimeError("Stream interrupted; inspect the study before retrying")
```
#### Proxy requirements
Every proxy between the client and Versive must forward `Accept: text/event-stream`
and stream the response immediately, including SSE comments. Disable response
buffering, caching, and compression that buffers small chunks; do not collect the
body with `.json()` or `.text()` before forwarding it. For nginx, use
`proxy_buffering off` and a suitable `proxy_read_timeout`. Preserve the upstream
content type and cancellation: when the downstream client disconnects, abort the
upstream request too.
Set idle timeouts comfortably above 15 seconds (for example, 60 seconds) and allow
a total request duration long enough for the edit. Heartbeats prevent idle read
timeouts only when all intermediaries flush them; they cannot extend an absolute
request-duration limit. Cloudflare documents a default
[125-second Proxy Read Timeout](https://developers.cloudflare.com/fundamentals/reference/connection-limits/).
A buffering customer proxy can still cause a timeout even when Versive streams.
To verify the integration, use a test study and check that `started` appears
promptly, comments arrive during quiet periods, and an edit lasting over 125
seconds still ends in `result`. On a disposable study, start an edit with
`auto_save: true`, disconnect while generation is in progress, and confirm the
study remains unchanged after the request has been cancelled. Also remove the
`Accept` header to confirm the default JSON behavior.
# AI edit questions (stateless)
Source: https://docs.getversive.com/api-reference/studies/ai-edit
POST /studies/{study_id}/ai-edit
Transform a question list with AI, without saving
A stateless AI editing endpoint: send a list of questions and an instruction, get back the transformed list. **Nothing is persisted** — use it to power your own editing UI, then save via the [batch questions endpoint](/api-reference/questions/batch-questions). For an agent that edits and saves the study directly, use the [agent endpoint](/api-reference/studies/agent-edit) instead.
The study ID (used for context and access control).
The editing instruction.
The current question list to transform.
The language the questions are written in.
### Response
The transformed questions. Newly added questions are flagged with `is_new: true`.
A structured description of what changed.
IDs of questions the AI removed.
# List available references
Source: https://docs.getversive.com/api-reference/studies/available-references
GET /studies/{study_id}/available-references
Which earlier questions can be referenced from a given position
Returns the catalog of questions that can be [referenced](/api-reference/questions/batch-questions#question-references-mentions) from a given position in the study — with ready-to-insert `{{Q:...}}` templates for each. Use this endpoint to build an "@-mention" picker or discover the exact token for one option response.
Always copy the returned `template` into the destination question's `content`. A full-answer token such as `{{Q:}}` inserts the complete response. To insert one item from a structured answer, choose an entry whose `kind` is `property`.
The study ID.
Only return questions that appear **before** this question — use when editing an existing question.
Only return the questions at zero-based interview positions lower than this value — use when composing a new question. Positions count questions in the order participants see them, with question groups expanded, so they match the numbers in the study editor. Ignored if `before_question_id` is set.
## Supported question types
The following source question types can be mentioned:
* `textInput`, `shortText`, `number`, and `multipleChoice` — full answer only.
* `matrixRatingScale` — full answer or `ratingForItem[index]`, which returns the rating for one item.
* `ranking` — full answer, `rankOfOption[index]`, or `optionAtRank[index]`.
* `allocation` — full answer or `allocationForItem[index]`.
* `cardSort` — full answer, `categoryForCard[index]`, or `cardsInCategory[index]`.
Property indices are **zero-based**. For example, `ratingForItem[0]` selects the first entry in the matrix question's `props.options`.
Property selectors are type-specific. There is no generic `.option[index]` selector, and multiple-choice questions expose only their full answer.
### Response
Each entry has `question_id`, `display_order` (zero-based interview position, groups expanded), `type`, `content`, a human-readable `label` such as `Q2`, and `available_references`.
`fullAnswer` for the complete response or `property` for one structured sub-answer.
The exact `{{Q:...}}` token to insert into the destination question's `content`.
Type-specific selector such as `ratingForItem`, `rankOfOption`, or `allocationForItem`. Null for a full answer.
Zero-based option, category, or rank-position index. Null for a full answer.
Human-readable option, category, or rank position selected by the property reference.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/available-references?before_display_order=5" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
{
"references": [
{
"question_id": "matrix-q-123",
"display_order": 1,
"type": "matrixRatingScale",
"content": "Rate each part of the experience",
"label": "Q2",
"available_references": [
{
"kind": "fullAnswer",
"label": "Q2",
"template": "{{Q:matrix-q-123}}",
"property_name": null,
"property_index": null,
"option": null
},
{
"kind": "property",
"label": "Q2.ratingForItem[1]",
"template": "{{Q:matrix-q-123.ratingForItem[0]}}",
"property_name": "ratingForItem",
"property_index": 0,
"option": "Speed"
}
]
}
]
}
```
# Create study
Source: https://docs.getversive.com/api-reference/studies/create-study
POST /studies
Create a new study
Creates a study in your organization. Versive applies sensible default configuration (interview mode, messages, screen-out defaults) and merges any `config` you provide over those defaults.
The study title.
Internal description of the study.
Study type. Use `VERSIVE_STUDY` (default) for AI-moderated studies.
Conversation mode: `TEXT_ONLY`, `TEXT_AND_VOICE`, `VOICE_WITH_PREVIEW`, or `VIDEO`.
Controls which organization members can access the study. Use `FULL_ACCESS`, `CAN_EDIT`,
`CAN_EDIT_SURVEY_ONLY`, `CAN_VIEW`, or `INVITE_ONLY`. This does not control participant access.
Study configuration overrides, merged over Versive's defaults (AI interviewer settings, branding, languages, device rules, and so on).
Branding you omit here is filled in from your organization's [study branding defaults](/platform/organizations-and-roles#study-branding-defaults); branding you send explicitly is kept as-is.
[Memory](/studies/ai-interviewer#memory) is set with `enableMemory` (boolean, off by default), `memoryFocus` and `memoryUsageRules` (strings, up to 300 characters each).
Welcome screen: `{ title, body, ctaText }`.
Completion screen: `{ title, body, ctaText, ctaLink }`.
Screen-out screen: `{ title, body, ctaText, ctaLink }`. A default is applied if omitted.
Folder to create the study in.
Arbitrary key/value metadata stored on the study.
Insights configuration (e.g. analysis model).
### Response
Returns the created study (status `201`) with fields: `id`, `title`, `description`, `metadata`, `type`, `mode`, `config`, `welcome_message`, `thank_you_message`, `screen_out_message`, `access_policy`, and `created_at`.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/studies \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Onboarding feedback — July",
"description": "Post-onboarding interview for new signups",
"welcome_message": {
"title": "Quick chat about your first week?",
"body": "This takes about 5 minutes.",
"ctaText": "Start"
}
}'
```
```json 201 theme={null}
{
"id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"title": "Onboarding feedback — July",
"description": "Post-onboarding interview for new signups",
"metadata": null,
"type": "VERSIVE_STUDY",
"mode": "TEXT_AND_VOICE",
"access_policy": "FULL_ACCESS",
"config": { "interviewMode": "quality", "lang": { "default": { "name": "English" } } },
"welcome_message": {
"title": "Quick chat about your first week?",
"body": "This takes about 5 minutes.",
"ctaText": "Start"
},
"thank_you_message": null,
"screen_out_message": { "title": "Thanks for your interest!" },
"created_at": "2026-07-13T10:30:00Z"
}
```
# Get study
Source: https://docs.getversive.com/api-reference/studies/get-study
GET /studies/{id}
Fetch a single study
The study ID.
### Response
The study object: `id`, `title`, `description`, `metadata`, `type`, `mode`, `config`, `welcome_message`, `thank_you_message`, `screen_out_message`, `created_at`.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Get study metrics
Source: https://docs.getversive.com/api-reference/studies/get-study-metrics
GET /studies/{id}/metrics
Response counts and quota progress for a study
Returns response counts and quota progress for a study. Counts exclude archived, mock, and AI-simulated interviews.
The study ID.
### Response
Completed interviews.
Interviews a participant has started but not finished.
Participants screened out by logic rules or question quotas.
The total-completes cap when the study uses one, otherwise `null`. Kept for compatibility; use `quotas` for the full picture.
Quota configuration and progress, same shape as [Get quota progress](/api-reference/quotas/get-quota-progress).
`off`, `fixed` (total completes), or `url_param` (per link parameter).
`{ limit, complete }` in `fixed` mode.
The URL parameter in `url_param` mode.
One `{ value, limit, complete }` per link value in `url_param` mode.
`allow` or `reject`: what happens to participants whose link has no matching value.
One `{ question_id, kind, match, value, limit, complete }` per [question quota](/studies/question-quotas), regardless of `mode`.
The study status (e.g. `published`, `paused`).
Derive "quota met" or "spots remaining" from `limit` and `complete` yourself. A `limit` of 0 means the bucket is closed.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/metrics \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
{
"complete": 42,
"in_progress": 3,
"screened_out": 11,
"quota": null,
"status": "published",
"quotas": {
"mode": "url_param",
"fixed": null,
"param_name": "group",
"buckets": [
{ "value": "1", "limit": 50, "complete": 30 },
{ "value": "2", "limit": 50, "complete": 12 }
],
"unmatched_param_policy": "allow",
"question_buckets": [
{
"question_id": "3f1c2a9e-8d4b-4c7a-9e21-5b6d7c8e9f01",
"kind": "choice",
"match": "equals",
"value": "iPhone",
"limit": 25,
"complete": 19
}
]
}
}
```
# List studies
Source: https://docs.getversive.com/api-reference/studies/list-studies
GET /studies
List all studies in your organization
Returns every AI-moderated (`VERSIVE_STUDY`) study in your organization.
### Response
An array of study objects: `id`, `title`, `description`, `metadata`, `type`, `mode`, `config`, `welcome_message`, `thank_you_message`, `screen_out_message`, `created_at`.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/studies \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 200 theme={null}
[
{
"id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"title": "Onboarding feedback — July",
"type": "VERSIVE_STUDY",
"mode": "TEXT_AND_VOICE",
"created_at": "2026-07-13T10:30:00Z"
}
]
```
# List study translations
Source: https://docs.getversive.com/api-reference/studies/list-study-translations
GET /studies/{id}/translations
Read all translated questions for a study
Returns the translated questions for a study, optionally filtered to one language. Poll this after [triggering a translation](/api-reference/studies/translate-study) to see results as they complete.
The study ID.
Filter to a single language (e.g. `German`). Omit for all languages.
### Response
An array of translated-question objects — see [Translated questions](/api-reference/translated-questions/list-translated-questions) for the shape.
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/translations?language=German" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Translate study
Source: https://docs.getversive.com/api-reference/studies/translate-study
POST /studies/{id}/translate
Kick off translation into all supported languages
Starts background translation of the study's questions and messages into every supported language configured on the study (`config.lang.support`) other than the default. Returns immediately with `202 Accepted`.
The study ID.
No request body. Returns `400` if the study has no default language configured.
### Response
The study being translated.
The target languages queued for translation.
```bash cURL theme={null}
curl -X POST https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b/translate \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
```json 202 theme={null}
{
"study_id": "9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b",
"translation_languages": ["German", "French", "Spanish"]
}
```
# Update study
Source: https://docs.getversive.com/api-reference/studies/update-study
PUT /studies/{id}
Partially update a study
Updates only the fields you send. `config` is **merged** into the stored configuration (existing keys you don't send are preserved); all other fields are replaced.
The study ID.
New title.
New description.
Configuration changes, merged into the existing config. For example, turn on [memory](/studies/ai-interviewer#memory) with `{ "enableMemory": true, "memoryFocus": "...", "memoryUsageRules": "..." }`; `enableMemory` must be a boolean, and the two text fields take up to 300 characters each.
Replaces the welcome message.
Replaces the thank-you message.
Replaces the screen-out message.
Move the study to a folder.
Total-completes cap. `null` or `0` removes a positive cap. Ignored when the study uses per-link-parameter buckets or is closed with a cap of `0`; use [Update study quotas](/api-reference/quotas/update-study-quotas) to change those.
### Response
The updated study object.
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/studies/9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "config": { "interviewMode": "fast" } }'
```
# Get translated question
Source: https://docs.getversive.com/api-reference/translated-questions/get-translated-question
GET /translated-questions/{translated_question_id}
Fetch a single question translation
The translated-question ID.
### Response
A single translated-question object — see [List translated questions](/api-reference/translated-questions/list-translated-questions) for the shape.
```bash cURL theme={null}
curl https://api.getversive.com/api/v1/translated-questions/tq-321 \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# List translated questions
Source: https://docs.getversive.com/api-reference/translated-questions/list-translated-questions
GET /translated-questions
List question translations for a study or question
Lists translated questions. Provide at least one of `study_id` or `question_id`.
All translations for a study.
Translations of one question.
Filter by language (e.g. `German`).
### Response
An array of translated-question objects:
The translated-question ID.
The source question.
The target language.
The original text.
The translated text.
Rich-text version, if available.
Translated type-specific settings (e.g. option labels).
```bash cURL theme={null}
curl "https://api.getversive.com/api/v1/translated-questions?study_id=9b2f7c1e-4a4b-4f6e-9a1d-1c2d3e4f5a6b&language=German" \
-H "Authorization: Bearer $VERSIVE_API_KEY"
```
# Update translated question
Source: https://docs.getversive.com/api-reference/translated-questions/update-translated-question
PUT /translated-questions/{translated_question_id}
Overwrite a translation's text
Replaces the translated text of a question. The edit is marked as manual, so re-running [study translation](/api-reference/studies/translate-study) won't overwrite it.
The translated-question ID.
The new translated text. **Plain text only** — markup isn't supported here.
### Response
The updated translated-question object.
```bash cURL theme={null}
curl -X PUT https://api.getversive.com/api/v1/translated-questions/tq-321 \
-H "Authorization: Bearer $VERSIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "Wie oft kochen Sie zu Hause?" }'
```
# Versioning and compatibility
Source: https://docs.getversive.com/api-reference/versioning
How Versive versions, changes, and deprecates its public API
## Current public version
The supported public API is `v1`, and every public endpoint begins with:
```
https://api.getversive.com/api/v1
```
Routes under `/api/v0` are used by the Versive application itself. They are not a public integration surface and are
not covered by the compatibility expectations on this page.
## Compatible changes
Versive may make backward-compatible additions within `v1`, including:
* Adding optional request parameters or fields.
* Adding response fields or new enum values.
* Adding endpoints and webhook payload fields.
* Improving validation, error detail, documentation, and performance.
Clients should ignore response fields they do not recognize and avoid exhaustive handling that fails when a new enum
value appears.
## Breaking changes
A change that requires existing integrations to update will use a new major path such as `/api/v2`. The existing
version will remain separate during migration rather than silently changing its contract.
When a public route or version is scheduled for removal, Versive will:
1. Mark it deprecated in the API reference and OpenAPI document.
2. Announce the replacement and migration guidance in the documentation.
3. Return standards-based `Deprecation` and `Sunset` response headers once a removal date has been set.
No `v1` sunset is currently scheduled. Contact [support@getversive.com](mailto:support@getversive.com) for contractual
support requirements or migration questions.
# Webhooks
Source: https://docs.getversive.com/api-reference/webhooks
Receive signed notifications when a Versive interview is completed
Versive can send an HTTPS webhook after an interview is completed. Webhooks are an organization-level integration
provisioned with the Versive team; creating and rotating destinations is not part of the public `v1` REST API. Contact
[support@getversive.com](mailto:support@getversive.com) to configure one for your organization.
## Event
The current public event type is:
| Event | Sent when |
| - | - |
| `interview.completed` | A participant completes an interview. Screened-out interviews are excluded. |
The HTTP request body contains the event type and the completed interview and study:
```json theme={null}
{
"event_type": "interview.completed",
"interview": {
"id": "interview-uuid",
"status": "closed",
"vid": "participant-facing-id",
"used_fallback_transcription": false
},
"study": {
"id": "study-uuid",
"title": "Onboarding research"
}
}
```
The interview payload can include transcript, recording, timing, and metadata fields. Treat the entire request as
sensitive research data, log only the fields you need, and do not expose the destination publicly.
`interview.used_fallback_transcription` is `true` if any of the interview's recorded answers was transcribed by a
fallback model rather than one of Versive's primary transcription models. It is `false` when only primary models
were used, or when no transcription was recorded. An attempt that fails and then succeeds on another primary model
does not set the flag, and transcribing an answer again later does not clear it. Text generation and speech synthesis
do not affect the flag. Real-time voice interviews transcribe speech live on a separate path, so the flag is always
`false` for them.
## Verify every request
Deliveries are signed by Svix. Verify the `svix-id`, `svix-timestamp`, and `svix-signature` headers against your endpoint
secret before parsing or processing the payload. Use a maintained Svix library when one is available for your language,
reject stale timestamps, and preserve the raw request body for signature verification.
See the [Svix verification guide](https://docs.svix.com/receiving/verifying-payloads/how) for language-specific examples.
## Retries and idempotency
Return a `2xx` response only after your service has accepted the event. Use the `svix-id` header as an idempotency key
because a delivery may be retried. Queue slow work and respond promptly rather than performing long-running processing
in the request handler.
For changes to available events or webhook management, follow the
[versioning policy](/api-reference/versioning).
# Key concepts
Source: https://docs.getversive.com/getting-started/concepts
How Versive is organized: studies, AI tests, personas, plans and usage, and workspaces
A quick tour of the building blocks you'll see everywhere in Versive.
## Studies
A **study** is research with real participants: an AI-moderated survey or interview that participants complete through a link, an embed on your site, or a recruited panel. Studies collect **interviews** (individual participant sessions) as responses, and can be paused or archived at any time. See [Studies overview](/studies/overview).
## AI tests
An **AI test** simulates users instead of recruiting them: AI personas evaluate a Figma prototype, a live website, or uploaded design images and produce transcripts, findings, and prioritized recommendations in minutes. See [AI tests overview](/ai-tests/overview).
## Personas
**Personas** are reusable AI participant profiles. You can write them by hand or generate them from your own research files (interview transcripts, survey exports, research docs). Personas power [AI tests](/ai-tests/overview) and can also take your studies as [simulated participants](/studies/launch-and-sharing#simulate-ai-test-participants) — a great way to test a study before launch. See [AI personas](/ai-tests/personas).
## Plans and usage
Versive has three plans: **Free**, **Pro**, and **Enterprise**. You can compare them and change your plan any time from **Organization → Plans** (or on the [pricing page](https://www.getversive.com/pricing)).
* **Free** is built for surveys: studies with fixed-response questions only. It includes a monthly allowance of survey responses, a cap on questions per survey, one seat, and MCP access for building and analyzing surveys from your AI tools. No credit card is needed to sign up.
* **Pro** adds **AI credits** for AI-moderated interviews and AI tests, a larger survey-response allowance, more questions per survey and seats, and unlocks insights, the assistant, AI personas, and simulations. Pro comes with a one-time 14-day trial (a payment method is required to start it; you are not charged until it ends, and you can cancel before then to return to Free).
* **Enterprise** has custom limits, SSO and admin controls, API access and custom integrations, and dedicated support.
Usage is measured in two separate allowances that reset every billing cycle:
| Allowance | What consumes it |
| - | - |
| **AI credits** | Completed AI-moderated interviews (1 per completion; 2 in the Voice to voice Realtime conversation mode) and AI test runs (1 per persona execution; website tests with the extended step limit can use up to 2). Simulated participants count like real completions. |
| **Survey responses** | Completed responses to surveys (studies with no AI questions). Surveys never use AI credits, so you can run them on every plan, including Free. |
Study creation, editing, and viewing results never consume anything; allowances are only used when a response or test run actually completes. When an allowance runs out, the studies or tests that draw on it pause until the cycle resets, until you top up (survey responses on every plan, AI credits on paid plans), or until you change plan. Features that need AI credits — insights, the assistant, AI personas, AI tests, and simulations — are visible on the Free plan but locked until you upgrade.
## Templates
The **Library** holds reusable building blocks: question templates, study templates, and email outreach templates, organized into color-coded categories. See [Templates & the Library](/platform/templates).
## Organizations
Everything in Versive lives inside an **organization** — your team's workspace. An organization has its own members, folders, studies, AI tests, persona library, templates, billing, and API keys. If you belong to several organizations (common for agencies running research for multiple clients), you can switch between them from the workspace menu.
## Folders
**Folders** organize your studies and AI test projects. Folders can be nested, and each folder has an access policy that controls what other members of your organization can do inside it — from full access down to invite-only. See [Folders & permissions](/platform/folders-and-permissions).
## Roles
Access is controlled at two levels: **organization roles** (Owner, Admin, Creator, and Member) and **study/folder roles** (Owner, Full access, Editor, Commenter, and Viewer). See [Organizations & roles](/platform/organizations-and-roles).
# Welcome to Versive
Source: https://docs.getversive.com/index
AI-powered user research and testing — run studies with real participants and usability tests with AI personas, all in one platform
Versive is an AI-powered user research and testing platform. It combines two complementary product lines on a single platform, with shared analysis, personas, and team workspaces:
AI-moderated surveys and interviews with real participants. Text, voice, and video modes, 18+ question types, conditional logic, and translations into 20 languages.
Instant usability tests using AI personas on Figma prototypes, live websites, and uploaded designs. Reports with transcripts, screenshots, and heuristic evaluations in minutes.
Both product lines share a unified analysis layer with AI-powered insights, theme extraction, sentiment analysis, and exportable reports.
## Explore the docs
Organizations, folders, credits, and how the pieces fit together.
Every question type available in the study builder, with settings and tips.
Build reusable AI personas from your own research data.
Transcripts, themes, sentiment, charts, and exports.
## For developers
Manage studies, questions, logic, and interviews programmatically with the public v1 REST API.
Embed Versive studies in your own product with `@getversive/embed` — modal or inline, \~4 KB, zero dependencies.
Connect Claude, ChatGPT, Cursor, and other AI agents to your research — analyze results and build studies in conversation.
Load the machine-readable public v1 contract into code generators, API clients, and AI agent tooling.
## Get help
* Email [support@getversive.com](mailto:support@getversive.com)
* Visit the [Trust Center](https://trust.oneleet.com/versive?tab=compliance) for security and compliance documentation
* Read the [blog](https://getversive.com/blog) for product announcements
# MCP best practices
Source: https://docs.getversive.com/mcp/best-practices
How to design, build, and analyze research with your AI agent
Working with Versive through an agent follows the same arc as any research project: decide what you want to learn, build the study, then turn responses into decisions. This guide covers all three — whether you're a researcher, designer, marketer, or product manager.
## 1. Design your study with the agent
**Start from goals, not questions.** The best studies begin with what you're trying to learn or decide — not a question list. Tell the agent the decision you're facing and let it propose the approach: it knows Versive's full method toolbox, from screeners and ratings to AI-moderated questions that probe with adaptive follow-ups and exploratory sections that pursue a research goal on their own.
**Design with your agent and your team, then build.** Treat the agent as a research partner in the design conversation: paste in the PRD, positioning doc, or campaign brief; workshop the discussion guide together; share the draft with your team before anything gets built. Studies are cheap to create, but a study that asks the right things is designed before it exists.
**Let the agent handle the mechanics.** Agents check what Versive supports on their own — question types, logic, grouping, defaults — and will suggest the right structure or a workaround without you needing to know the catalog.
Some prompts to try:
* "I want to understand why trials churn before converting. Help me design a 10-minute interview study — what should we ask, and what should we deliberately leave out?"
* "Here's the PRD for our new dashboard. What are the riskiest assumptions in it, and how would you test them with an eight-question study?"
* "Draft a discussion guide for a pricing study, then critique it: which questions are leading, and what's missing?"
## 2. Build, edit, and launch
**Build in conversation, review in the dashboard.** Once the design is settled, the agent can create the whole study — questions, groups, screeners, logic, messages — in one go. Everything it creates appears in your dashboard immediately, and nothing reaches participants until you share the link, so review the built study the way you'd review a teammate's draft.
**Iterate incrementally.** Edits are conversational: add a screener, soften the welcome message, cap follow-ups, reorder sections — no rebuilding. If the study is already collecting responses, the agent can still adjust messages and unanswered questions.
**Launching is sharing the link.** Preview the study yourself first (take it once end-to-end), then distribute the share link — directly, through your panel, or via an integration. The agent can check response volume and drop-off as results come in.
Some prompts to try:
* "Create the study we just designed, with a screener that ends the interview for anyone who isn't a current customer."
* "Cap the AI follow-ups at two per question and make the welcome message warmer."
* "Move the demographics to the end and randomize the two concept sections."
The consent screen lists exactly what will be granted before you approve. Every client covered in the setup guide
receives write access ("Create and edit your studies"). If you're building your own client, you can request a
read-only connection by sending an explicit `scope`. Your organization role and each study's access policy still
apply to every request.
## 3. Analyze results and create reports
**Start broad, then drill in.** Ask for themes, completion, and drop-off first — study-level summaries are fast and cheap. Then pull quotes, dig into specific interviews, or export CSV once you know where to look. This ordering gets better answers than dumping every transcript into the conversation.
**Make recurring readouts repeatable.** The built-in prompts (`study-summary`, `study-insights`, `study-insights-summary`) encode a consistent analysis structure, so this week's readout is comparable with last week's. For one-off questions, `custom-insight` runs your question across every transcript.
**Build reports where your stakeholders read them.** The agent can turn results into the artifact you actually need — a one-page executive summary with supporting quotes, a slide-ready narrative, a Slack update, or a comparison across studies — in your voice, for your audience.
**Refer to studies by name.** Agents can search your workspace, so "my March onboarding study" is enough — no IDs needed.
Some prompts to try:
* "What are the biggest pain points participants mentioned in my onboarding study? Give me the top three with a quote each."
* "Which questions have the highest drop-off, and what might be causing it?"
* "Compare the themes in my March and June brand studies — what changed?"
* "Write a one-page readout of the checkout research for leadership: key findings, supporting quotes, and what we should do next."
# Versive MCP server
Source: https://docs.getversive.com/mcp/overview
Connect Claude, ChatGPT, Cursor, and other AI agents to your Versive research
The Versive MCP server lets AI assistants work with your research directly. Connect it once and your agent can answer questions about your results, pull quotes from interviews, draft and edit studies, and export data — all in conversation.
```text theme={null}
https://mcp.getversive.com/mcp
```
It's built on the [Model Context Protocol](https://modelcontextprotocol.io) (MCP), an open standard supported by Claude, ChatGPT, Cursor, Claude Code, and a growing list of other AI tools. You sign in with your Versive account — there are no API keys to manage, and the server is available to every Versive user.
Step-by-step setup for Claude, ChatGPT, Cursor, Claude Code, and any other
MCP client.
Every tool, prompt, and permission scope the server exposes.
How to design, build, and analyze studies with your agent.
Prefer raw HTTP? The public REST API covers similar ground for enterprise
customers.
## What you can do
**Analyze results.** Ask about completion rates, drop-off, and themes across a study, dig into individual interview transcripts, or export responses as CSV. Built-in prompts generate structured research summaries, per-question insights, and stakeholder-ready executive summaries.
**Build and edit studies.** Create a study from a conversation, add and reorder questions, organize them into groups, and set up skip logic. Agents know Versive's full question-type catalog — including AI-moderated questions — and can check what's supported before building.
**Works on every plan.** The Free plan includes MCP access for building and analyzing surveys. Tools that need AI credits — the study assistant and AI editing endpoints, insights generation, and simulations — return a clear `ai_plan_required` message on plans without them, so agents can tell you to upgrade instead of failing silently.
**Ask how Versive works.** Agents can search this help center and read its pages, so questions about credits and billing, sharing, recruiting, roles, or connecting the MCP server get answered from the documentation instead of from memory.
**Keep humans in the loop.** Everything an agent creates shows up in your dashboard immediately, and nothing reaches participants until you share the study link yourself.
## How access works
When you connect a client, Versive walks you through a standard OAuth sign-in:
1. Your client asks for access and you're taken to Versive in the browser.
2. You sign in (if you aren't already) and see a consent screen listing exactly which permissions will be granted. Clients that request specific scopes get those; clients that request none get the full set, including write access.
3. After you approve, the client can act on your behalf, limited to what **you** can see and do: your organization role and each study's access policy apply to every request.
Access is personal. Each teammate connects with their own Versive account, and
every action is recorded in Versive's audit log. If your account uses both the
US and EU regions, you'll pick the region to connect during sign-in.
# Set up the MCP server
Source: https://docs.getversive.com/mcp/setup
Connect Versive to Claude, ChatGPT, Cursor, Claude Code, Codex, or any other MCP client
Every client uses the same server URL:
```text theme={null}
https://mcp.getversive.com/mcp
```
In Claude, Versive is listed in the connector directory, so you can add it without pasting anything. For every other client, add the URL as a remote MCP server (sometimes called a "custom connector"). Either way, sign in to Versive and approve access when your client opens the browser. No API keys are involved.
You can also find this guide in the app, under **MCP** in the sidebar.
## Discovery for integrators
MCP clients discover OAuth automatically from the server's
[protected-resource metadata](https://mcp.getversive.com/.well-known/oauth-protected-resource/mcp). Agents and connector
catalogs can inspect the public
[Versive capability manifest](https://mcp.getversive.com/.well-known/versive-mcp.json) for tool names, descriptions,
required scopes, prompts, and resources before a user connects.
These discovery documents are descriptive and do not grant access. The live MCP `tools/list` method, tool schemas, and
tool calls require OAuth, and every request remains subject to the connected user's organization role and study
permissions.
## Client-specific instructions
Versive is in the Claude connector directory. Works in claude.ai and the Claude desktop app.
In any chat, click the **+** button next to the message box, then **Browse connectors**.
Search for **Versive** and click **Connect**.
Your browser opens Versive — sign in and approve the requested access.
In any conversation, enable Versive from the search and tools menu, then ask about your research.
You can also add Versive manually: go to **Settings → Connectors**, click **Add custom connector**, name it
"Versive", and paste `https://mcp.getversive.com/mcp`. Custom connectors require a paid Claude plan.
Add the server from your terminal:
```bash theme={null}
claude mcp add --transport http versive https://mcp.getversive.com/mcp
```
Then, inside Claude Code, run `/mcp` and select **versive** to sign in and approve access. Tools become available immediately after authentication.
Custom MCP plugins in ChatGPT require Developer Mode.
Go to **Settings → Plugins → Developer Mode** and turn on **Developer Mode**.
Back in **Plugins**, click **+** in the top right. Name it "Versive", set the server URL to `https://mcp.getversive.com/mcp`, and choose **OAuth** for authentication.
Sign in to Versive when the browser opens and approve the requested access.
Enable the Versive plugin in a new conversation.
ChatGPT can take a few minutes to load the tool list after you connect. If the plugin shows no tools right after
setup, use **Refresh** on the plugin's connection page or wait a moment and check again. Plugins are enabled per
conversation, so make sure Versive is turned on in the chat you're testing.
Add Versive to `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` to make it available everywhere:
```json theme={null}
{
"mcpServers": {
"versive": {
"url": "https://mcp.getversive.com/mcp"
}
}
}
```
Then open **Cursor Settings → MCP** and click the authentication prompt next to Versive to sign in and approve access.
Add the server from your terminal:
```bash theme={null}
codex mcp add versive --url https://mcp.getversive.com/mcp
```
Then run `codex mcp login versive` to sign in to Versive and approve access. The Codex CLI and IDE extension share this configuration, so one setup covers both.
Versive works with any MCP client that supports **remote servers over Streamable HTTP with OAuth** — just add `https://mcp.getversive.com/mcp` wherever your client accepts a remote MCP server and complete the sign-in when prompted. A legacy SSE endpoint is available at `https://mcp.getversive.com/sse` for older clients.
If your client only supports local (stdio) servers, bridge it with [mcp-remote](https://www.npmjs.com/package/mcp-remote):
```json theme={null}
{
"mcpServers": {
"versive": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.getversive.com/mcp"]
}
}
}
```
## Disconnecting
Removing the connector from your client stops it from reaching Versive. To fully revoke a grant on the Versive side, ask an organization admin or contact [support@getversive.com](mailto:support@getversive.com). Access also ends automatically if you leave the organization.
## Troubleshooting
Connections made before late 2025 used an older grant format that no longer registers tools. Remove the connector and add it again to re-run the sign-in.
Versive runs separate US and EU data regions. Pick the region where your Versive account lives — if you're unsure, it's the region in your app URL (`getversive.com` for US, `eu.getversive.com` for EU).
Your client may have cached old credentials. Remove and re-add the connector; for `mcp-remote` bridges, also clear the local cache with `rm -rf ~/.mcp-auth`.
Access tokens are short-lived and normally refresh on their own. If calls keep failing, your grant may have been revoked or your organization membership changed — reconnect, or check with your organization admin.
# Tools & capabilities
Source: https://docs.getversive.com/mcp/tools
Every tool, prompt, resource, and permission scope on the Versive MCP server
You don't call these tools yourself — your AI assistant picks the right ones based on what you ask. This page is a reference for what's possible and what permissions each capability needs.
## Permission scopes
The consent screen shows exactly which scopes will be granted when you connect. Every client covered in the [setup guide](/mcp/setup) receives all three scopes, including connectors with no configurable scope field. If you're building your own client, you can request a read-only connection by sending an explicit `scope` with just the read scopes.
| Scope | Grants |
| - | - |
| `studies:read` | Read your studies, questions, groups, logic, and settings |
| `interviews:read` | Read interviews and results in your studies |
| `studies:write` | Create and edit studies, questions, groups, and logic (includes `studies:read`) |
Scopes are fixed when a client connects. To change them (for example, to add write access to a connection that was approved read-only), disconnect the client and connect it again so the consent screen runs with the new scopes.
Scopes are an upper bound, not a bypass: every request is also checked against your organization role and each study's access policy, so an agent can never see or change more than you can in the dashboard.
## Tools
### Studies
| Tool | Description | Scope |
| - | - | - |
| `list_studies` | List your studies newest-first, with status filters, search, and optional activity counts | `studies:read` |
| `get_study` | Full study detail: settings, quota, branding, messages, languages, and share links | `studies:read` |
| `create_study` | Create a new study (requires an owner, admin, or creator organization role) | `studies:write` |
| `edit_study_settings` | Edit title, description, status, mode, quota (a total cap, or per-link-parameter buckets with a matching-value policy), pause URL, access policy, branding, study context, or languages | `studies:write` |
| `edit_interview_message` | Edit the welcome, thank-you, or screen-out message | `studies:write` |
| `archive_study` | Archive a study — the only removal MCP offers; reversible in the dashboard | `studies:write` |
### Questions
| Tool | Description | Scope |
| - | - | - |
| `list_questions` | List questions in display order with type, group, notes, and logic flags | `studies:read` |
| `get_question_details` | One question's full configuration, media download links, logic rules, and quotas | `studies:read` |
| `add_questions` | Add questions at a position or append them to a group | `studies:write` |
| `edit_question` | Edit any question field, including its type | `studies:write` |
| `set_question_quotas` | Cap completes per option on a multiple choice question (`equals` or `includes` match, 0 closes an option); pass the full list, an empty list clears it | `studies:write` |
| `remove_questions` | Remove questions (soft delete); reports logic rules left dangling | `studies:write` |
| `reorder_questions` | Reorder all questions in an ungrouped study | `studies:write` |
### Question groups
| Tool | Description | Scope |
| - | - | - |
| `list_question_groups` | Group hierarchy, order, and randomization settings | `studies:read` |
| `add_question_group` | Create a top-level group or a subgroup (groups nest at most two levels) | `studies:write` |
| `edit_question_group` | Rename a group or toggle child randomization | `studies:write` |
| `move_questions_to_group` | Move questions into a group or back to the top level | `studies:write` |
| `remove_question_group` | Ungroup or delete a group (delete cascades to its questions) | `studies:write` |
### Randomizers
Randomizers are weighted split tests: each participant is routed to exactly one arm, and an arm shows one question or one question group (or is left empty as a placeholder while you build). Use a randomized question group when you only want to shuffle order.
| Tool | Description | Scope |
| - | - | - |
| `list_randomizers` | Randomizers with their arms, weights, and each arm's target question or group | `studies:read` |
| `add_randomizer` | Create a split test over existing questions or groups (2–12 arms, weights total 10,000 basis points) | `studies:write` |
| `edit_randomizer` | Rename a randomizer or replace its arms, weights, and targets | `studies:write` |
| `remove_randomizer` | Dissolve a randomizer keeping all its content (`ungroup`), or delete it with everything in its arms (`delete`) | `studies:write` |
### Logic rules
| Tool | Description | Scope |
| - | - | - |
| `get_logic_rules` | Logic rules for one question or the whole study | `studies:read` |
| `add_logic_rule` | Add a conditional rule: skip to a question, move to a group, end the interview, screen the participant out, or redirect | `studies:write` |
| `edit_logic_rule` | Edit an existing rule | `studies:write` |
| `delete_logic_rule` | Delete a rule | `studies:write` |
### Interviews & results
| Tool | Description | Scope |
| - | - | - |
| `list_interviews` | List interviews with status filters and each interview's metadata. Simulated interviews are included by default; set `include_simulations` to `false` to see real participants only | `interviews:read` |
| `get_interview` | One interview with its question-and-answer conversation and metadata | `interviews:read` |
| `get_study_stats` | Completion funnel, drop-off by question, weekly trends, or per-question answer aggregates | `interviews:read` |
| `export_study_data` | Interview responses as CSV — one row per interview, one column per question, plus a `metadata:` column per metadata field | `interviews:read` |
### Recruiting panels
Panels recruit participants through Prolific or Respondent. The tools create and edit **drafts**; paying and publishing always happen in the Versive dashboard, so no tool charges money or publishes a panel.
For a study with screen-out logic, a Prolific panel must pay screened-out participants: the create tool takes a screen-out reward and the number of screen-outs to pay for, and the estimate includes that budget. Buying more screen-out slots after publishing is done in the dashboard.
| Tool | Description | Scope |
| - | - | - |
| `list_panel_projects` | Recruiting panels with status and dashboard links — one study, or the whole organization when no study is given | `studies:read` |
| `get_panel_project` | One panel with its provider targeting and screener questions | `studies:read` |
| `estimate_panel_project_cost` | Advisory cost for a participant count and incentive on either provider | `studies:read` |
| `search_prolific_filters` | Search the Prolific participant-filter catalog for filter and choice ids, or list one filter's choices with `filter_id` | `studies:read` |
| `get_prolific_eligible_count` | How many Prolific participants match a set of filters | `studies:read` |
| `get_respondent_lookups` | Respondent targeting vocabularies (countries, demographics, industries, topics) | `studies:read` |
| `search_respondent_options` | Search Respondent job titles and skills | `studies:read` |
| `create_prolific_panel_project` | Create a draft Prolific panel | `studies:write` |
| `update_prolific_panel_project` | Edit a draft Prolific panel | `studies:write` |
| `create_respondent_panel_project` | Create a draft Respondent panel | `studies:write` |
| `update_respondent_panel_project` | Edit a draft Respondent panel | `studies:write` |
| `publish_panel_project` | Check a draft is ready and get the dashboard link where you pay and publish | `studies:write` |
### Capabilities
| Tool | Description | Scope |
| - | - | - |
| `get_capabilities` | The ground truth on what Versive supports: question types with defaults, logic and group rules, and unsupported features with workarounds | `studies:read` |
### Help center
| Tool | Description | Scope |
| - | - | - |
| `search_docs` | Search this help center for product and how-to documentation — credits and billing, sharing, recruiting, roles, MCP setup, API and SDK basics | `studies:read` |
| `read_doc` | Read one help-center page, or a single section of it, as Markdown | `studies:read` |
## Prompts
Prompts are ready-made workflows. Most clients surface them in a prompt or command menu (in Claude, look under the connector's entry in the tools menu).
| Prompt | What it does |
| - | - |
| `get-started` | Turns your research goal into a first study: plans the questions with you, creates the study, and hands back the share link (needs `studies:write`) |
| `study-summary` | Structured research summary: themes with supporting quotes, contradictions, confidence, and follow-up questions |
| `study-insights` | Per-question thematic insights, mirroring the dashboard's Insights tab |
| `study-insights-summary` | Executive summary for stakeholders: overview, takeaways, participants, recommendations |
| `custom-insight` | Runs your own analysis question across all transcripts in a study |
| `interview-summary` | One interview: overview, participant profile, sentiment, takeaways, and quality/fraud ratings |
## Resources
| Resource | Description |
| - | - |
| `versive://study/{study_id}` | A study as a JSON document; clients that support resource browsing can list your accessible studies |
## Good to know
Your agent handles fetching and pagination on its own — there's nothing to configure. A few things to know:
* **Question media links expire.** `get_question_details` returns each asset's stable `url` plus a usable `download_url`. Private download links last one hour, with their UTC expiry in `download_url_expires_at`. Fetch details again to refresh a link. A `null` download URL means the private file is currently unavailable.
* **Response metadata lets your agent split results and follow up.** Each interview's metadata comes back with it and as `metadata:` columns in the CSV export: the [hidden fields](/studies/launch-and-sharing#hidden-fields--participant-tracking) on the participant's link (for example `source`, `segment`, or a market code) and fields from uploaded contact lists or the API, such as email. The participant's session token (the `vid` on invite links) is always left out. Sharing is off until an owner or admin turns on **Share participant metadata** in [organization settings](/platform/organizations-and-roles#ai-apps); until then, your agent receives no metadata.
* **Numbers can differ from a casual dashboard glance.** Mock and archived interviews are never exposed over MCP, and simulated interviews are always reported separately from real ones — so MCP counts reflect real research activity only.
* **A few things still happen in the dashboard.** Figma prototype tasks, tree tests, and conjoint questions are configured there (their text stays editable via MCP), and stimulus media is attached there. Agents check the `get_capabilities` tool for the full list of unsupported features, each with a workaround, so they'll route around these on their own.
# Collaboration
Source: https://docs.getversive.com/platform/collaboration
Comments, live observation, notifications, and public sharing
If multiple people edit a study at the same time, changes can override each other. Coordinate with your team before editing a study someone else may be working on.
## Comments
Discuss studies right where the work is. Comments can be attached to any question, or to the welcome, thank-you, and screen-out messages.
* **Threads** — reply to comments to keep discussions together.
* **Resolve** — mark threads as resolved once addressed (study owners and full-access collaborators can resolve).
* **Email notifications** — the study owner is notified of new comments, and comment authors are notified of replies.
Anyone with the **Commenter** role or above can participate — see [Folders & permissions](/platform/folders-and-permissions).
## Notifications
Subscribe a study to **interview completed** events and route them to:
* **Email** — one or more addresses.
* **Slack** — a channel, via an incoming webhook.
* **Webhooks** — your own endpoint, for custom workflows (CRM updates, data pipelines, internal alerts).
Configure these in **Settings → Notifications** on any study.
## Public sharing links
Share read-only views with people outside your workspace — no Versive account required:
| Shareable | What viewers see |
| - | - |
| Study insights | The full insights view for a study |
| A single interview | One interview's transcript |
| A custom insight | One AI analysis view |
| AI test results | A test's results and summary |
| Reports | A published report |
Each link is a unique token you can **revoke at any time**. Regenerating uses the same link until revoked, so a shared URL stays stable.
## Reports
For synthesized deliverables that span multiple studies, build [reports](/studies/results-and-insights#reports) — documents or presentations assembled with an AI assistant — and share them with a public link or export to PDF.
# Folders & permissions
Source: https://docs.getversive.com/platform/folders-and-permissions
Organize work into folders and control access per folder and per study
## Folders
Folders organize studies and AI test projects, and can be **nested** for hierarchy (e.g. *Client A → Q3 Discovery*). Your dashboard shows folders, studies, and AI test projects together, with search, filtering, and sorting. AI personas have their own folders on the **AI Personas** page, and they work the same way.
### Moving items
* **One item:** open its **⋮** menu and choose **Move to folder**, or drag its row onto a folder. Folders move the same way, with everything inside them.
* **Many items:** hover a row and tick the checkbox that appears to the left of its icon (on phones and tablets the checkboxes always show). Once a row is ticked, every row shows its checkbox and the **Name** header gets a checkbox that selects the whole page. Hold **Shift** to tick every row between two clicks, and press **Esc** to clear the selection. Then choose **Move** in the bar at the bottom of the list. You can mix folders and projects in one move.
* The folder picker shows each folder's full path (e.g. *Europe › UK*). A folder can't be moved into itself or one of its own subfolders.
Inside a folder, the folder controls sharing: a study or AI test project moved into a folder takes that folder's access policy. Before the move, Versive warns you when the folder's policy is more open than the project's own. It also warns you when people invited to a study aren't invited to a folder that isn't **Full access**, because inside a folder only the folder's invites count. When a study or AI test project leaves a folder and ends up **Invite only**, Versive also warns you about people invited to that folder who aren't invited where it lands: they lose access. A drag onto a folder asks you to confirm in those cases. Moving a study or AI test project back to the top level keeps its current policy.
A moved folder keeps its own policy and its own invited people, and so do the studies inside it: moving a folder under an **Invite only** folder hides it from the dashboard for people who aren't invited there, but anyone who could open its studies before can still open them. To restrict those studies, set the moved folder's own policy to Invite only.
### Deleting a folder
Open the folder's **⋮** menu and choose **Delete**, or use the trash icon at the top of the folder's page. Deleting a folder also deletes all its subfolders and every study, AI test project, or persona inside them. Organization owners and admins can delete any folder. People with other roles can delete a folder they created, as long as every subfolder inside it is theirs too.
To delete many items at once, select them and choose **Delete** in the bar at the bottom of the list. When the selection includes a folder, you type **DELETE FOLDER** to confirm. Items that can't be deleted stay selected, and the dialog says why.
## Transcript retention
A folder can have a retention policy: the number of days to keep interview transcripts in its studies, counted from each interview's last message (or from when the interview was created, if it has no messages). Set it with the API when you [create a folder](/api-reference/folders/create-folder) or [update one](/api-reference/folders/update-folder). Only the organization owner, or an organization API key, can set or change it.
Versive checks for expired transcripts every hour. For each interview past the window it deletes:
* the transcript: the conversation history, the transcript text, and its translations, and
* the [memory](/studies/ai-interviewer#memory) observations learned from it. The study's memory is then rebuilt from the interviews that remain.
The study, its questions, and its settings are kept, so you can keep running it. These are not deleted by retention: audio and video recordings, clips, transcript files stored with the interview (imported transcripts and raw transcription output), the per-interview summary on the results page, and the study's [insights](/studies/results-and-insights), which can quote participants.
Setting a policy on a folder that already has studies applies it to every interview in them: transcripts older than the window are deleted at the next hourly check. The policy covers studies directly in the folder; a subfolder follows its own policy.
## Folder access policies
Every folder has an access policy that sets the default for organization members:
| Policy | Effect |
| - | - |
| **Full access** (default) | Members can view and edit everything inside. |
| **Can edit** | Members can edit content but not manage sharing. |
| **Can view** | Read-only for members. |
| **Invite only** | Hidden from everyone except people explicitly invited to the folder. |
Studies have the same set of access policies of their own.
## Folder & study roles
On top of the default policy, you can grant individual people a role on a folder or study:
| Role | Permissions |
| - | - |
| **Owner** | Full control, including managing other people's roles. |
| **Full access** | Everything except managing folder sharing. |
| **Editor** | Edit the study, questions, and insights; view interviews; can't recruit panels or resolve comments. |
| **Commenter** | Study-level only: view results and insights, and participate in [comments](/platform/collaboration#comments). |
| **Viewer** | Read-only. |
Roles granted on a folder flow down to the studies inside it. Folder-level roles are Owner, Full access, Editor, and Viewer; the Commenter role is granted on individual studies.
## Common setups
* **Open team** — leave folders on Full access; use roles only for external collaborators.
* **Agency** — one Invite-only folder per client; grant the account team Owner/Editor, and clients Commenter or Viewer on deliverables.
* **Sensitive research** — an Invite-only folder restricted to the core team, with results shared more broadly via [public sharing links](/platform/collaboration#public-sharing-links) when ready.
# Organizations & roles
Source: https://docs.getversive.com/platform/organizations-and-roles
Workspaces, members, and organization-level permissions
An **organization** is your team's workspace — it owns all studies, AI tests, personas, templates, billing, and API keys. Users can belong to multiple organizations and switch between them, which is how agencies keep client work separated.
## Inviting members
Owners and admins can invite teammates by email from the organization settings. Members sign in with email/password or Google, and can secure their account with **multi-factor authentication** (TOTP authenticator apps). The number of seats is set by your plan.
If Google sign-in fails, Versive shows a general sign-in error. Retry signing in; if the problem continues, contact support.
## Organization roles
| Role | What they can do |
| - | - |
| **Owner** | Everything, including billing and subscription management — the only role that can change the plan. |
| **Admin** | Manage everything except billing (can view it): members, org settings, studies, folders, and the Library. |
| **Creator** | Create and manage studies, folders, and Library content. No access to org settings, members, or billing. |
| **Member** | View studies and folders — read-only. |
Only owners and admins can add, change, or remove members.
## Single sign-on (SAML)
Enterprise organizations can sign in through their own identity provider (Okta, Microsoft Entra ID, Google Workspace, and other SAML 2.0 providers).
* **How it works** — enter your work email on the login page, or choose **Continue with SSO**. If your email domain is set up for single sign-on, Versive sends you to your identity provider and back; no Versive password is needed. Sign-in starts from the Versive login page; to add Versive to your identity provider's app dashboard, add it as a bookmark to the login page.
* **Membership** — people who sign in through SSO for the first time join your organization automatically with the default role your organization chose (Creator unless configured otherwise). Existing members who switch to SSO keep their role. Who can sign in is decided by who your IT team assigns to Versive in your identity provider. To remove someone, remove them in both places: in your identity provider, so they can't sign in again, and from your organization in Versive, which ends their access right away (removing them in the identity provider doesn't end a session they already have). People removed only in Versive rejoin on their next SSO sign-in.
* **Invitations** — people at your SSO domain aren't invited: they join by signing in, and an owner or admin can change their role on the Team page afterwards. Invite people outside your SSO domain, such as contractors, as usual.
* **Setup** — your IT team creates a SAML app for Versive in the identity provider and shares its metadata URL; Versive registers it against your email domain. Contact [support@getversive.com](mailto:support@getversive.com) to get started.
## Organization settings
Organization settings are split across tabs:
* **Team** — your organization name, the logo shown in your workspace, and members.
* **Plans** — your subscription and billing.
* **Settings** — study branding defaults, embed domains, and AI apps, covered below.
* **API** — organization-scoped keys for the [public API](/api-reference/introduction), available to enterprise organizations.
### Study branding defaults
Every study carries its own branding — the logo and color participants see. Rather than restyle each new study by hand, owners and admins can set the branding new studies start from under **Organization > Settings > Study defaults**:
| Default | Applies to |
| - | - |
| **Study logo** | The logo in the header participants see. New studies with no logo of their own get this one. |
| **Primary color** | The accent color of the participant experience. Must be a 6-digit hex value like `#00786F`. |
Two things are worth knowing about how these are applied:
* **They are copied in at creation, not linked.** A study takes a snapshot of the defaults the moment it is created and owns its branding from then on, so changing a default later leaves existing studies alone. To restyle a study that already exists, edit its [Branding](/studies/settings#branding) tab.
* **An explicit choice always wins.** Only branding the creator left unset is filled in from the defaults. This holds however the study is created — the dashboard, the [API](/api-reference/studies/create-study), or the AI agent. Studies duplicated or created from a template keep the source's branding and are not touched at all.
Each study can still change or remove its branding in its own [Branding](/studies/settings#branding) tab.
### Embed domains
The domain allow-list required before a study can be embedded with the [Embed SDK](/sdk/security). Studies cannot be embedded anywhere until at least one domain is added.
### AI apps
Apps connected through the [MCP server](/mcp/overview), such as ChatGPT, Claude, and Cursor, can read each response's metadata: the [URL parameters](/studies/launch-and-sharing#hidden-fields--participant-tracking) on the participant's link and fields from uploaded contact lists or the API, such as email. Agents use it to split results by segment and to follow up with participants. The participant's session token (the `vid` on invite links) is never shared.
This is off by default. Owners and admins turn it on with **Share participant metadata** under **Organization > Settings > AI apps**. While it's off, connected apps receive no participant metadata at all. The setting doesn't change what the assistant inside Versive can see.
## Two permission layers
Organization roles set what someone can do *globally*. Access to specific folders and studies is refined by a second layer — [folder & study roles](/platform/folders-and-permissions). A user's effective access to a study is the combination of both.
# Templates & the Library
Source: https://docs.getversive.com/platform/templates
Reusable questions, studies, and outreach emails for your organization
The **Library** is your organization's collection of reusable building blocks, with three sections: question templates, study templates, and email templates.
## Question templates
Save any question — with its type, settings, and media — as a template, and drop it into future studies from the question builder.
* Templates are organized into **color-coded categories** you define (e.g. "Screeners", "NPS & loyalty", "Onboarding").
* Templates are shared across your organization, so the whole team asks recurring questions the same way.
Deleting a category also removes the question templates inside it.
## Study templates
Start a new study from a pre-built template instead of a blank page:
* **Versive templates** for common research needs, plus **organization templates** your team creates.
* When creating from a template you choose the new study's title, destination folder, and access policy — then customize freely.
## Email templates
Reusable outreach emails for [participant invitations](/studies/launch-and-sharing#send-email-outreach), with a rich-text editor, a subject line, a reply-to address, and **merge fields** (participant name, metadata, and their personal interview link).
## Tips
* Turn your best-performing **screener blocks** into question templates — screener quality is the highest-leverage reuse in the library.
* Keep a "standard closing" template (final open feedback + thank-you) so every study ends consistently.
* For agencies: one study template per engagement type (discovery, concept test, usability) makes new client projects a 10-minute setup.
# Embedding studies
Source: https://docs.getversive.com/sdk/embedding
Modal and inline embeds, zero-code data attributes, and passing context
## Modal vs. inline
**Modal** (`versive.open`) overlays the study on your page — best for triggered feedback moments (after checkout, on cancel, feature launch). Only one modal session is active at a time; opening a new one closes the previous.
**Inline** (`versive.embed`) renders the study inside a container element — best for dedicated feedback pages or embedded research panels. The iframe **auto-resizes** to the study content as the participant progresses, and multiple inline embeds can coexist on one page.
```js theme={null}
const versive = Versive.init();
// Modal
versive.open('study-id', { display: { width: '560px' } });
// Inline — pass a selector or an element
versive.embed('study-id', '#feedback-container');
```
## Zero-code embedding with data attributes
When loaded via the script tag, the SDK automatically scans the page (and keeps watching for dynamically added elements, so single-page apps work) and wires up any element with `data-versive-study`:
```html theme={null}
Give feedback
```
| Attribute | Values | Description |
| - | - | - |
| `data-versive-study` | study ID | **Required.** The study to embed. |
| `data-versive-mode` | `inline` (default) · `modal` | `modal` makes the element a click trigger. |
| `data-versive-context-*` | any string | Everything after the prefix becomes a context key: `data-versive-context-plan="pro"` → `plan=pro`. |
| `data-versive-preview` | presence | Enables [preview mode](#preview-mode). |
## Passing context (identifying participants)
Use `context` to attach your own data — a user ID, plan, experiment arm — to the response. Context arrives in Versive as response metadata, available in results, filters, and exports:
```js theme={null}
versive.open('study-id', {
context: {
userId: 'user_123',
plan: 'pro',
cohort: '2026-07',
},
});
```
Context values are appended to the study URL as query parameters, so they're visible to the participant. Never pass emails, names, tokens, or anything sensitive — use an opaque internal ID and join it to your data on your side. The keys `embed` and `mode` are reserved and ignored.
## Preview mode
Set `preview: true` (globally in `init`, per call, or via `data-versive-preview`) to run the study without saving responses — for development and internal demos:
```js theme={null}
const versive = Versive.init({ preview: true });
```
## Reacting to the study lifecycle
Listen for events on the session (or set defaults in `init`) — for example, to grant an incentive on completion:
```js theme={null}
const session = versive.open('study-id', { context: { userId } });
session.on('complete', ({ interviewId, responseId }) => {
grantIncentive(userId);
});
session.on('close', (reason) => {
// 'completed' | 'dismissed' | 'error'
if (reason !== 'completed') showMaybeLaterToast();
});
```
The full event list is in the [API reference](/sdk/reference#events).
# Embed SDK overview
Source: https://docs.getversive.com/sdk/overview
Embed Versive studies in any web app with @getversive/embed
`@getversive/embed` is a lightweight (\~4 KB gzipped), zero-dependency JavaScript SDK that embeds Versive studies — text surveys and AI voice/video interviews — directly in your product. The SDK renders the study in an iframe and manages the modal/inline UI, loading states, and a secure `postMessage` event bridge. All study logic, AI moderation, and branding stay server-side; the SDK never touches study content.
Modal and inline modes, zero-code data attributes, and passing context.
Every method, option, event, and error code.
## Installation
```bash theme={null}
npm install @getversive/embed
```
```js theme={null}
import Versive from '@getversive/embed';
```
```html theme={null}
```
The script exposes a global `Versive` class and automatically initializes any element with a `data-versive-study` attribute — no JavaScript required.
## Quick start
### Modal
Open a study in a modal overlay — for example after a user completes an action in your app:
```js theme={null}
const versive = Versive.init();
const session = versive.open('your-study-id', {
context: { userId: 'user_123', plan: 'pro' },
});
session.on('complete', ({ interviewId, responseId }) => {
console.log('Study completed', interviewId);
});
```
### Inline
Embed a study directly in your page. The iframe automatically resizes to fit the study content:
```js theme={null}
const versive = Versive.init();
versive.embed('your-study-id', '#survey-container');
```
### Zero-code (script tag)
With the script tag, you can embed without writing any JavaScript:
```html theme={null}
Give feedback
```
## Before you ship
Embedding is disabled until an organization admin adds your site's domain to the **allowed embed domains** list in Versive settings. Studies only render inside iframes on allow-listed origins. See [Security & domains](/sdk/security).
Voice and video studies also need microphone/camera permissions delegated to the Versive iframe — the SDK sets `allow="microphone; camera"` on the iframe for you, but your own Content Security Policy and Permissions Policy must not block the Versive origin. Details in [Security & domains](/sdk/security).
# SDK reference
Source: https://docs.getversive.com/sdk/reference
Complete API reference for @getversive/embed
## `Versive.init(config?)`
Creates a client with global configuration. Call once and reuse.
```js theme={null}
const versive = Versive.init({
preview: false,
display: { width: '480px' },
on: { complete: handleComplete },
});
```
Origin the study loads from. Auto-detected in script-tag mode; you normally don't set this.
Global preview mode — responses are not saved.
Default modal display options, merged with per-call options.
Default event callbacks. Both global and per-call callbacks fire.
## `versive.open(studyId, options?)`
Opens a study in a **modal** overlay. Closes any previously open modal session. Returns a [`StudySession`](#studysession).
The study's ID (from the study's Launch → Embed tab, or study settings).
Preview mode for this session.
Key/value pairs attached to the response as metadata. Appended to the study URL as query parameters — don't pass sensitive data. Keys `embed` and `mode` are reserved.
Modal display options for this session.
Event callbacks for this session.
## `versive.embed(studyId, container, options?)`
Embeds a study **inline**. Returns a [`StudySession`](#studysession). Throws if the container isn't found. Inline embeds ignore `display` — the iframe fills the container's width and auto-sizes its height.
A CSS selector or element to render into.
`options` accepts `preview`, `context`, and `on` (as above).
## `versive.close()` / `versive.destroy()`
`close()` closes the active modal session. `destroy()` closes it and removes all listeners.
## Display options
Modal-only, passed via `display`:
| Option | Type | Default |
| - | - | - |
| `width` | `string` | `'480px'` |
| `maxHeight` | `string` | `'90vh'` |
| `closeOnOverlayClick` | `boolean` | `true` |
| `closeOnEscape` | `boolean` | `true` |
| `zIndex` | `number` | `999999` |
## `StudySession`
Returned by `open()` and `embed()`.
| Member | Description |
| - | - |
| `isOpen` | `boolean` — whether the session is currently open. |
| `on(event, handler)` | Subscribe to an [event](#events). Returns an unsubscribe function. |
| `off(event, handler)` | Unsubscribe a handler. |
| `close()` | Close the session (tears down the iframe/modal). |
| `destroy()` | Close and remove all event listeners. |
## Events
| Event | Payload | Fires when |
| - | - | - |
| `ready` | — | The study has loaded and the loader is hidden. |
| `start` | `{ interviewId }` | The participant begins the study. |
| `complete` | `{ interviewId, responseId }` | The participant finishes. |
| `heightChange` | `height` (number) | The study content resized (inline auto-height). |
| `close` | `reason` — `'completed' \| 'dismissed' \| 'error'` | The session closed. |
| `error` | `{ code, message }` | Something went wrong. |
| `permissionRequired` | `'microphone' \| 'camera'` | Reserved for voice/video permission prompts — treat as experimental. |
### Error codes
| Code | Meaning |
| - | - |
| `TIMEOUT` | The study didn't load within 15 seconds. The session auto-closes. |
| `SUBMISSION_ERROR` | A response failed to submit inside the study. |
## Loading behavior
The SDK shows a spinner while the study loads (inline embeds reserve a 600px placeholder until the first height report). If the study hasn't loaded after **15 seconds**, an `error` with code `TIMEOUT` fires and the session closes — most commonly because the host domain isn't on the [allowed embed domains list](/sdk/security).
# Security & domains
Source: https://docs.getversive.com/sdk/security
Domain allow-listing, CSP requirements, and how the embed stays safe
## Allowed embed domains
Embedded studies only render on domains your organization has explicitly approved. An **organization admin** manages the list in Versive's embed settings.
* Until at least one domain is allow-listed, embedding is disabled and the embed will fail to load (surfacing as a `TIMEOUT` error in the SDK).
* Add every origin you embed from — production, staging, and localhost for development.
* Enforcement happens server-side (via `frame-ancestors`), so a study ID leaking somewhere it shouldn't be embedded is not enough to render it there.
## Content Security Policy on your site
If your site sets a CSP, allow the Versive frame:
```
Content-Security-Policy: frame-src https://getversive.com https://www.getversive.com;
```
For **voice and video studies**, the browser also needs permission to delegate microphone/camera to the iframe. The SDK sets `allow="microphone; camera"` on the iframe automatically, but if you set a `Permissions-Policy` header, include the Versive origin:
```
Permissions-Policy: microphone=(self "https://www.getversive.com"), camera=(self "https://www.getversive.com")
```
## What the SDK does (and doesn't do)
* The SDK is a thin, zero-dependency wrapper: it creates a sandboxed iframe, shows loading state, and relays a small set of `postMessage` events. All study logic, AI moderation, and data collection happen inside the iframe on Versive's origin.
* Messages between your page and the iframe are **origin-validated in both directions** — the SDK ignores messages that don't come from the study iframe, and the study ignores commands from other origins.
* No API keys or secrets are used in the browser. The only identifier the SDK needs is the public study ID; access control comes from the domain allow-list.
## Data hygiene
`context` values travel as URL query parameters and are stored as response metadata:
* Use opaque IDs (`userId: 'u_8f3k2'`), never emails, names, or tokens.
* Anything you pass can be seen by the participant in DevTools — treat it as public.
# The AI interviewer
Source: https://docs.getversive.com/studies/ai-interviewer
Configure how Versive's AI moderator conducts your interviews
The AI interviewer is the conversational moderator that runs your study: it asks your questions, listens, probes with follow-ups, and keeps the conversation on track. Everything about its behavior is configurable in **Settings → AI Interviewer**.
The AI Interviewer tab is hidden for studies using the **Survey** engine, since surveys don't have conversational questions.
## Interviewer mode
Find it under **Advanced settings** on the AI Interviewer tab.
| Mode | Behavior |
| - | - |
| **Quality** (default) | Smarter, more natural follow-up questions — best results for depth interviews. |
| **Fast** | Quicker and more scripted — good for short studies where speed matters. |
## Personality & guidelines
* **Description** (up to 900 characters) — the interviewer's persona: tone, role, and style. For example, a warm UX researcher, or a neutral market-research moderator.
* **Guidelines** (up to 3,000 characters) — behavioral rules for the whole interview. When set, your guidelines replace Versive's defaults, so include everything you care about (probing style, what to avoid, how to handle off-topic answers).
## Study context
Add **Study context** (up to 3,000 characters) to give the interviewer background about your study, product, audience, or terminology. For example: "We're studying how small business owners use our invoicing tool. Most participants manage billing themselves and send fewer than 20 invoices per month."
This optional background helps the interviewer ask more relevant questions and follow-ups in both traditional and realtime voice interviews, including exploratory questions. It supplements your Description and Guidelines. Leave it blank or clear it to run interviews without additional study context.
Study context is loaded by the interviewer on the server and excluded from the public study data sent to participants' browsers. The 3,000-character limit also applies to API and assistant updates.
## Memory
Turn on **Memory** to let the interviewer learn from completed interviews in the same study and ask sharper, more informed follow-up questions as responses accumulate.
After each completed live interview, Versive extracts small observations — emerging findings, follow-up questions that worked, threads participants left open — and folds them into a per-study briefing. In later interviews, the interviewer uses that briefing to pursue unresolved threads, probe findings that need confirmation, reuse probes that landed, and skip ground that's already well covered.
Good to know:
* Off by default; toggle it in **Settings → Memory**. The same tab shows what the interviewer has learned so far, grouped by question, to members who can see the study's results.
* **What should the memory focus on?** (up to 300 characters) — optional. Steers what gets remembered from each completed interview. It applies to interviews completed after you save, for example "Capture price sensitivity and the reasons behind it; ignore feedback about the app."
* **Any rules for using it in interviews?** (up to 300 characters) — optional. Added to the interviewer's memory briefing. It applies to live interviews as soon as you save, for example "Don't bring up competitors from memory unless the participant mentions them first."
* Only completed live interviews contribute — simulated interviews don't feed memory.
* Findings are treated carefully: a pattern needs multiple independent confirmations before the interviewer treats it as established, and when participants disagree, the interviewer probes to resolve the disagreement rather than assuming.
* The interviewer never reveals or attributes what earlier participants said — memory shapes which questions get asked, not what gets shared.
* In a folder with a [transcript retention policy](/platform/folders-and-permissions#transcript-retention), what memory learned from an interview is deleted along with its transcript.
* Memory can also be set through the API: `enableMemory`, `memoryFocus`, and `memoryUsageRules` in the study `config` ([Create study](/api-reference/studies/create-study), [Update study](/api-reference/studies/update-study)).
## Question rephrasing
By default the AI may **rephrase the next question** so it flows naturally from the conversation ("You mentioned onboarding was confusing — walk me through what happened when…"). You can:
* Turn rephrasing off entirely if exact wording matters (e.g. standardized instruments).
* Add **rephrasing instructions** (up to 300 characters) to constrain how questions may be reworded.
## Follow-ups
Follow-up behavior is configured per question — see the [AI Question settings](/studies/question-types#ai-question) for follow-up limits, instructions, and duration targets.
## Transcription keywords
Under **Advanced → Keywords**, add domain-specific terms — company names, product names, industry jargon — to improve voice transcription accuracy.
## Voice settings
For studies in the Voice to voice Realtime conversation mode, tune the **silence threshold** (0.5–5 seconds, default 1.5) that controls how long the AI waits after the participant stops speaking before responding.
# Languages & translations
Source: https://docs.getversive.com/studies/languages
Run one study in up to 20 languages with AI translation
Versive can automatically translate your entire study — all questions, plus the welcome, thank-you, and screen-out messages — into 20 languages:
Arabic, Chinese, Dutch, English, Finnish, French, German, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Russian, Spanish, Swedish, Turkish, Ukrainian, and Vietnamese.
## Language settings
Configure languages in **Settings → Languages** (editable while building the study):
| Setting | Description |
| - | - |
| **Default language** | The language the study was written in. |
| **Supported languages** | The languages participants can switch between while taking the study. |
| **Starting language** | The language participants see first when they open the study. Falls back to the default language if unset. |
### Per-link language override
You can also set the starting language per link by appending `?lang=` to the study URL — handy when you're sending different language cohorts their own links:
```
https://getversive.com/s/your-study-id?lang=de
```
## Reviewing translations
AI translations are editable: review any question's translated text and adjust wording where needed. Manually edited translations are tracked so re-translating the study won't overwrite your edits. Translation status per language is visible while the study translates in the background.
Question media assets can also have **per-language variants**, so German participants can see a German screenshot while French participants see a French one.
## Translations via the API
You can trigger translation and manage translated question text programmatically — see [Translate a study](/api-reference/studies/translate-study) and the [Translated Questions endpoints](/api-reference/translated-questions/list-translated-questions).
# Launching & sharing
Source: https://docs.getversive.com/studies/launch-and-sharing
Share links, participant sources, email outreach, embeds, and AI simulation
The **Launch** tab is where a study meets its participants. It has five sub-tabs: **Link**, **Send**, **Recruit**, **Simulate**, and **Embed**.
## Link
Every study has a public share URL:
```
https://getversive.com/s/{studyId}
```
Anyone with the link can take the study while it's live.
### Hidden fields & participant tracking
Append URL parameters to pass metadata into the response without asking the participant:
```
https://getversive.com/s/{studyId}?source=newsletter&cohort=beta
```
Parameters are stored as response metadata and available in results, filters, and CSV exports, and to AI apps connected through the [MCP server](/mcp/tools) if your organization [shares participant metadata with AI apps](/platform/organizations-and-roles#ai-apps). If you've configured a [unique identifier](/studies/settings#sharing--participants), include it the same way to track individual participants and enable cross-device resume.
URL parameters are visible to participants and can end up in browser history, logs, and analytics. Use non-sensitive values like `source=newsletter` or an opaque internal ID — never emails, names, or secrets. For individually tracked invitations, prefer [personal links](#send-email-outreach) or the [API](/api-reference/interviews/create-interview), which keep metadata server-side.
### Participant sources
Recruiting from more than one channel? Add named **sources** on the Link tab. Each source gets its own share link (`…/s/{studyId}?source=`) and can send its participants somewhere different at each exit point:
| Outcome | Default behavior | With a custom URL |
| - | - | - |
| **Completion** | The study's thank-you page | Full-page redirect |
| **Screenout** | The study's [screen-out destination](/studies/settings#sharing--participants) | Full-page redirect |
| **Quota / paused** | The study's pause URL or paused page | Full-page redirect |
This is how you give a panel its completion-code redirect while your email list still sees the thank-you page — each channel keeps its own behavior.
Good to know:
* Custom URLs must be `https://` and support `{param}` placeholders: any parameter on the participant's link is substituted in, which is how panel IDs and completion codes (e.g. `{PID}`) pass through.
* A source's URL key is generated from its name when created and then locked — renaming the source later never breaks links you've already distributed.
* Links without a `?source=`, with an unknown key, or hitting an outcome with no custom URL fall back to the study's defaults.
* Some sources are created for you: email outreach creates an `emails` source, and panel recruiting creates a `respondent` source (its screenout redirect is managed by Versive so panel payment tracking keeps working).
## Send (email outreach)
Invite specific people and track them individually. Each participant gets a personal link (`…?vid=`).
* **Add participants** by uploading a CSV, entering them manually, or importing from your [Audience](/studies/recruiting-participants#your-audience).
* **Compose emails** in the built-in editor with **merge fields** (name, custom metadata, and the participant's personal interview link), reusable [email templates](/platform/templates#email-templates), and a preview.
* **Track delivery** per recipient: delivered, opened, bounced, failed, or spam complaint — plus complete/incomplete study status.
* **Suppression is automatic**: unsubscribed and bounced contacts are skipped, and every email includes one-click unsubscribe.
* **Export** the participant table (links, statuses, email history, metadata) to CSV.
Email sends count against your plan's monthly email allowance.
## Recruit (participant panel)
Recruit from a global pool of 4 million+ consumers and professionals across 150 countries, powered by Respondent. See [Recruiting participants](/studies/recruiting-participants) for the full workflow — screeners, incentives, statuses, and payments.
## Simulate (AI test participants)
Before launching to real people, run **simulated interviews** with [AI personas](/ai-tests/personas) to shake out confusing questions, broken logic, and awkward AI-interviewer behavior.
* Pick personas and an execution count per persona (up to 10 runs per persona, 100 simulations per batch).
* Conversational questions are simulated for real: AI Question and Exploratory questions run as full multi-turn conversations, so you can see how the interviewer probes before real participants do.
* Simulated responses appear in your Results tab, clearly marked as simulations, and can be included in or excluded from insights.
* Simulations consume AI credits like real completions, so they are available on plans with AI credits.
Some question types are skipped during simulation: Prototype Task, Website Task, Tree Test, Conjoint, Media Upload, Website Link, and Calendar.
## Embed
Embed the study in your own product — as an inline widget or a modal — using the `@getversive/embed` SDK or a zero-code script tag. The Launch → Embed tab generates ready-to-paste snippets for your study.
Embedding requires an organization admin to allow-list your site's domain first.
Full documentation in the [Embed SDK section](/sdk/overview).
## Public result sharing
Share read-only results without inviting people into your workspace: generate **public sharing links** for study insights, individual interview transcripts, or reports. Links can be revoked at any time. See [Collaboration](/platform/collaboration#public-sharing-links).
# Logic & branching
Source: https://docs.getversive.com/studies/logic
Build conditional paths, screen participants out, and pipe answers forward
Question logic lets each question branch based on the participant's answer. Rules are evaluated **top to bottom — the first matching rule wins**. If no rule matches, the interview simply continues to the next question.
## Conditions
The conditions available depend on the question type:
| Question type | Available conditions |
| - | - |
| Multiple Choice | Always · Equals · Is not (single-select) · Includes, Does not include, Fewer than N selections (multi-select) |
| Rating Scale, NPS, Star Rating, Number | Always · `=` · `≠` · `>` · `>=` · `<` · `<=` |
| AI Question, Exploratory, Open Text, Short Text | Always · **AI rule** |
| All other types | Always |
**Is not** and **Does not include** need an answer to compare: a question the participant skipped matches neither, so the next rule (or the next question in order) applies.
### AI rules (smart conditions)
For open-ended questions, you can write a condition in plain language — for example, *"If the participant mentions price as a concern"* — and Versive's AI evaluates it against the response. AI rules are evaluated in order along with your other rules.
Keep AI rules specific and observable ("mentions a competitor by name") rather than interpretive ("seems unhappy"). Specific rules evaluate more reliably.
## Actions
When a condition matches, one of five actions runs:
| Action | What happens |
| - | - |
| **Go to question** | Jump ahead to a later question, skipping everything in between. |
| **Move to group** | Jump ahead to a question group — the interview enters at the group's first question and continues from there. |
| **End interview** | Finish the interview immediately and show the thank-you message. |
| **Screen out** | End the interview — the response is marked screened-out and doesn't count toward your quota. The participant lands on your [screen-out destination](/studies/settings#sharing--participants): the screen-out page, a custom URL, or a per-channel [source redirect](/studies/launch-and-sharing#participant-sources). |
| **Redirect to URL** | Send the participant to an external URL (not available on AI Question or Exploratory questions). |
### Where jumps can land
Jumps are **forward-only**: a rule can only target a question or group that comes after the question it belongs to, so the last question of a study has no jump targets. When your study uses question groups, two more rules apply:
* **Randomized groups** — questions inside a group with randomized order can't be targeted directly, since their position differs per participant. Target the group itself instead: each participant enters at whichever question their shuffled order puts first, so randomization is preserved.
* **Empty groups** can't be targeted — there's no question to jump to.
The target pickers only offer valid destinations, so you don't need to memorize these rules. If a later edit invalidates a saved rule — say, deleting the target or enabling randomized order on its group — the logic editor flags the rule with a warning.
## Showing a question conditionally (display logic)
Branching decides where the interview goes next; a **display condition** decides whether a question is shown at all. Open the question's logic settings, and under **Display logic** choose **Add display condition**: pick an earlier question as the source and set the condition on its answer. A question is shown only when **all** of its display conditions are met; otherwise the participant skips it and the interview continues with the next question that can be shown.
* **Sources** come from earlier in the study and use the same conditions as branching: Multiple Choice (Equals; Is not for single-select; Includes, Does not include and Fewer than N selections for multi-select), Rating Scale, NPS, Star Rating and Number (`=` `≠` `>` `>=` `<` `<=`), or an open-ended question with an AI rule. The picker only offers eligible questions.
* A source can't be one the participant might not see before the question — for example a question inside a randomized group that could shuffle it after, or one inside a randomizer arm the participant may skip. The editor flags saved conditions that no longer hold (a renamed or removed option, a source moved after the question), and the study can't be saved until they're fixed.
* If the participant never answered the source — a branch skipped it, or the source was itself hidden — the condition doesn't pass and the question is hidden. This holds for **Is not** and **Does not include** too: they need an answer to compare.
* AI rules on display conditions are evaluated as soon as the participant leaves the source question, so later questions don't wait on them. If an evaluation fails, the question is shown rather than silently skipped.
* Branching and display conditions work together: branching picks the next question, then display conditions decide whether it and the questions after it are shown. When every remaining question is hidden, the interview ends with the thank-you message.
## Screening participants
To build a screener, put your qualifying questions first and add **Screen out** rules to each. Screened-out participants see the customizable [screen-out message](/studies/settings#study-messages), and their responses are excluded from completions and insights by default.
## Reusing earlier answers (mentions)
To pipe an earlier answer into a later question, use **mentions**: type `@` in the question editor and pick a previous question to insert a reference to its answer — or to a specific option or property of it. Each participant sees their own earlier answer woven into the question text ("Why did you choose the *Pro* plan?").
Answers from these types can be referenced: Open Text, Short Text, Number, Multiple Choice, Matrix Rating Scale, Card Sort, Ranking, and Allocation.
## Good to know
* The logic editor warns you about rules that can no longer fire: targets that were deleted, moved to before the question, or moved inside a randomized group, plus rules on the last question.
* Logic is language-aware — rules are evaluated against the participant's study language.
* Chaining multiple rules on one question is fully supported; order them from most to least specific since the first match wins.
# Studies overview
Source: https://docs.getversive.com/studies/overview
AI-moderated surveys and interviews with real participants
A **study** is Versive's core research unit: a set of questions that participants complete through a shareable link, an embed in your product, or a recruited panel. Depending on how you configure it, a study can feel like a traditional survey, a conversational AI-moderated interview, or a full voice/video interview.
## Study types
Every study has one of two types, chosen when you create it and changeable later in **Settings → General**:
| Study type | What it does | Usage |
| - | - | - |
| **AI interview** | AI-moderated interview: participants answer, the AI asks follow-ups | 1 AI credit per completion (2 in the Voice to voice Realtime conversation mode) |
| **Survey** | Classic survey with no AI questions — structured question types only | 1 survey response per completion, no AI credits |
AI interviews need a plan with AI credits. On the Free plan, new studies are surveys, and a survey can't be switched to an AI interview until you upgrade. See [Plans and usage](/getting-started/concepts#plans-and-usage).
## Conversation modes
The conversation mode controls how participants respond. Surveys support Text only and Text and voice; AI interviews can use any mode.
| Mode | Description |
| - | - |
| **Text only** | Participants type their answers in a chat interface |
| **Text and voice** | Participants can type or speak (default) |
| **Voice only** | Participants answer by voice |
| **Voice with preview** | Participants speak, then review and edit the transcription before submitting |
| **Video** | Records participant video alongside the interview |
| **Voice to voice Realtime** | A live spoken conversation with the AI on the realtime engine, with a configurable silence threshold (2 AI credits per completion) |
## Ways to create a study
* **AI study assistant** — describe your research goals in natural language and the assistant generates the full study: questions, settings, and logic. Keep chatting to refine it — add, reorder, or rewrite questions, change settings, and update logic rules, with structured change tracking. You can also import a Figma prototype and get auto-suggested questions.
* **Manual creation** — build question by question with the drag-and-drop builder and the question library.
* **Templates** — start from pre-built or organization-specific [study templates](/platform/templates).
## Study status
New studies are live by default — they accept participants as soon as you share the link. You can **pause** a study (visitors are sent to your custom pause URL if one is set) and **archive** it when the research is done. A study also stops accepting new participants once it reaches its [quota](/studies/settings#quotas); the study itself stays live so anyone mid-interview can finish.
## Next steps
All 20+ question types and their settings.
Every setting, tab by tab.
Test Figma prototypes and web-based prototypes from Figma Make, v0, Lovable, Bolt, Replit, and Framer.
Conditional paths, screen-outs, and AI-evaluated rules.
Links, email outreach, embeds, and AI simulation.
# Prototype testing
Source: https://docs.getversive.com/studies/prototype-testing
Test Figma prototypes and web-based prototypes (Figma Make, v0, Lovable, Bolt) with real participants
Versive embeds two kinds of prototypes in studies, and each has its own question type and media type:
* **Figma prototypes** — click-through designs made in Figma (`figma.com/proto/…` links). Versive integrates with Figma directly: frame-by-frame path tracking, click capture, and automatic goal detection.
* **Web-based prototypes** — working apps published from tools like **Figma Make, v0, Lovable, Bolt, Replit, and Framer**. These are real websites, so they're embedded directly and participants use the actual app.
## Which one do I use?
| You have | Give participants a task | Show it beside a question |
| - | - | - |
| A **Figma prototype** (`figma.com/proto/…`) | [Prototype Task](/studies/question-types#prototype-task) | [Figma media type](/studies/question-media#figma-prototypes) |
| A **web-based prototype** (Figma Make, v0, Lovable, Bolt, …) or any website | [Website Task](/studies/question-types#website-task) with **Embed the site** on | [Embedded website media type](/studies/question-media) |
The task types are for "try to do X" scenarios — participants start the task, explore, think aloud, and finish explicitly. The media types show the prototype as context beside any question — ratings, open-ends, or AI-moderated questions about what participants see.
## Figma prototypes
Paste the prototype link into a **Prototype Task** (or attach it as Figma media on any question). Versive reads the file and its interactions from Figma, so you can pick a starting frame, and — for tasks — a **goal frame** that detects completion automatically. Every click and screen change is tracked.
The Figma file needs link sharing enabled ("Anyone with the link can view"), or participants will see a Figma login inside the study.
## Web-based prototypes
Paste the **published** app link into a Website Task (with **Embed the site in Versive** on) or an embedded-website media attachment — direct embedding is detected automatically from the URL:
| Tool | Link to paste | Where to get it |
| - | - | - |
| **Figma Make** | `your-app.figma.site` | **Publish** your Make app in Figma |
| **v0** | `your-app.vercel.app` | **Deploy** the app in v0 |
| **Lovable** | `your-app.lovable.app` | **Publish** in Lovable |
| **Bolt** | `your-app.bolt.host` | **Deploy** in Bolt |
| **Replit** | `your-app.replit.app` | **Deploy** in Replit |
| **Framer** | `your-site.framer.website` | **Publish** in Framer |
Editor and share links don't embed — the builder tells you how to fix the link when it recognizes one (a `v0.app/chat/…` share link, a `figma.com/make/…` editor link). Any other website works too; sites not in this table open in a secure virtual browser instead of a direct embed.
### Check your link before launching
Direct embedding requires the prototype to be **publicly reachable** — the most common failure is an app that sits behind a login:
* **v0 / Vercel** — Deployment Protection (password or SSO) must be off.
* **Figma Make** — apps restricted to your organization's members won't load for participants; publish publicly.
* **Replit** — private deployments require a Replit login.
The builder's **Preview prototype** panel shows exactly what participants will see. If it asks for a login there, it will for them too.
## What's captured
| Signal | Figma prototype | Web prototype (direct embed) | Other websites (virtual browser) |
| - | - | - | - |
| Task duration | ✅ | ✅ | ✅ |
| Voice think-aloud transcript | ✅ | ✅ | ✅ |
| Completion | ✅ automatic (goal frame) | ✅ self-reported | ✅ self-reported |
| Screens / pages visited | ✅ | — | ✅ |
| Clicks | ✅ | — | — |
A directly embedded web app is opaque to Versive — clicks and navigation inside it aren't tracked. For richer capture, turn on **browser-tab screen recording** in the Website Task card to record what participants do, and lean on voice think-aloud plus AI follow-up questions for the "why".
## Troubleshooting
* **Blank or stuck panel** — after \~15 seconds participants get an **Open in a new tab** fallback. Usually means the deployment is slow, was taken down, or is login-walled — recheck the builder preview.
* **App loads but misbehaves** — prototypes that rely on popup-based sign-in or third-party cookies can act up inside an embed. Test your specific app in the preview; if it needs a real tab, turn off the embed toggle to use the new-tab flow.
* **Site shows the virtual browser instead of embedding** — only the domains in the table above embed directly; everything else intentionally routes through the virtual browser.
# Question media
Source: https://docs.getversive.com/studies/question-media
Attach images, Figma prototypes, videos, PDFs, and embedded websites to questions
Most questions can include rich media that participants see alongside (or instead of) the question text — the backbone of concept tests, design feedback, and stimulus-based research.
## Media types
| Type | Notes |
| - | - |
| **Images** | Screenshots, mockups, ad creative — anything visual. |
| **Figma prototypes** | Interactive embeds — participants click through the real prototype, with frame navigation. |
| **Videos** | With autoplay and loop options. |
| **PDFs** | Document display for concept docs, menus, one-pagers. |
| **Embedded websites** | Show a live site inside the question. Published prototypes from Figma Make, v0, Lovable, Bolt, Replit, and Framer are [embedded directly](/studies/prototype-testing); other sites open in a secure virtual browser. |
### Supported formats and limits
Uploaded files must be one of these formats and at most 50 MB each:
* **Images** — JPEG, PNG, GIF, WebP, BMP, TIFF
* **Videos** — MP4, WebM, QuickTime (MOV)
* **Documents** — PDF
SVG is not accepted; export it as PNG first. Organization logos accept the same image formats up to 10 MB.
The file picker offers supported formats. If an upload is rejected, the builder explains known validation problems,
such as an unsupported file type or a file exceeding the size limit. Choose a supported format or a smaller file
before retrying.
### Viewing media
In the study builder and results, media stays visible when your sign-in session renews automatically. You do not need to reload the page.
Shared insights display uploaded question images, videos, and PDFs. Viewers can see these previews through the shared link without signing in.
## Layout & sizing
* **Layout** — inline with the question, or full-screen alongside it (best for detailed designs).
* **Sizing** (full-screen) — fit to view, or scroll for tall content.
* **Max width** (inline images and videos) — full width by default, or capped at 10% to 90% of the question column in 10% steps. Use this for tall or portrait media so it doesn't push the answer controls off screen, especially on phones.
## Figma prototypes
Paste a Figma link to embed an interactive prototype. Versive reads the file and its defined interactions directly from Figma.
The Figma file needs link sharing enabled ("Anyone with the link can view") for Versive to import it. Versive shows specific guidance if your file's sharing settings block the import.
For task-based prototype testing with automatic completion detection, use the dedicated [Prototype Task](/studies/question-types#prototype-task) question type instead of a media attachment.
## Per-language variants
If your study runs in [multiple languages](/studies/languages), you can attach different media per language — German participants see the German screenshot while French participants see the French one.
# Question quotas
Source: https://docs.getversive.com/studies/question-quotas
Cap completes per answer option on a Multiple Choice question
A question quota caps how many completed interviews may choose a given option on a **Multiple Choice** question. Use it to fill segments from a single link, for example 50 participants who pick *iPhone* and 50 who pick *Android*, without creating a link per group.
Question quotas are independent of the [study quota](/studies/settings#quotas): a study can have both, and each is enforced on its own. Only Multiple Choice questions support them.
## Setting up a quota
In the study editor, select a Multiple Choice question. The **Quotas** section sits below its logic rules.
Click **Add quota**, pick the match type and the option, and enter the number of completes. Options without a row are unlimited. A question can hold up to 50 rows, one per match type and option.
Quotas are saved with the rest of the study. Questions that carry a quota show a target icon in the question list.
## Equals vs Includes
| Match | Available on | An answer counts when |
| - | - | - |
| **Equals** | Single- and multi-select | The participant selected exactly that one option and nothing else. |
| **Includes** | Multi-select only | The option is among the selected options, whatever else was chosen. |
Custom text typed into an **Other** option never matches an option quota. On an Equals quota, an Other entry alongside the option also means the answer is no longer an exact match, so it doesn't count.
Matching is language-aware: a translated option label counts toward the same quota as the original.
## Closing an option
Set the limit to 0 to close an option: the next participant who chooses it is screened out. Remove the row to lift the cap.
## What participants see
A participant whose answer lands on a full option is screened out at that moment, and their response is marked screened out rather than complete. They land on the study's [screen-out destination](/studies/settings#sharing--participants): the screen-out message, your custom URL, or the per-channel [source redirect](/studies/launch-and-sharing#participant-sources). Other options keep accepting answers.
Question quotas don't gate entry. Participants can start the study and answer earlier questions before reaching a full option, so place quota questions early, typically with your screener, to keep screened-out sessions short. Use a [study quota](/studies/settings#quotas) when you need to turn participants away at the door.
## What counts toward a quota
* Only **completed** interviews count. Screened-out and in-progress interviews don't.
* Mock interviews, previews, and AI simulations never count, and a mock interview is never screened out by a quota.
* Archived interviews don't count.
Each saved row shows a **N so far** readout with its current count, in red once the option is full. The header quota pill covers the study quota only; question quota progress lives here in the question editor.
Caps are approximate. The count is checked when a participant answers, and everyone already past the question can finish, so a few participants answering at the same moment can push an option slightly past its limit.
## Good to know
* Quotas match on option text. Renaming an option in the editor carries its quota along. Deleting an option, or changing the question to another type, removes its quotas.
* An Includes quota only works while the question is multi-select. If you turn multi-select off, switch the quota to Equals or remove it before saving; the study won't save with an Includes quota on a single-select question.
* Quotas are enforced in every conversation mode, including voice.
* Manage question quotas programmatically with the [API](/api-reference/quotas/update-question-quotas) or the MCP server's [`set_question_quotas`](/mcp/tools) tool.
# Question types
Source: https://docs.getversive.com/studies/question-types
Every question type in the study builder, with all available settings
Versive offers 20+ question types organized into four groups: **Open response**, **Choices & sorting**, **Ratings & feedback**, and **Other**. Every question type supports a **Required** toggle, and most support media attachments — see [Question media](/studies/question-media).
**Surveys** (the no-AI engine) hide the conversational types (AI Question and Exploratory) and use structured types only.
## Open response
### AI Question
The signature Versive question: an open-ended question where the AI interviewer probes with intelligent follow-ups based on what the participant says.
| Setting | Description |
| - | - |
| Limit follow-up questions | Cap the number of AI follow-ups (1–10, default 5 when enabled). Leave off for unlimited. |
| Add instructions | Guidance shown to the AI interviewer for this question (also displayed as a subtitle to participants). |
| Interviewer notes | Private notes that steer the AI's probing — Versive can also suggest these automatically. |
| Duration tracker | Show an on-screen timer with a target response window (`min`/`max` duration). The timer is yellow before the minimum, green in range, and red from the maximum on. |
| Follow-up durations | Separate min/max duration targets for follow-up answers (defaults to 50% of the main question's targets, with a 15-second minimum). |
### Exploratory
A goal-driven, multi-turn AI conversation. Instead of a fixed question, you give the AI a **research goal** and a **turn budget** (default 8 turns), and it explores the topic conversationally until the goal is covered or the budget runs out.
Exploratory questions support the same **duration tracker** settings as AI Questions:
| Setting | Description |
| - | - |
| Enable duration tracker | Show participants an elapsed-time timer for each response. |
| Response duration range (optional) | Set min/max targets in seconds for the opening response. The timer changes color after the participant starts typing or recording: yellow below the minimum, green within range, and red at the maximum. |
| Follow-up response duration (optional) | Override min/max targets for later responses. Each unset target defaults to 50% of the corresponding opening target, with a 15-second minimum. |
The timer resets for each new question or follow-up. It pauses after 30 seconds without an initial response and resumes when the participant types or records; stopping a recording also pauses it. Reaching the maximum shows a reminder to wrap up, without forcing the participant to advance. These targets apply to individual responses, not the entire exploratory conversation.
Targets must be non-negative whole seconds, and the minimum cannot exceed the maximum when both bounds of a response range are explicitly set. A single follow-up override is allowed even if it falls outside the automatic bound; in that case the timer may have no green interval.
Turning the tracker off in the editor clears its duration targets; disabling it through the assistant or MCP preserves them for reuse. Ask the assistant to clear a specific target to remove it, or clear a follow-up override to restore automatic timing. MCP callers can pass `clear_duration_fields` to `edit_question` with a list containing `min_duration`, `max_duration`, `follow_up_min_duration`, or `follow_up_max_duration`; passing `null` for a duration argument keeps its stored value unchanged.
### Open Text
Long-form free text (or voice) input. Supports optional instructions shown to participants, and an optional **character limit** — participants see a live counter and typing stops at the limit.
### Short Text
A brief, single-line text answer. Supports an optional **character limit** with a live counter.
### Message
Not a question — displays information, instructions, or media between questions. Settings: custom button text (default "Sounds good") and an optional **timer** that participants must wait out before continuing.
## Choices & sorting
### Multiple Choice
Single- or multi-select from a list of options.
| Setting | Description |
| - | - |
| Multi-select | Allow choosing more than one option, with an optional **max selections** limit. |
| Display format | Single-select only: show options as the classic list, or collapse long option lists into a **dropdown**. |
| Exclusive options | Multi-select only: mark options like "None of the above" as exclusive — picking one clears every other selection, and picking any other option clears it. |
| Include "Other" | Adds a free-text "Other" option, with an optional character limit for the field. |
| Randomize order | Shuffle option order per participant to avoid order bias. |
### Card Sort
Participants sort cards into categories — ideal for information architecture research. Settings: cards, categories, randomize order, **allow new categories** (open sort), and **allow new cards**.
### Ranking
Rank a list of options by preference, via **drag-and-drop** or **dropdown** format. Supports randomized order.
### Matrix Ranking
Rank options across multiple **criteria** (e.g. rank features by importance *and* by satisfaction). Same format options as Ranking.
### Allocation
Distribute a fixed budget of points across options (default total: 100). Options can optionally be pulled from a previous question's answers, and you can enforce the total as a hard limit. Turn on **custom options** to let participants add their own options, each with a name and a value; their values count in the total, and a name that is already in the list is refused. With the limit off, each option is a separate value, and an optional **maximum per option** caps every value (for example 100, for a percentage per option). The total, or each option, can also be checked against an earlier answer — see [Checks against earlier answers](#checks-against-earlier-answers).
### Matrix Allocation
A grid of values: **rows** are the things being split, **columns** are scenarios or time points (up to 8), and each column is filled in on its own. With **Has allocation limit** on (the default), every column must add up to the **total allocation** (default 100), and participants see a live total under each column. With the limit off, each cell is a separate value, an optional **maximum per option** caps every cell, and columns don't need to add up. Participants type a number in each cell, with up to two decimal places. Columns never affect each other. Supports randomized row order; columns keep their order. Results show one Allocation-style breakdown per column.
### Conjoint
Choice-based conjoint analysis (CBC): participants repeatedly choose between product concepts assembled from your attributes, revealing how much each attribute drives preference.
| Setting | Description |
| - | - |
| Attributes & levels | The product dimensions being traded off (e.g. Price, Quality, Support), each with 2–5 levels. 3–6 attributes recommended. |
| Concepts per task | How many concepts appear side by side in each choice (2 or 3). |
| Tasks per respondent | How many choice tasks each participant completes (6–12). |
| Include "None" option | Adds a "None of these" choice to every task. |
| Randomization | Shuffle task order and concept order per participant. |
Results include **attribute importance**, **level utilities**, **choice shares**, and design diagnostics — all computed automatically in Insights.
### Tree Test
Findability testing on a navigation tree. Participants complete tasks by locating the right node in your hierarchy.
| Setting | Description |
| - | - |
| Tree | The nested navigation structure to test. |
| Tasks | Each task has a description and one or more correct answers. |
| Randomize tasks | Shuffle task order. |
| Show task progress | Display progress through tasks (on by default). |
| Max levels | Maximum visible tree depth (default 6). |
| Behavior options | Start expanded, allow skip, allow going back, allow selecting parent nodes, custom instructions. |
## Ratings & feedback
### Rating Scale
A Likert-style scale (default 1–5) with customizable labels for the low, middle, and high points.
### Star Rating
A configurable icon rating — **stars, hearts, or paws** — with an adjustable maximum (default 5).
### NPS
Standard Net Promoter Score (default 0–10) with customizable end labels ("Not at all likely" / "Extremely likely").
### Matrix Rating Scale
Rate multiple items on the same scale. Supports randomized row order and an optional **N/A** column.
An optional **one selection per column** constraint makes each scale value usable by at most one row — once a row picks a value, it's greyed out for the others (N/A stays shared). Useful for forced-ranking grids. The toggle is only available when every row can still receive a value: at least as many scale points as rows, or the N/A column enabled.
## Other
### Prototype Task
A Figma prototype navigation task. Participants attempt to complete a task in your interactive prototype while Versive tracks their path.
| Setting | Description |
| - | - |
| Goal node | The Figma frame that counts as task success — completion is detected automatically. |
| Enable recording | Record the participant's prototype session. |
Task outcomes are tracked as *not started, in progress, completed,* or *gave up*.
### Website Task
Send participants to a live website or prototype to complete a task.
| Setting | Description |
| - | - |
| URL & button text | The site to visit and the button label (default "Visit website"). |
| Voice recording | Ask participants to think aloud while browsing (on by default). |
| Embed the site | Show the site inside the study instead of a new tab. Published prototypes from **Figma Make, v0, Lovable, Bolt, Replit, and Framer** are embedded directly — participants use the real app in-page. Other websites open in a secure virtual browser. |
Paste the *published* prototype link — the `figma.site`, `vercel.app`, `lovable.app`, `bolt.host`, `replit.app`, or `framer.website` URL — not the editor or chat share link. For Figma design prototypes (`figma.com/proto/...`), use the Prototype Task instead. See [Prototype testing](/studies/prototype-testing) for the full setup guide.
### Website Link
Redirect the participant to an external URL (e.g. a partner survey or booking page).
### Media Upload
Participants upload images and/or videos. Configure allowed types, maximum number of files, and maximum file size.
### Email
Capture a valid email address.
### Number
Numeric input, with an optional min/max range validation. The number can also be checked against an earlier answer — see [Checks against earlier answers](#checks-against-earlier-answers).
### Date
Structured date entry with month/day selectors and a typed four-digit year. Full date is the default; authors can instead collect month & year or year only and choose MDY, DMY, or YMD display order. Optional earliest/latest limits restrict which dates participants can submit. Answers remain stored in sortable ISO partial-date format: `YYYY-MM-DD` for full dates, `YYYY-MM` for month and year, and `YYYY` for year only. Storage is independent of display order.
### Calendly
External Calendly booking — share a scheduling link (e.g. for a follow-up session) inside the study.
## Referencing earlier answers
Questions can reference earlier answers with **mentions** — type `@` in the question editor to pipe a previous answer into the question text. See [Reusing earlier answers](/studies/logic#reusing-earlier-answers-mentions).
## Checks against earlier answers
A Number or Allocation question can require its answer to compare with an earlier answer — for example, "patients who started treatment this year" must be at most "patients under your care", or an age-group allocation must total exactly that number. Open the question card and turn on **Checks against earlier answers**, then pick the earlier question (a Number question, or an Allocation question and one of its options) and the comparison: less than, less than or equal to, equal to, greater than or equal to, or greater than.
| Question | What receives the checks |
| - | - |
| Number | The typed number. |
| Allocation, **By total allocation** | The total. While the total has a check, **Has allocation limit** is off. |
| Allocation, **By allocation option** | One option of this question per check (e.g. "2025" must be at least "4Q25"). Options without a check stay free. |
A Number answer, and each Allocation option, can carry several checks; the Allocation total carries one. Several checks on one answer are joined with "and": every check must pass. The builder does not stop you from writing checks that no answer can satisfy, such as "equal to Q1" together with "less than Q1"; a participant who meets such a pair is stuck on the question, so check each pair against the answers you expect.
Participants see the check as a hint ("Enter a number 78 or less"; for a total with an "equal to" or "less than or equal to" check, "78 remaining") and cannot continue while a typed answer fails a check (an optional question can still be left blank). A check that fails prints one line under the answer, in the participant's language, such as "The number must be at most 100." or "The total must be at least 1200."; an "equal to" or "less than or equal to" check on an Allocation total shows the remaining count instead. If the earlier question was skipped, or answered with something other than a number, the check does not apply — the card warns you when the earlier question is not required. When a participant goes back and changes an earlier answer that a check reads, the later answers stay; the later question is checked again against the new value when the participant reaches it, and it blocks until the answer fits.
Renaming an option keeps its checks; deleting one drops them. If the earlier question is deleted, changes type, or ends up after the question it checks (including through randomization), the card flags the check so you can fix it. To also show the earlier value in the question text, add a [mention](#referencing-earlier-answers). Simulated interviews respect these checks too.
# Recruiting participants
Source: https://docs.getversive.com/studies/recruiting-participants
Bring your own users, manage an audience, or recruit from a 4M+ participant panel
There are three ways to get participants into a study:
1. **Bring your own** — share the [study link](/studies/launch-and-sharing#link) or [embed the study](/sdk/overview) in your product.
2. **Your audience** — invite contacts you've saved in Versive via [email outreach](/studies/launch-and-sharing#send-email-outreach).
3. **The participant panel** — recruit vetted participants through Versive's Prolific or Respondent integrations.
## Your audience
The **Audience** is your organization's contact list — a lightweight research CRM.
* Import contacts in bulk (deduplicated by email) or add them individually, with arbitrary metadata fields that become filterable columns.
* Add contacts to any study in one step: each gets a personal tracked interview link.
* Contact statuses track deliverability and consent — **unsubscribed** and **bounced** contacts are automatically excluded from future sends.
## The participant panel
The **Recruit** tab connects your study to consumers and professionals through two panel providers:
* **Prolific** is suited to fast consumer and general-population studies, with a searchable catalog of built-in audience filters.
* **Respondent** is suited to B2B and harder-to-reach professional audiences, with custom targeting criteria and screener questions.
### Setting up a Respondent project
1. Define your **target audience** — B2C or B2B targeting with demographics (age, education, household income, and more) and professional attributes (industries, skills, seniority, company size).
2. Add **screener questions** — multiple choice, checkboxes, text, numeric, or slider-scale questions that qualify participants before they reach your study.
3. Set the **incentive** — as a rule of thumb, budget about \$1 per minute of study length; B2B audiences typically require more.
### Setting up a Prolific project
1. Set the **participant count, estimated duration, and reward**. Versive displays the estimated total, including provider fees, before checkout.
2. If your study uses screen-out logic, Versive turns on screen-out payments automatically: set the **max screen-outs** and the **screen-out reward** (see below).
3. Search Prolific's filter catalog and add the demographic or behavioral criteria you need. You can assign distribution quotas across selected filter values.
4. Review the audience and cost, then choose **Pay and publish**. You can pause or resume recruitment from the project afterward.
Versive creates the required Prolific completion codes and sends participants back to Prolific automatically. Prolific projects cannot use Versive **redirect** logic, since the integration owns where participants go when they finish.
#### Screening participants out
Prolific's audience filters exclude people before they start your study, at no cost. Screen-out logic on a question inside your survey is different: those participants have already started, so Prolific requires them to be paid. When your study has screen-out logic, the Prolific project's **Screen-out questions** toggle is on and locked, and the section shows which questions screen participants out. A study without screen-out logic needs no screen-out budget: everyone who starts it counts as a completion. (If you plan to add screen-out rules after launch, turn the toggle on anyway; a budget can't be added once the study is published.)
* **Max screen-outs** — the number of paid screen-outs you're budgeting for. It defaults to one per participant, and Versive shows the qualify rate your budget implies (for example, 20 screen-outs for 20 participants assumes about 50% of people who start the study qualify). Screened-out participants don't use up study places. When the limit is reached, Prolific pauses recruiting and Versive emails your workspace owners, admins and creators.
* **Screen-out reward** — a fixed amount paid automatically to each screened-out participant. Prolific requires at least $0.14 and less than the participant reward. The default is $0.25; set it by how long participants spend before the screen-out question.
The screen-out budget (reward × max screen-outs, plus Prolific fees) is included in the checkout total; unused screen-out budget is refunded after you close the project (Versive processes the refund). The reward can't be changed after publishing, but while the study is active or paused you can **add screen-out slots** from the project's Submissions tab — pay for the extra slots and recruiting resumes automatically if Prolific had paused it. Unused top-up budget is included in the refund when you close the project.
Screened-out participants appear as **Screened out** in the project's submissions, and each panel row shows screen-outs used against the limit.
### Drafting a panel with the assistant
You can also ask the Versive Assistant (⌘J) to set up a panel: for example, "Recruit 50 US adults on Prolific for this study, \$8 for 10 minutes." It reads the study, looks up the provider's targeting options, shows you the plan with a cost estimate, and asks you to confirm before it creates anything. The result is a **draft** panel on the Recruit tab with a link to the review page; the assistant never pays or publishes, so nothing is charged until you choose **Pay and publish** there. If the study screens participants out, a Prolific draft includes the screen-out reward and the number of paid screen-outs, and the estimate covers them; buying more screen-out slots later is done from the panel. You can ask it to adjust a draft (participants, reward, filters, screen-outs, screener questions) or to check whether a draft is ready to publish. The same tools are available to agents connected through the [MCP server](/mcp/tools).
### Tracking recruitment
Panel projects have a lifecycle of **Draft → Active → Closed / Archived** and can be paused, resumed, duplicated, or closed. Respondent projects show funnel counts such as requested, invited, survey taken, qualified, and paid. Prolific projects show each submission's live status (including screened-out participants and how many screen-out slots remain) and let you approve, reject, or bulk-approve responses awaiting review.
Closing a Respondent project approves completed respondents for payment. You can also export Respondent profiles (name, job title, company, LinkedIn, skills, location, match quality) to CSV.
Panel recruiting is billed pay-as-you-go on top of your subscription — you pay per qualified participant, not from your credit allowance.
## Which approach when?
| Situation | Best option |
| - | - |
| You have engaged users and want product feedback | Your own link or the Embed SDK |
| You have a list of customers/leads to interview | Audience + email outreach |
| You need specific demographics or professions you don't have access to | Participant panel |
| You want feedback *today* and can't wait for recruiting | [AI tests](/ai-tests/overview) or [simulated interviews](/studies/launch-and-sharing#simulate-ai-test-participants) |
# Results & insights
Source: https://docs.getversive.com/studies/results-and-insights
Transcripts, AI analysis, themes, charts, reports, and exports
Once responses come in, two tabs on the study page do the heavy lifting: **Results** (individual responses) and **Insights** (AI analysis across all responses).
## Results
Browse responses in two views:
* **Transcript view** — a list of interviews with the full conversation transcript alongside. Voice and video interviews include an audio player, video playback, and word-level timestamps.
* **Grid view** — a spreadsheet with one row per respondent and one column per question, ideal for scanning structured answers.
Each interview shows the transcript, recordings (audio, video, and screen recordings if enabled), uploaded media, respondent details and metadata, duration, word count, tags, and notes. Specialized renderers show prototype task paths, tree test results, and website task sessions.
If a voice answer was transcribed poorly, you can **re-run transcription** — for a single message or the whole interview — directly from the transcript view.
Interviews move through statuses — *open, in progress, paused, processing, closed (complete), screened out,* and *canceled* — and can be archived. Simulated interviews are labeled with their persona and run number.
### Per-interview AI analysis
Every completed interview gets automatic AI analysis:
* **Summary** — an overview of the conversation.
* **Sentiment** — positive, neutral, or negative, with the reasoning.
* **Quality score** — a rating with explanation.
* **Fraud detection** — automatic flagging of spam and low-quality responses, with reasoning.
## Insights
The Insights tab analyzes the whole study:
* **Study summary** — an executive overview with key bullets.
* **Per-question insights** — themes, a summary, and sentiment for each question, with response counts.
* **Charts** — auto-generated visualizations for quantitative questions (multiple choice, rating scales, NPS, star ratings, numbers), including bar charts and heatmaps for matrix questions.
* **Custom insights** — define your own AI analysis prompts ("What pricing objections came up?") and get reusable, reorderable insight views.
### Quotes with receipts
Every insight is backed by evidence: quotes link to the exact interview, position in the transcript, and timestamp — with one click to jump to the source.
### Analysis controls
* **Analysis mode** — Basic (faster, cost-effective) or Pro (deeper analysis).
* **Regenerate** — refresh the summary, a single insight, or everything after new responses arrive.
* **Scope** — include or exclude incomplete transcripts and simulated interviews.
## Filtering
Filter both Results and Insights by:
* Question answers (equals, includes, greater/less than) on quantitative types
* Metadata fields (including [hidden fields](/studies/launch-and-sharing#hidden-fields--participant-tracking) from your links)
* Interview status — completed, archived, screened out
* Simulated vs. real interviews
* [Split-test arm](/studies/split-tests) — compare variants in studies with a randomizer
Filters support multiple values and can be saved for reuse.
## Reports
Build cross-study **reports** (documents or presentations) with an AI chat assistant: pull in findings from multiple studies, add custom analysis, and share the result publicly with a revocable link. Reports track whether their source studies have new data since the report was written.
## Exports
* **PDF** — formatted reports with a cover page, executive summary, custom insights, and per-question pages with charts and data tables. Optimized for large studies (1,000+ responses).
* **CSV** — raw response data, sanitized for Excel compatibility. Multi-select multiple choice answers export as one column per option (cell filled when selected, blank when not, plus an *Other* column when free-text entries are enabled) — the same fan-out matrix, ranking, and allocation questions use — so per-option pivots work directly in Excel. An allocation question with **custom options** turned on adds two last columns: *Custom options (total)*, the sum of the values a participant gave to their own options, and *Custom options*, their names and values as text. The two columns are exported only while the setting is on.
### Telling repeated questions apart
Concept tests often repeat the same questions once per stimulus — three concept blocks inside one randomized group, say — so the question text alone can't tell you which concept a column belongs to. The CSV export adds that context to each column header:
* **Group titles** — a question inside a titled group is prefixed with the group's breadcrumb: `3. Concepts › Concept B › How appealing is this?`. Untitled groups add nothing, so name your concept blocks to get labeled columns.
* **Attached media** — a question with [media attached](/studies/question-media) lists the file names after its text: `1. Take a look at this [concept-b.png]`.
* **Order shown** — each randomized group gets an extra ` (order shown)` column recording the order that participant actually met its contents in, pipe-separated so it splits cleanly: `Concept B|Concept C|Concept A`. Blocks the participant never reached are left out. An untitled block is named by the first file attached inside it.
## Staying in the loop
Get notified the moment an interview completes — by [email, Slack, or webhook](/studies/settings#notifications) — so you can review pilot responses right after launch and catch issues early.
# Study settings
Source: https://docs.getversive.com/studies/settings
Every study-level setting, tab by tab
Study settings live in the settings panel on the study page, organized into tabs: **General**, **Sharing**, **AI Interviewer**, **Branding**, **Languages**, and **Notifications**. This page covers everything except the [AI Interviewer](/studies/ai-interviewer) and [Languages](/studies/languages) tabs, which have their own pages.
## General
| Setting | Description |
| - | - |
| Study name | The internal title of your study. |
| Study type | **AI interview** (AI-moderated interview with follow-up questions; 1 AI credit per completion, or 2 in the Voice to voice Realtime conversation mode) or **Survey** (fixed-response questions only; completions count against your survey responses, never AI credits). AI interviews need a plan with AI credits; on the Free plan every study is a survey. To switch to Survey, first remove any conversational questions (AI Question or Exploratory); to switch a survey to an AI interview, your plan needs AI credits. Surveys support the Text only and Text and voice modes. |
| Conversation mode | Text only, Text and voice, Voice only, Voice with preview, Video, or Voice to voice Realtime (a live spoken conversation on the realtime engine, 2 AI credits per completion). See [Conversation modes](/studies/overview#conversation-modes). |
| Silence threshold | Voice to voice Realtime only: how long the AI waits after the participant stops speaking before replying (0.5–5 s, default 1.5 s). |
| Require device | Any device, Desktop only, or Mobile only. |
| Record user screens | Desktop only. Choose **Browser tab** or **Full screen** recording permissions. |
### Advanced settings
| Setting | Description |
| - | - |
| Show voice tooltip | Prompt participants that they can answer by voice (non-voice modes). |
| Allow copy and paste | Off by default — keeping it off deters low-effort or AI-generated text answers. |
| Beta transcription models | Use the newest transcription models first. |
| Customize support email | Replace the default support contact shown to participants. |
| Show estimated completion time | Display the expected length of the study on the welcome screen. |
| Project ID | Read-only study identifier — used with the [API](/api-reference/introduction) and [Embed SDK](/sdk/overview). |
## Sharing & participants
| Setting | Description |
| - | - |
| Project status | **Live** (accepting participants) or **Paused**. |
| Quota | Stop accepting new participants once you have enough completes: a total cap, or a separate cap per link parameter value. See [Quotas](#quotas). |
| Custom pause URL | Where participants land when the study is paused or full. Supports `{param}` placeholders from URL parameters, including a placeholder as the full URL base. The resolved destination must use `http://` or `https://`. |
| When a participant is screened out | Send them to the study's screen-out page, or redirect to your own URL (e.g. panel tracking). [Participant sources](/studies/launch-and-sharing#participant-sources) can override the destination per channel. |
| Unique identifier | The URL parameter name you use to identify participants (e.g. `uid`). Enables per-participant tracking and cross-device resume. Share links as `…/s/{studyId}?uid=12345`. |
## Quotas
A quota stops the study from accepting new participants once you have enough completes. Anyone already mid-interview can still finish. Set it in **Sharing & participants** by choosing one of three modes:
| Mode | What it does |
| - | - |
| No quota | Keep accepting participants until you pause the study. |
| Total completes | Stop after a set number of completed interviews. |
| Per link parameter | A separate cap for each value of a URL parameter, so you can fill groups independently from one study. |
To cap individual answer options instead (for example 50 iPhone users and 50 Android users), use [question quotas](/studies/question-quotas). They work independently of the study quota and can be combined with it.
### Per link parameter
Enter the parameter name your links will carry, such as `group`. Letters, digits, underscores, and hyphens only.
Each row pairs a link value with its number of completes. Every value can be used once, up to 50 values per study.
Append the parameter to the study link:
```
https://getversive.com/s/{studyId}?group=1
https://getversive.com/s/{studyId}?group=2
```
Matching is exact and case-sensitive: a participant who opens `?group=1` counts toward the `1` row, while `?Group=1` or `?group=01` do not. The parameter is stored as response metadata like any other [hidden field](/studies/launch-and-sharing#hidden-fields--participant-tracking), so you can filter results by it.
**Require a matching value** decides what happens to participants whose link has no value from your list, including the plain study link:
* **Off** (default): they are let in. Their completes don't count toward any row.
* **On**: they are turned away and see the same thing as participants arriving at a full study.
Leave it off if you also share the plain study link.
### Closing a quota
A limit of 0 closes the study (Total completes) or that one value (Per link parameter) to new participants. To remove the cap entirely, switch to **No quota**.
### What participants see when a quota is full
Late arrivals are handled the same way as a paused study, in this order:
1. The **quota** redirect of their [participant source](/studies/launch-and-sharing#participant-sources), when the link carries a `source` parameter that has one.
2. Your **custom pause URL**, if set.
3. The built-in paused page ("This study has been paused").
### What counts toward a quota
* Only **completed** interviews count. In-progress and screened-out interviews don't.
* Mock interviews, previews, and AI simulations never count.
* Archived interviews don't count.
Caps are approximate. Versive checks the count when a participant arrives and lets everyone who was admitted finish, so several participants completing at the same moment can push a total slightly past its limit.
### Tracking progress
The study header shows a quota pill: `Quota 42/100` for a total cap, or the parameter name with combined progress (`Group · 38/60`) with a per-value breakdown on hover. It turns amber when any value is full and red when every value is full. The pill covers the study quota only; question quotas show their own counts in the question editor.
## Branding
| Setting | Description |
| - | - |
| Study logo | The logo shown in the header participants see. Upload your own, or remove it to go back to the default. |
| Study title | The title shown next to the logo. Leave blank to use the study name. |
| Primary color | The accent color of the participant experience (default `#00786F`). |
| Hide Versive branding | Removes "Powered by Versive" from the participant experience. Available on eligible plans. |
Branding is per study, so what you set here affects this study only.
To avoid restyling every study by hand, owners and admins can set a default logo and primary color for the whole organization under **Organization > Settings > Study defaults** — see [study branding defaults](/platform/organizations-and-roles#study-branding-defaults). New studies start from those defaults; this tab always wins over them, and changing a default later leaves studies that already exist alone.
## Study messages
Three fixed messages frame every study. Each is fully editable and translated along with your questions:
* **Welcome message** — title, body, and call-to-action button text shown before the study starts.
* **Thank-you message** — title, body, and an optional CTA link shown on completion.
* **Screen-out message** — what disqualified participants see, with an optional CTA link.
## Notifications
Get notified when an interview completes:
* **Email** — send to one or more addresses.
* **Slack** — post to a channel via an incoming webhook URL.
* **Webhooks** — call your own endpoint, for custom workflows.
## Access policy
Each study has an access policy that sets the default level of access for organization members: **Full access**, **Can edit**, **Can view**, or **Invite only**. Combine with per-user [study roles](/platform/folders-and-permissions) for finer control.
# Split tests
Source: https://docs.getversive.com/studies/split-tests
Route participants into weighted study arms and compare variants side by side
Split tests let one study show different participants different content — concept A vs. concept B, two message framings, alternative pricing pages — and compare the results side by side. They're built with **randomizers**: an element in the study builder that routes each participant down one of several weighted **arms**.
## Building a split test
1. In the study builder's add menu, choose **Add randomizer** (alongside *Add question* and *Add group*).
2. Drag the questions or question groups for each variant into its arm.
3. Open **Randomizer settings** to name the randomizer, label the arms, and set their weights. A randomizer has 2–12 arms; weights are percentages and must total 100%.
When a participant reaches the randomizer, they're assigned to one arm at random according to the weights, answer only that arm's questions, and then continue with the rest of the study. Everything outside the randomizer is seen by everyone — so shared screeners and intro questions go before it, and shared closing questions after.
Publishing validates the setup: empty arms, missing labels, or weights that don't add up are flagged in the builder before the study goes live.
## Reading split-test results
Every response records which arm the participant entered:
* **Filter** both Results and Insights by arm to compare variants.
* The grid view and transcripts label each response with its arm.
* **CSV exports** include the routing columns, so you can pivot by arm in your own tools.
## Split tests with the AI study creator
You can also ask the AI study creator for a split test directly — *"Create a concept test where 50% of participants see concept A and 50% see concept B"* — and it builds the randomizer, arms, and variant groups for you. To undo a split test without losing the content, ask it to *remove the randomizer but keep the questions*: every arm's content moves back into the study and all participants see it.
## Split tests via the API and MCP
Randomizers are available programmatically too: the [Randomizers endpoints](/api-reference/randomizers/list-randomizers) list, create, update, and remove them, and the [Versive MCP server](/mcp/tools#randomizers) exposes the same operations as `list_randomizers`, `add_randomizer`, `edit_randomizer`, and `remove_randomizer`.