> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.prolific.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.prolific.com/_mcp/server.

# Create a Batch

POST https://api.prolific.com/api/v1/data-collection/batches
Content-Type: application/json

Create a new Task Builder batch. The dataset does not need to be in READY status at creation time.

### Configurable task layouts via `batch_items`

You can configure a custom task layout using `batch_items` which also stores instructions and content as part of batch creation. It replaces the deprecated `POST /api/v1/data-collection/batches/{batch_id}/instructions` endpoint, which will reject requests on batches that were created with `batch_items`.

`batch_items` is a nested layout describing what is shown to participants:

* `batch_items` is an ordered array of **pages**. Each page is shown to participants as a single screen.
* Each page has an ordered array of **rows**.
* Each row has 1 or 2 **columns** rendered side-by-side.
* Each column has one or more **items** — a dataset field reference, a content block (`image`, `rich_text`), or an instruction (`free_text`, `free_text_with_unit`, `multiple_choice`, `multiple_choice_with_free_text`, `file_upload`, `video_narration`).

Items are a discriminated union on `type`. Each `dataset_field` item references a field in the attached dataset by name — only fields with type `text`, `image_url`, `audio_url`, or `video_url` are permitted, and the same field may not be referenced more than once on the same page.

On a successful response, every item in `batch_items` is returned with a server-assigned `id`.

If `batch_items` fails server-side validation (for example: a `dataset_field` item used when no v4 dataset with a populated schema is attached, an unknown `dataset_field`, the same `dataset_field` referenced more than once on a page, an `answer_limit` larger than the number of options, or a `default_unit` that does not match the supplied `unit_options`), the request fails with **`422 Unprocessable Entity`** and an `INVALID_BATCH_ITEMS` payload containing per-item `page` / `row` / `column` / `item` locations. See the `BatchItemsValidationError` schema for the full shape.

Reference: https://docs.prolific.com/api-reference/task-builder/create-task-builder-batch

## Authentication

- `Authorization` header (required) (prefixed with ` Token  `) — The Prolific API uses API token to authenticate requests. You can create an API token directly from your settings. Your API token does not have an expiry date and carries full permission, so be sure to keep them secure. If your token is leaked, delete it and create a new one directly in the app. In your requests add `Authorization` header with the value `Token <your token>`.

## Request

### Body (application/json)

This endpoint expects an object.

- `name` (string, required) — The name of the batch
- `workspace_id` (string, required) — The ID of the Prolific workspace
- `task_details` (ApiV1DataCollectionBatchesPostRequestBodyContentApplicationJsonSchemaTaskDetails, required) — Task metadata displayed to participants
- `dataset_id` (string, optional) — The ID of the dataset to attach (optional at creation time)
- `batch_items` (list of BatchItemsPage, optional, nullable) — Inline pages of instructions and content shown to participants. Each entry is a page containing rows of columns of items (dataset field references, content blocks, or instructions). When supplied, this is the recommended way to author instructions — the legacy `POST /batches/{batch_id}/instructions` endpoint is rejected for batches created with `batch_items`.

## Response

### 201

Created

- `id` (string, required)
- `created_at` (datetime, required) — An ISO-8601 formatted string representing the batch creation time, in UTC.
- `created_by` (string, required) — User ID of the Prolific user that created the resource.
- `datasets` (list of TaskBuilderBatchCreateDatasetsItems, required)
- `name` (string, required)
- `status` (enum, required)
  - Allowed values: `UNINITIALISED`, `PROCESSING`, `READY`, `ERROR`
- `total_task_count` (integer, required)
- `total_instruction_count` (integer, required)
- `workspace_id` (string, required)
- `task_details` (TaskBuilderBatchCreateTaskDetails, required)
- `batch_items` (list of BatchItemsPage, optional, nullable) — The persisted `batch_items` layout, returned only when `batch_items` was supplied on create. Every page, row, column, and item is returned with a server-assigned `id`.

## Errors

### 422 Unprocessable Entity Error

Unprocessable Entity — `batch_items` failed validation

- `type` (enum, required)
  - Allowed values: `INVALID_BATCH_ITEMS`
- `message` (string, required)
- `issues` (list of BatchItemsValidationErrorIssuesItems, required)

### 400 Client Request Error

Error

- `error` (ErrorDetail, required)

## Types

