---
title: "List responses"
method: GET
path: "/api/v1/responses"
tags: ["Responses"]
---

# List responses

`GET /api/v1/responses`

## Request

- Base URL: `https://app.voicepanel.com`
- URL: `https://app.voicepanel.com/api/v1/responses`
- Auth: HTTP bearer

Retrieve responses for a study, transcripts included. Supports filtering by study, distribution, status, date range, and more. Without an `environment` filter, preview responses are left out. Returns one page of `limit` responses (default 50), ordered by creation time (newest first); pass `next_cursor` back as `cursor` to read the next page.

## Query parameters

- `studyId` string
- `startDateTime` string
- `endDateTime` string
- `environment` 'production' | 'preview'
- `hasMessages` 'true' | 'false'
- `status` union
  - 'created' | 'opened' | 'incomplete' | 'completed' | 'in_progress': Where the response is in its lifecycle. `created`: the link was opened but the welcome screen was not passed. `opened`: the respondent passed the welcome screen. `in_progress`: the respondent answered at least one question. `completed`: the interview finished. `incomplete`: the respondent left before the end, or was screened out.
  - string[]
- `distributionId` union
  - string
  - string[]
- `id` union
  - string
  - string[]
- `limit` integer
- `cursor` string

## Response `200`

Successful response

