---
title: "Create a distribution"
method: POST
path: "/api/v1/distributions"
tags: ["Distributions"]
---

# Create a distribution

`POST /api/v1/distributions`

## Request

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

Create a new distribution for a study. A distribution defines how participants access the study — via a shareable link, a panel provider, embedded widget, or other method.

## Request body

- DistributionCreateBody
  - `study_id` string, required: ID of the study this distribution belongs to
  - `name` string, nullable: Name of the distribution
  - `type` 'link' | 'service' | 'email' | 'website' | 'app' | 'panel' | 'simulation': How the study is distributed to participants
  - `distribution_provider` 'respondent' | 'user_interviews' | 'prolific' | 'terac', nullable: Third-party panel provider
  - `config` object: Provider-specific configuration
  - `incentive` object, nullable: Incentive configuration for link distributions
  - `quota_limit` number, nullable: Maximum number of responses
  - `quota_frequency` 'lifetime' | 'monthly' | 'weekly' | 'daily': How often the quota resets
  - `segment_quotas` union
    - string
    - number
    - boolean
    - Json[]
    - object
  - `screener_questions` Json[]: Screener questions for qualifying participants
    - union
      - string
      - number
      - boolean
      - Json[]
      - object
  - `targeting_condition` union
    - string
    - number
    - boolean
    - Json[]
    - object
  - `default_response_language` string, nullable: Default language for responses
  - `collect_email` boolean: Whether to collect participant email
  - `screen_email` boolean: Whether to screen participants against an email list
  - `email_list_id` string, nullable: Email list used to screen or invite participants
  - `automatic_invites` boolean: Whether participants are invited automatically
  - `key` string, nullable: Snippet key used to trigger an intercept distribution
  - `traffic_threshold` number, nullable: Share of eligible traffic shown the study, out of 1,000,000
  - `complete_redirect_url` string, nullable: URL to redirect to after completion
  - `screen_out_redirect_url` string, nullable: URL to redirect screened-out participants
  - `quota_full_redirect_url` string, nullable: URL to redirect when quota is full
  - `quality_terminate_redirect_url` string, nullable: URL to redirect participants terminated for quality
  - `description` string, nullable: Description of the distribution
  - `is_archived` boolean: Whether the distribution is archived. Archiving hides it in the dashboard and does not change its status.

## Response `201`

Created

- Distribution: A distribution of a study to participants
  - `id` string, required: Distribution ID
  - `url` string, nullable, required: Public link participants open to take the study. Set for link distributions only; null for every other type.
  - `study_id` string, required: ID of the study this distribution belongs to
  - `name` string, nullable, required: Name of the distribution
  - `description` string, nullable, required: Description of the distribution
  - `type` 'link' | 'service' | 'email' | 'website' | 'app' | 'panel' | 'simulation', required: How the study is distributed to participants
  - `status` 'draft' | 'published' | 'paused' | 'completed' | 'in_review', required: Current status of the distribution
  - `distribution_provider` 'respondent' | 'user_interviews' | 'prolific' | 'terac', nullable, required: Third-party panel provider
  - `distribution_provider_id` string, nullable, required: External provider project ID
  - `config` object, required: Provider-specific configuration
  - `incentive` object, nullable, required: Incentive configuration for link distributions
  - `quota_limit` number, nullable, required: Maximum number of responses
  - `quota_frequency` 'lifetime' | 'monthly' | 'weekly' | 'daily', required: How often the quota resets
  - `quota_usage` integer, required: Responses counted against the current quota
  - `segment_quotas` union, required
    - string
    - number
    - boolean
    - Json[]
    - object
  - `screener_questions` Json[], required: Screener questions for qualifying participants
    - union
      - string
      - number
      - boolean
      - Json[]
      - object
  - `targeting_condition` union, required
    - string
    - number
    - boolean
    - Json[]
    - object
  - `device_targeting` union, required
    - string
    - number
    - boolean
    - Json[]
    - object
  - `default_response_language` string, nullable, required: Default language for responses
  - `collect_email` boolean, required: Whether to collect participant email
  - `screen_email` boolean, required: Whether to screen participants against an email list
  - `email_list_id` string, nullable, required: Email list used to screen or invite participants
  - `automatic_invites` boolean, required: Whether participants are invited automatically
  - `key` string, nullable, required: Snippet key used to trigger an intercept distribution
  - `traffic_threshold` number, nullable, required: Share of eligible traffic shown the study, out of 1,000,000
  - `complete_redirect_url` string, nullable, required: URL to redirect to after completion
  - `screen_out_redirect_url` string, nullable, required: URL to redirect screened-out participants
  - `quota_full_redirect_url` string, nullable, required: URL to redirect when quota is full
  - `quality_terminate_redirect_url` string, nullable, required: URL to redirect participants terminated for quality
  - `study_data` union, required
    - string
    - number
    - boolean
    - Json[]
    - object
  - `is_archived` boolean, required: Whether the distribution is archived
  - `seq_num` integer, nullable, required: Sequence number within the study
  - `published_at` string, date-time, nullable, required: When the distribution was published
  - `last_completed_at` string, date-time, nullable, required: When the latest response completed
  - `created_by` string, nullable, required: ID of the user who created the distribution
  - `created_at` string, date-time, nullable, required
  - `updated_at` string, date-time, nullable, required
  - `pretranslations` object[]: Locales with a stored translation of the distribution. Not returned by publish.
    - `locale` string, required

## 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.
- `409`: Conflict. The write disagrees with the current state of the resource.
- `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.
- `503`: Service unavailable. A dependency did not answer and nothing was saved. Retry later.

---

[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)