### ApiV1DataCollectionBatchesPostRequestBodyContentApplicationJsonSchemaTaskDetails

Task metadata displayed to participants

- `task_name` (string, required) — The title displayed to participants
- `task_introduction` (string, required) — HTML formatted introduction shown at the start of the task
- `task_steps` (string, required) — HTML formatted step-by-step instructions

### BatchItemsPage

A single page of a batch's inline layout. Each page is rendered as one screen to participants and contains an ordered list of rows. On responses, includes a server-assigned `id`; omit `id` on create to add a new page.

- `rows` (list of BatchItemsRow, required)
- `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing page when updating.
- `display_position` (enum, optional) — Renders the page once — before ("intro") or after ("outro") the repeating body — instead of once per datapoint. Omit (or set "body") for the default repeating behaviour. Pages with display_position "intro" or "outro" may only contain rich_text/image content blocks, not instructions or dataset_field refs.
  - Allowed values: `intro`, `outro`, `body`

### TaskBuilderBatchCreateDatasetsItems

- `id` (string, required)
- `total_datapoint_count` (integer, required)

### TaskBuilderBatchCreateTaskDetails

- `task_name` (string, required)
- `task_introduction` (string, required) — HTML formatted task introduction
- `task_steps` (string, required) — HTML formatted task steps

### BatchItemsValidationErrorIssuesItems

- `page` (integer, required) — Zero-based index of the page containing the invalid item.
- `row` (integer, required) — Zero-based index of the row within the page.
- `column` (integer, required) — Zero-based index of the column within the row.
- `item` (integer, required) — Zero-based index of the item within the column.
- `type` (string, required) — The item `type` that failed validation (e.g. `dataset_field`, `multiple_choice`, `file_upload`).
- `message` (string, required) — Human-readable validation error message.
- `field` (string, optional) — Dataset field name. Present only for `dataset_field` validation issues.

### ErrorDetail

- `status` (integer, required) — Status code as in the http standards
- `error_code` (integer, required) — Internal error code
- `title` (string, required) — Error title
- `detail` (ErrorDetailDetail, required) — Error detail
- `additional_information` (string, optional) — Optional extra information
- `traceback` (string, optional) — Optional debug information
- `interactive` (boolean, optional)

### BatchItemsRow

A row within a page. Renders 1 or 2 columns side-by-side.

- `columns` (list of BatchItemsColumn, required)
- `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing row when updating.

### ErrorDetailDetail

Error detail

- string
- list of string
- ErrorDetailDetail2

### BatchItemsColumn

A column within a row. Contains one or more items rendered top-to-bottom.