- object
  - `data` Response[], required
    - `id` string, required: Response ID
    - `study_id` string, required: ID of the study
    - `distribution_id` string, nullable, required: ID of the distribution the participant came through. Null for a preview.
    - `segment_id` string, nullable, required: ID of the segment the participant was recruited for
    - `status` 'created' | 'opened' | 'incomplete' | 'completed' | 'in_progress', required: Where the response is in its lifecycle. `created`: the link was opened but the welcome screen was not passed. `opened`: the respondent passed the welcome screen. `in_progress`: the respondent answered at least one question. `completed`: the interview finished. `incomplete`: the respondent left before the end, or was screened out.
    - `status_reason` 'exited_welcome_screen' | 'exited_paused_screen' | 'started_interview' | 'screened_out' | 'interview_error' | 'spam' | 'hit_time_limit' | 'answered_all_questions' | 'content_filter' | 'inactive_timeout' | 'recording_stopped' | 'quota_full', nullable, required: Why the response has its status. `answered_all_questions` and `hit_time_limit` go with `completed`. `exited_welcome_screen`, `exited_paused_screen`, `screened_out`, `quota_full`, `inactive_timeout`, `recording_stopped`, `interview_error`, `content_filter` and `spam` go with `incomplete`. `started_interview` goes with `in_progress`.
    - `mode` 'preview' | 'production' | 'simulation', required: The environment the response was collected in. `production` responses come from real participants. `preview` responses come from the dashboard preview. `simulation` responses come from AI simulated participants. Previews and simulations do not count toward quotas, and only `production` responses fire webhooks.
    - `format` 'video' | 'audio' | 'chat' | 'audio_only' | 'chat_only', required: How the respondent answered the open-ended questions. `video` records the camera. `audio` and `audio_only` record the voice. `chat` and `chat_only` are typed. An `_only` value means the study offered no other input.
    - `language` string, required: ISO 639-1 code of the language the participant took the interview in
    - `custom_id` string, nullable, required: Your own participant ID, read from the `cid` query parameter of the study link
    - `email` string, nullable, required: Participant email, when collected
    - `query_params` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `messages` ResponseMessage[], nullable, required: The transcript, in order. Null until the participant answers the first question. Left out of webhook events.
      - `role` 'moderator' | 'respondent', required: Who spoke: the AI moderator or the respondent.
      - `content` union, required: What a message says. `type` tells which shape `value` has. A `moderator` message always holds a `question`. A `respondent` message holds one of the answer shapes.
        - object: What the AI moderator said. Only on a `moderator` message.
          - `type` 'question', required: The content of every `moderator` message.
          - `value` string, required: The question or follow-up probe the AI moderator asked, as the respondent saw or heard it.
        - object: A spoken answer to an open-ended step.
          - `type` 'spoken', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The transcript of what the respondent said. Empty when no transcript was produced.
        - object: A typed answer to an open-ended step.
          - `type` 'open-text', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The text the respondent typed.
        - object: A single-select step.
          - `type` 'single_select', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The selected choice.
        - object: A multi-select step.
          - `type` 'multi_select', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string[], required: The selected choices.
        - object: A rating-scale step.
          - `type` 'rating_scale', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The selected rating, as a string.
        - object: A ranking step.
          - `type` 'ranking', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string[], required: The choices in the respondent's order, first to last.
        - object: A matrix step with one selection per row.
          - `type` 'matrix_single_select', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` object, required: The selected column, keyed by row text.
        - object: A matrix step with several selections per row.
          - `type` 'matrix_multi_select', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` object, required: The selected columns, keyed by row text.
        - object: A task step.
          - `type` 'task', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `completed` boolean, required: Whether the respondent completed the task.
          - `value` string, required: What the respondent said aloud while on the task. Empty when they said nothing.
        - object: A spoken answer whose audio went to the moderator without a transcript.
          - `type` 'spoken_raw_audio', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The transcript. Empty when no transcript was produced.
        - object: An answer the AI moderator found inside the respondent's answer to a different question.
          - `type` 'detected', required: The kind of answer. It matches the step type for a closed-choice step, and names the input method for an open-ended step.
          - `value` string, required: The part of the earlier answer that answers this question.
          - `referenceIndexes` integer[], required: Indexes into `messages` of the answers the moderator read this from.
      - `sectionNumber` integer: 1-based position of the section in the plan, as authored.
      - `stepNumber` integer: 1-based position of the step inside its section.
      - `probeNumber` integer: 1 for the scripted question and its answer. 2 and up for each follow-up probe the AI moderator asked on the same step.
      - `secondsElapsed` number: Seconds from the start of the interview to the end of this message.
      - `sectionId` string: ID of the section run the message belongs to. It is the `sectionNumber`, plus a letter when the section loops over a group of stimuli: `2` for section 2, `2b` for the run that shows the second stimulus of the group, in the authored order. It does not change when sections or stimuli are randomized.
    - `translated_messages` object[], nullable, required: `messages` translated into English, one entry per message at the same index. Null when the interview was in English.
      - `role` 'moderator' | 'respondent', required: Who spoke: the AI moderator or the respondent.
      - `content` object, required
        - `type` 'text', required: The content of every translated message.
        - `value` string, required: The message translated into English. Always free text, whatever the type of the answer. A selection, a ranking or a matrix answer comes back in whatever wording the translation chose, such as `Red, Blue`, so read the typed answer from `messages` at the same index.
    - `screener_responses` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `translated_screener_responses` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `summary` string, nullable, required: AI-generated summary of the response, when one was made
    - `seconds_elapsed` number, required: Seconds the participant spent in the interview
    - `quality_score` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `moderator_quality_score` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `segments` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `include_in_analysis` boolean, nullable, required: Whether the response counts in analysis. A completed response is included unless a reviewer rejects it.
    - `has_messages` boolean, nullable, required: True when the participant answered at least one question
    - `has_evaluated_screen_out` boolean, required: Whether the screen-out criteria were evaluated
    - `additional_info` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `device_info` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `call_id` string, nullable, required: ID of the phone call, for phone interviews
    - `call_provider` 'vapi' | 'retell', nullable, required: Provider of the phone call
    - `feedback` union, required
      - string
      - number
      - boolean
      - Json[]
      - object
    - `message_media_expected` integer, nullable, required: Per-answer recordings the plan asks for
    - `message_media_completed` integer, nullable, required: Per-answer recordings that were uploaded
    - `section_media_expected` integer, nullable, required: Section recordings (screen, camera) the plan asks for
    - `section_media_completed` integer, nullable, required: Section recordings that were uploaded
    - `panel_incentive_amount` number, nullable, required: Incentive the participant was recruited at, in whole USD. Panel distributions only.
    - `panel_recruiting_fee` number, nullable, required: Recruiting fee at recruitment, in whole USD. Panel distributions only.
    - `seq_num` integer, nullable, required: The response number shown in the dashboard. It counts up from 1 within the study.
    - `opened_at` string, date-time, nullable, required: When the participant passed the welcome screen
    - `first_message_at` string, date-time, nullable, required: When the participant answered the first question
    - `last_message_at` string, date-time, nullable, required: When the transcript last changed
    - `created_at` string, date-time, nullable, required: When the link was opened
    - `updated_at` string, date-time, nullable, required: When the response last changed
  - `has_more` boolean, required: True when rows exist after the last one in data
  - `next_cursor` string, nullable, required: Pass back as `cursor` to read the next page

## Other responses

- `400`: Bad request. `code` is `validation_error` when a field is invalid or a query parameter is unknown, with the field paths in `details`, or `bad_request` otherwise.
- `401`: Unauthorized. The token is missing, invalid, or has no user.
- `403`: Forbidden. The token has no access to this resource.
- `404`: Not found. The resource does not exist or belongs to another account.
- `429`: Too many requests. The account used its API rate limit. `code` is `too_many_requests`. Wait for the number of seconds in `Retry-After`, then retry.
- `500`: Internal error. Quote `request_id` when you contact support.

---

[API](https://skmtc.dev/voicepanel/apis/voicepanel-api.md) - [All operations](https://skmtc.dev/voicepanel/apis/voicepanel-api/llms.txt) - [OpenAPI document](https://skmtc.dev/voicepanel/apis/voicepanel-api/revisions/ee41535c5694?raw)
