> 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.

# Update a Batch

PATCH https://api.prolific.com/api/v1/data-collection/batches/{batch_id}
Content-Type: application/json

Update an existing Task Builder batch. You can update the name, task details, associated dataset, and/or `batch_items`. The dataset does not need to be in READY status for updates.

When updating `batch_items`, include the `id` of any existing pages, rows, columns, or items you want to preserve — items without an `id` are treated as new and assigned one server-side. Omitting an existing `id` removes that entry. The same validation rules as on create apply, and validation failures return **`422 Unprocessable Entity`** with the `BatchItemsValidationError` payload.

Reference: https://docs.prolific.com/api-reference/task-builder/update-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

### Path parameters

- `batch_id` (string, required) — The unique identifier of the batch

### Body (application/json)

This endpoint expects an object.

- `name` (string, optional)
- `task_details` (ApiV1DataCollectionBatchesBatchIdPatchRequestBodyContentApplicationJsonSchemaTaskDetails, optional)
- `dataset_id` (string, optional)
- `batch_items` (list of BatchItemsPage, optional, nullable) — Replacement layout for the batch's instructions and content. Include the `id` of any existing pages, rows, columns, or items you want to preserve; omit `id` to add new entries. Items absent from the payload are removed.
- `auto_sync_enabled` (boolean, optional) — When `true`, datapoints subsequently appended to the batch's attached dataset (via `POST /datasets/{dataset_id}/datapoints`) automatically trigger a sync that materialises tasks for them — no explicit `POST /batches/{batch_id}/sync` call is needed. When `false`, appended datapoints are only picked up by an explicit sync. If this field is omitted from the PATCH payload, the existing auto-sync setting is left unchanged. A sync (auto or manual) only creates tasks on the batch — it doesn't grow the places on any study built from the batch unless that study opted in via `data_collection_metadata.increase_places_on_sync`.

## Response

### 200

Ok

- `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 TaskBuilderBatchDatasetsItems, 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)
- `schema_version` (integer, required)
- `task_details` (TaskBuilderBatchTaskDetails, required)
- `total_task_groups` (integer, required)
- `batch_items` (list of BatchItemsPage, optional, nullable) — The persisted `batch_items` layout, populated when the batch was created with `batch_items`. `null` for legacy batches authored via the standalone instructions endpoint. Every page, row, column, and item carries a server-assigned `id`.
- `auto_sync_enabled` (boolean, optional) — When `true`, datapoints appended to the batch's attached dataset automatically trigger a sync that materialises tasks for them. Optional — absent on batches that have never enabled auto-sync. Absent or `false` mean auto-sync is off.

## Errors

### 400 Bad Request Error

Bad Request

- `message` (string, optional)

### 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

### ApiV1DataCollectionBatchesBatchIdPatchRequestBodyContentApplicationJsonSchemaTaskDetails

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

### 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`

### TaskBuilderBatchDatasetsItems

- `id` (string, required)
- `total_datapoint_count` (integer, required)
- `filename` (string, required) — The filename of the dataset

### TaskBuilderBatchTaskDetails

- `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

**Request**

```json
{}
```

**Response**

```json
{
  "id": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "created_by": "6278cb09062dbb35bc4abebc",
  "datasets": [
    {
      "id": "string",
      "total_datapoint_count": 1,
      "filename": "string"
    }
  ],
  "name": "Data Collection Batch",
  "status": "UNINITIALISED",
  "total_task_count": 1,
  "total_instruction_count": 1,
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "schema_version": 1,
  "task_details": {
    "task_name": "string",
    "task_introduction": "string",
    "task_steps": "string"
  },
  "total_task_groups": 1,
  "batch_items": [
    {
      "rows": [
        {
          "columns": [
            {
              "items": [
                {
                  "type": "dataset_field",
                  "field": "string"
                }
              ],
              "id": "string"
            }
          ],
          "id": "string"
        }
      ],
      "id": "string",
      "display_position": "intro"
    }
  ],
  "auto_sync_enabled": true
}
```

**SDK Code**

```python
import requests

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

payload = {}
headers = {
    "Authorization": "Token <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript
const url = 'https://api.prolific.com/api/v1/data-collection/batches/batch_id';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
  body: '{}'
};

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

```go
package main

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

func main() {

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

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("PATCH", 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
require 'uri'
require 'net/http'

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

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Token <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

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

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.prolific.com/api/v1/data-collection/batches/batch_id")
  .header("Authorization", "Token <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.prolific.com/api/v1/data-collection/batches/batch_id', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Token <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.prolific.com/api/v1/data-collection/batches/batch_id");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Token <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Token <token>",
  "Content-Type": "application/json"
]
let parameters = [] 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/batch_id")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```