- `items` (list of BatchItemsItem, required)
- `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing column when updating.

### ErrorDetailDetail2

All fields with validation errors

- `any_field` (list of string, optional) — Name of the field with a validation error and as a value an array with the error descriptions

### BatchItemsItem

A single item within a column. One of: a dataset field reference (`dataset_field`), a content block (`image`, `rich_text`), or an instruction (`free_text`, `free_text_with_unit`, `multiple_choice`, `multiple_choice_with_free_text`, `file_upload`, `video_narration`). Discriminated on `type`.

- `type`: `dataset_field` (dataset_field)
  - `field` (string, required) — Name of the dataset schema field to reference.
- `type`: `image` (image)
  - `alt_text` (string, required) — Alt text shown to screen readers. Required for accessibility.
  - `url` (string, required) — HTTPS URL of the image. Non-HTTPS URLs are rejected.
  - `caption` (string, optional) — Optional caption displayed below the image.
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
- `type`: `rich_text` (rich_text)
  - `content` (string, required) — Rich text content. Interpreted as HTML by default, or as Markdown when `content_format` is set to `markdown` (converted to HTML server-side before storage).
  - `content_format` (enum, optional, default: html) — Format of the `content` field. Defaults to `html`.
    - Allowed values: `html`, `markdown`
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
- `type`: `free_text` (free_text)
  - `description` (string, required) — The question or prompt displayed to participants.
  - `helper_text` (string, optional) — Additional guidance text displayed below the question.
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `placeholder_text_input` (string, optional) — Placeholder text displayed in the input field.
  - `validation` (ValidationRule, optional) — Optional validation constraints for the input value.
- `type`: `free_text_with_unit` (free_text_with_unit)
  - `description` (string, required) — The question or prompt displayed to participants.
  - `unit_options` (list of BatchItemsFreeTextWithUnitInstructionUnitOptionsItems, required) — Available units the participant can select from.
  - `unit_position` (enum, required) — Position of the unit selector relative to the text input.
    - Allowed values: `prefix`, `suffix`
  - `default_unit` (string, optional) — Default selected unit. Must match the `value` of one of the entries in `unit_options`.
  - `helper_text` (string, optional)
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `placeholder_text_input` (string, optional)
- `type`: `multiple_choice` (multiple_choice)
  - `answer_limit` (integer, required) — Number of options that can be selected. Use `1` for single-select, `-1` for unlimited, or any number up to the total options.
  - `description` (string, required) — The question or prompt displayed to participants.
  - `options` (list of BatchItemsMultipleChoiceInstructionOptionsItems, required)
  - `disable_dropdown` (boolean, optional, default: false) — When true, always renders checkbox/radio elements instead of a dropdown select.
  - `helper_text` (string, optional)
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `placeholder_text_input` (string, optional)
- `type`: `multiple_choice_with_free_text` (multiple_choice_with_free_text)
  - `answer_limit` (integer, required)
  - `description` (string, required)
  - `options` (list of BatchItemsMultipleChoiceWithFreeTextInstructionOptionsItems, required)
  - `disable_dropdown` (boolean, optional, default: false)
  - `helper_text` (string, optional)
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `placeholder_text_input` (string, optional)
- `type`: `file_upload` (file_upload)
  - `description` (string, required)
  - `accepted_file_types` (list of string, optional) — File extensions to accept (each must start with a dot, e.g. `.jpg`). Defaults to `[".jpg", ".jpeg", ".png", ".heic", ".heif"]`.
  - `helper_text` (string, optional)
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `max_file_count` (integer, optional) — Maximum number of files allowed. Defaults to 10. Must be greater than or equal to `min_file_count`.
  - `max_file_size_mb` (double, optional) — Maximum size in megabytes per file. Defaults to 25.
  - `min_file_count` (integer, optional) — Minimum number of files required. Defaults to 1.
- `type`: `video_narration` (video_narration)
  - `description` (string, required) — The prompt displayed to the participant.
  - `helper_text` (string, optional) — Additional guidance displayed below the prompt.
  - `id` (string, optional) — Server-assigned identifier; present on responses. Include to preserve an existing item when updating.
  - `max_file_size_mb` (double, optional, default: 50) — Maximum size in megabytes of each recorded narration file. Defaults to 50.
  - `narration_mode` (enum, optional, default: continuous) — Use `continuous` for one narration spanning the video, or `segmented` to allow one or more narrations for video time ranges.
    - Allowed values: `continuous`, `segmented`
  - `optional` (boolean, optional, default: false) — When true, the participant may skip this instruction. Instructions are required by default.

### ValidationRule

Optional validation constraints for input values

- `type` (enum, required) — The expected input type. When "number", the input must be numeric and min/max constrain the numeric value. When "string", the input is treated as text and min/max constrain the character count.
  - Allowed values: `number`, `string`
- `min` (double, optional, nullable) — Minimum value (for type "number") or minimum character count (for type "string"). Null means unbounded. When type is "string", must be a non-negative integer. If both min and max are provided, min must be less than or equal to max.
- `max` (double, optional, nullable) — Maximum value (for type "number") or maximum character count (for type "string"). Null means unbounded. When type is "string", must be a non-negative integer. If both min and max are provided, max must be greater than or equal to min.

### BatchItemsFreeTextWithUnitInstructionUnitOptionsItems

- `label` (string, required)
- `value` (BatchItemsFreeTextWithUnitInstructionUnitOptionsItemsValue, required)
- `validation` (ValidationRule, optional) — Optional validation constraints for input values

### BatchItemsMultipleChoiceInstructionOptionsItems

- `label` (string, required)
- `value` (BatchItemsMultipleChoiceInstructionOptionsItemsValue, required)
- `exclusive` (boolean, optional) — When true, selecting this option deselects all other options. Useful for "None of the above" style options. Not allowed when `answer_limit` is 1, and at least one non-exclusive option must remain if any option is exclusive.

### BatchItemsMultipleChoiceWithFreeTextInstructionOptionsItems

- `label` (string, required)
- `value` (BatchItemsMultipleChoiceWithFreeTextInstructionOptionsItemsValue, required)
- `heading` (string, required) — Required. Section heading that groups this option.
- `exclusive` (boolean, optional) — When true, selecting this option deselects all other options.

### BatchItemsFreeTextWithUnitInstructionUnitOptionsItemsValue

- string
- double
- boolean

### BatchItemsMultipleChoiceInstructionOptionsItemsValue

- string
- double
- boolean

### BatchItemsMultipleChoiceWithFreeTextInstructionOptionsItemsValue

- string
- double
- boolean

## Examples

### Batch Create Example

**Request**

```json
{
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": {
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  },
  "dataset_id": "1234acb09999db4b99bcded1"
}
```

**SDK Code**

```python Batch Create Example
import requests

url = "https://api.prolific.com/api/v1/data-collection/batches"

payload = {
    "name": "Sentiment Analysis Batch",
    "workspace_id": "6278acb09062db3b35bcbeb0",
    "task_details": {
        "task_name": "Evaluate Product Reviews",
        "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
        "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
    },
    "dataset_id": "1234acb09999db4b99bcded1"
}
headers = {
    "Authorization": "Token <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Batch Create Example
const url = 'https://api.prolific.com/api/v1/data-collection/batches';
const options = {
  method: 'POST',
  headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
  body: '{"name":"Sentiment Analysis Batch","workspace_id":"6278acb09062db3b35bcbeb0","task_details":{"task_name":"Evaluate Product Reviews","task_introduction":"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>","task_steps":"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"},"dataset_id":"1234acb09999db4b99bcded1"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Batch Create Example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.prolific.com/api/v1/data-collection/batches"

	payload := strings.NewReader("{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Token <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Batch Create Example
require 'uri'
require 'net/http'

url = URI("https://api.prolific.com/api/v1/data-collection/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Token <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\"\n}"

response = http.request(request)
puts response.read_body
```

```java Batch Create Example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/data-collection/batches")
  .header("Authorization", "Token <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\"\n}")
  .asString();
```

```php Batch Create Example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.prolific.com/api/v1/data-collection/batches', [
  'body' => '{
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": {
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  },
  "dataset_id": "1234acb09999db4b99bcded1"
}',
  'headers' => [
    'Authorization' => 'Token <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Batch Create Example
using RestSharp;

var client = new RestClient("https://api.prolific.com/api/v1/data-collection/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Token <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Batch Create Example
import Foundation

let headers = [
  "Authorization": "Token <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": [
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  ],
  "dataset_id": "1234acb09999db4b99bcded1"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/data-collection/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Batch Create With batch_items Example

**Request**

```json
{
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": {
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  },
  "dataset_id": "1234acb09999db4b99bcded1",
  "batch_items": [
    {
      "rows": [
        {
          "columns": [
            {
              "items": [
                {
                  "type": "rich_text",
                  "content": "<p>Read the review below and pick the sentiment that best matches.</p>"
                },
                {
                  "type": "dataset_field",
                  "field": "review_text"
                },
                {
                  "type": "multiple_choice",
                  "answer_limit": 1,
                  "description": "What sentiment does this review express?",
                  "options": [
                    {
                      "label": "Positive",
                      "value": "positive"
                    },
                    {
                      "label": "Neutral",
                      "value": "neutral"
                    },
                    {
                      "label": "Negative",
                      "value": "negative"
                    }
                  ]
                },
                {
                  "type": "free_text",
                  "description": "Briefly explain your choice."
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

**SDK Code**

```python Batch Create With batch_items Example
import requests

url = "https://api.prolific.com/api/v1/data-collection/batches"

payload = {
    "name": "Sentiment Analysis Batch",
    "workspace_id": "6278acb09062db3b35bcbeb0",
    "task_details": {
        "task_name": "Evaluate Product Reviews",
        "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
        "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
    },
    "dataset_id": "1234acb09999db4b99bcded1",
    "batch_items": [{ "rows": [{ "columns": [{ "items": [
                                {
                                    "type": "rich_text",
                                    "content": "<p>Read the review below and pick the sentiment that best matches.</p>"
                                },
                                {
                                    "type": "dataset_field",
                                    "field": "review_text"
                                },
                                {
                                    "type": "multiple_choice",
                                    "answer_limit": 1,
                                    "description": "What sentiment does this review express?",
                                    "options": [
                                        {
                                            "label": "Positive",
                                            "value": "positive"
                                        },
                                        {
                                            "label": "Neutral",
                                            "value": "neutral"
                                        },
                                        {
                                            "label": "Negative",
                                            "value": "negative"
                                        }
                                    ]
                                },
                                {
                                    "type": "free_text",
                                    "description": "Briefly explain your choice."
                                }
                            ] }] }] }]
}
headers = {
    "Authorization": "Token <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Batch Create With batch_items Example
const url = 'https://api.prolific.com/api/v1/data-collection/batches';
const options = {
  method: 'POST',
  headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
  body: '{"name":"Sentiment Analysis Batch","workspace_id":"6278acb09062db3b35bcbeb0","task_details":{"task_name":"Evaluate Product Reviews","task_introduction":"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>","task_steps":"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"},"dataset_id":"1234acb09999db4b99bcded1","batch_items":[{"rows":[{"columns":[{"items":[{"type":"rich_text","content":"<p>Read the review below and pick the sentiment that best matches.</p>"},{"type":"dataset_field","field":"review_text"},{"type":"multiple_choice","answer_limit":1,"description":"What sentiment does this review express?","options":[{"label":"Positive","value":"positive"},{"label":"Neutral","value":"neutral"},{"label":"Negative","value":"negative"}]},{"type":"free_text","description":"Briefly explain your choice."}]}]}]}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Batch Create With batch_items Example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.prolific.com/api/v1/data-collection/batches"

	payload := strings.NewReader("{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\",\n  \"batch_items\": [\n    {\n      \"rows\": [\n        {\n          \"columns\": [\n            {\n              \"items\": [\n                {\n                  \"type\": \"rich_text\",\n                  \"content\": \"<p>Read the review below and pick the sentiment that best matches.</p>\"\n                },\n                {\n                  \"type\": \"dataset_field\",\n                  \"field\": \"review_text\"\n                },\n                {\n                  \"type\": \"multiple_choice\",\n                  \"answer_limit\": 1,\n                  \"description\": \"What sentiment does this review express?\",\n                  \"options\": [\n                    {\n                      \"label\": \"Positive\",\n                      \"value\": \"positive\"\n                    },\n                    {\n                      \"label\": \"Neutral\",\n                      \"value\": \"neutral\"\n                    },\n                    {\n                      \"label\": \"Negative\",\n                      \"value\": \"negative\"\n                    }\n                  ]\n                },\n                {\n                  \"type\": \"free_text\",\n                  \"description\": \"Briefly explain your choice.\"\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Token <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Batch Create With batch_items Example
require 'uri'
require 'net/http'

url = URI("https://api.prolific.com/api/v1/data-collection/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Token <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\",\n  \"batch_items\": [\n    {\n      \"rows\": [\n        {\n          \"columns\": [\n            {\n              \"items\": [\n                {\n                  \"type\": \"rich_text\",\n                  \"content\": \"<p>Read the review below and pick the sentiment that best matches.</p>\"\n                },\n                {\n                  \"type\": \"dataset_field\",\n                  \"field\": \"review_text\"\n                },\n                {\n                  \"type\": \"multiple_choice\",\n                  \"answer_limit\": 1,\n                  \"description\": \"What sentiment does this review express?\",\n                  \"options\": [\n                    {\n                      \"label\": \"Positive\",\n                      \"value\": \"positive\"\n                    },\n                    {\n                      \"label\": \"Neutral\",\n                      \"value\": \"neutral\"\n                    },\n                    {\n                      \"label\": \"Negative\",\n                      \"value\": \"negative\"\n                    }\n                  ]\n                },\n                {\n                  \"type\": \"free_text\",\n                  \"description\": \"Briefly explain your choice.\"\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Batch Create With batch_items Example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/data-collection/batches")
  .header("Authorization", "Token <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\",\n  \"batch_items\": [\n    {\n      \"rows\": [\n        {\n          \"columns\": [\n            {\n              \"items\": [\n                {\n                  \"type\": \"rich_text\",\n                  \"content\": \"<p>Read the review below and pick the sentiment that best matches.</p>\"\n                },\n                {\n                  \"type\": \"dataset_field\",\n                  \"field\": \"review_text\"\n                },\n                {\n                  \"type\": \"multiple_choice\",\n                  \"answer_limit\": 1,\n                  \"description\": \"What sentiment does this review express?\",\n                  \"options\": [\n                    {\n                      \"label\": \"Positive\",\n                      \"value\": \"positive\"\n                    },\n                    {\n                      \"label\": \"Neutral\",\n                      \"value\": \"neutral\"\n                    },\n                    {\n                      \"label\": \"Negative\",\n                      \"value\": \"negative\"\n                    }\n                  ]\n                },\n                {\n                  \"type\": \"free_text\",\n                  \"description\": \"Briefly explain your choice.\"\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}")
  .asString();
```

```php Batch Create With batch_items Example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.prolific.com/api/v1/data-collection/batches', [
  'body' => '{
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": {
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  },
  "dataset_id": "1234acb09999db4b99bcded1",
  "batch_items": [
    {
      "rows": [
        {
          "columns": [
            {
              "items": [
                {
                  "type": "rich_text",
                  "content": "<p>Read the review below and pick the sentiment that best matches.</p>"
                },
                {
                  "type": "dataset_field",
                  "field": "review_text"
                },
                {
                  "type": "multiple_choice",
                  "answer_limit": 1,
                  "description": "What sentiment does this review express?",
                  "options": [
                    {
                      "label": "Positive",
                      "value": "positive"
                    },
                    {
                      "label": "Neutral",
                      "value": "neutral"
                    },
                    {
                      "label": "Negative",
                      "value": "negative"
                    }
                  ]
                },
                {
                  "type": "free_text",
                  "description": "Briefly explain your choice."
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Token <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Batch Create With batch_items Example
using RestSharp;

var client = new RestClient("https://api.prolific.com/api/v1/data-collection/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Token <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Sentiment Analysis Batch\",\n  \"workspace_id\": \"6278acb09062db3b35bcbeb0\",\n  \"task_details\": {\n    \"task_name\": \"Evaluate Product Reviews\",\n    \"task_introduction\": \"<p>In this task, you will analyze product reviews and categorize their sentiment.</p>\",\n    \"task_steps\": \"<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>\"\n  },\n  \"dataset_id\": \"1234acb09999db4b99bcded1\",\n  \"batch_items\": [\n    {\n      \"rows\": [\n        {\n          \"columns\": [\n            {\n              \"items\": [\n                {\n                  \"type\": \"rich_text\",\n                  \"content\": \"<p>Read the review below and pick the sentiment that best matches.</p>\"\n                },\n                {\n                  \"type\": \"dataset_field\",\n                  \"field\": \"review_text\"\n                },\n                {\n                  \"type\": \"multiple_choice\",\n                  \"answer_limit\": 1,\n                  \"description\": \"What sentiment does this review express?\",\n                  \"options\": [\n                    {\n                      \"label\": \"Positive\",\n                      \"value\": \"positive\"\n                    },\n                    {\n                      \"label\": \"Neutral\",\n                      \"value\": \"neutral\"\n                    },\n                    {\n                      \"label\": \"Negative\",\n                      \"value\": \"negative\"\n                    }\n                  ]\n                },\n                {\n                  \"type\": \"free_text\",\n                  \"description\": \"Briefly explain your choice.\"\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Batch Create With batch_items Example
import Foundation

let headers = [
  "Authorization": "Token <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Sentiment Analysis Batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "task_details": [
    "task_name": "Evaluate Product Reviews",
    "task_introduction": "<p>In this task, you will analyze product reviews and categorize their sentiment.</p>",
    "task_steps": "<ol><li>Read each review carefully</li><li>Select the appropriate sentiment</li><li>Provide a brief explanation</li></ol>"
  ],
  "dataset_id": "1234acb09999db4b99bcded1",
  "batch_items": [["rows": [["columns": [["items": [
                [
                  "type": "rich_text",
                  "content": "<p>Read the review below and pick the sentiment that best matches.</p>"
                ],
                [
                  "type": "dataset_field",
                  "field": "review_text"
                ],
                [
                  "type": "multiple_choice",
                  "answer_limit": 1,
                  "description": "What sentiment does this review express?",
                  "options": [
                    [
                      "label": "Positive",
                      "value": "positive"
                    ],
                    [
                      "label": "Neutral",
                      "value": "neutral"
                    ],
                    [
                      "label": "Negative",
                      "value": "negative"
                    ]
                  ]
                ],
                [
                  "type": "free_text",
                  "description": "Briefly explain your choice."
                ]
              ]]]]]]]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/data-collection/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```