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

# Configurable Layout (`batch_items`)

The `batch_items` field lets you control exactly how content is arranged on the participant task screen. Instead of a fixed, sequential layout, you describe your task as a set of pages, rows, and columns, and place dataset stimuli, display content, and input questions wherever you want them.

This unlocks layouts such as **side-by-side evaluations**, mixed display and input blocks, and multi-column comparisons — all defined declaratively when you create or update a Batch.

Configurable layout is available for **AI Task Builder Batches only** (not Collections or Survey Builder), and is set up via the API. `dataset_field` items require a **V4 dataset with a schema** — see [Defining a Dataset Schema](/api-reference/ai-task-builder/dataset-schema).

## When to use `batch_items`

| Approach                        | Behaviour                                                                                                                                         |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Batch **without** `batch_items` | Legacy mode. Instructions are created separately via the `POST /instructions` endpoint and displayed sequentially alongside each datapoint.       |
| Batch **with** `batch_items`    | Configurable layout. You control the position of every stimulus, content block, and input, and instructions are defined inline within the layout. |

When `batch_items` is set, instructions are defined inline within the layout rather than through the standalone instructions endpoint — giving you full control over where they appear relative to dataset stimuli and display content. See [Relationship to the standalone instructions endpoint](#relationship-to-the-standalone-instructions-endpoint).

## Structure

`batch_items` is a four-level nested structure:

```
batch_items = Page[]
Page        = { rows: Row[] }
Row         = { columns: Column[] }   // 1–2 columns
Column      = { items: ColumnItem[] }
```

* A **page** is repeated once per dataset row. For the current single-task Batch use case, `batch_items` typically contains a single page.
* A **row** stacks vertically down the screen.
* A **column** sits horizontally within a row (maximum 2 per row).
* An **item** is a single component rendered top-to-bottom within its column.

## Column item types

Each item in a column is a tagged object discriminated by its `type` field. There are three categories.

### Dataset fields

Pull a value from your dataset schema into the layout.

| Field   | Type   | Required | Description                                                                                                    |
| ------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
| `type`  | string | Yes      | `"dataset_field"`                                                                                              |
| `field` | string | Yes      | The name of a field declared in the dataset schema. Case-sensitive — must match the schema field name exactly. |

Only fields typed `text` or `image_url` can be referenced. Fields typed `metadata` or `task_group_id` are not participant-visible and are rejected.

```json
{ "type": "dataset_field", "field": "response_a" }
```

Today, `dataset_field` items support **text** and **image** fields. Support for presenting audio and video stimuli in the task UI is on the roadmap and will be added as additional field types without breaking existing layouts.

### Content blocks (display-only)

Static content defined inline. These use the same schemas as content blocks elsewhere in AI Task Builder.

**`rich_text`**

| Field            | Type   | Required | Description                                           |
| ---------------- | ------ | -------- | ----------------------------------------------------- |
| `type`           | string | Yes      | `"rich_text"`                                         |
| `content`        | string | Yes      | The text to display. Supports basic HTML or Markdown. |
| `content_format` | string | No       | `"html"` (default) or `"markdown"`.                   |

```json
{
  "type": "rich_text",
  "content": "<p>Rate each response for factual accuracy.</p>",
  "content_format": "html"
}
```

**`image`**

| Field      | Type   | Required | Description                                                    |
| ---------- | ------ | -------- | -------------------------------------------------------------- |
| `type`     | string | Yes      | `"image"`                                                      |
| `url`      | string | Yes      | HTTPS URL of the image to display. Must begin with `https://`. |
| `alt_text` | string | Yes      | Accessible alt text for the image.                             |
| `caption`  | string | No       | Optional caption shown beneath the image.                      |

```json
{
  "type": "image",
  "url": "https://example.com/reference.png",
  "alt_text": "Reference diagram",
  "caption": "Figure 1"
}
```

### Instructions (inputs)

Input questions defined inline. These use the standard AI Task Builder instruction input schemas — the same ones documented in [Instructions](/api-reference/ai-task-builder/instructions). Supported types:

* `free_text`
* `free_text_with_unit`
* `multiple_choice`
* `multiple_choice_with_free_text`
* `file_upload`

```json
{
  "type": "multiple_choice",
  "description": "Which response is more accurate?",
  "answer_limit": 1,
  "options": [
    { "label": "Response A", "value": "a" },
    { "label": "Response B", "value": "b" }
  ]
}
```

Instruction items are validated against the same input schemas used for standalone [Instructions](/api-reference/ai-task-builder/instructions). Refer to that page for the full set of fields available on each input type.

## Example: side-by-side evaluation

A comparison layout with per-column ratings and a shared free-text follow-up. The first row shows shared guidance; the second row places each image and its rating in its own column; the third row collects reasoning across the full width. Here each image is displayed with an `image` content block.

```json
{
  "batch_items": [
    {
      "rows": [
        {
          "columns": [
            {
              "items": [
                {
                  "type": "rich_text",
                  "content": "<p>Compare the two images and rate how well each one matches the prompt.</p>",
                  "content_format": "html"
                }
              ]
            }
          ]
        },
        {
          "columns": [
            {
              "items": [
                {
                  "type": "image",
                  "url": "https://example.com/image_a.png",
                  "alt_text": "Response A"
                },
                {
                  "type": "multiple_choice",
                  "answer_limit": 1,
                  "options": [
                    { "label": "Matches the prompt", "value": "match" },
                    { "label": "Does not match", "value": "no_match" }
                  ]
                }
              ]
            },
            {
              "items": [
                {
                  "type": "image",
                  "url": "https://example.com/image_b.png",
                  "alt_text": "Response B"
                },
                {
                  "type": "multiple_choice",
                  "answer_limit": 1,
                  "options": [
                    { "label": "Matches the prompt", "value": "match" },
                    { "label": "Does not match", "value": "no_match" }
                  ]
                }
              ]
            }
          ]
        },
        {
          "columns": [
            {
              "items": [
                {
                  "type": "free_text",
                  "helper_text": "Explain your reasoning"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

## Setting `batch_items`

Provide `batch_items` when creating (or updating) a Batch, alongside your dataset and task details.

```bash
POST /api/v1/data-collection/batches
```

```json
{
  "name": "Response evaluation batch",
  "workspace_id": "6278acb09062db3b35bcbeb0",
  "dataset_id": "0192a3b5-e8f9-7a0b-1c2d-3e4f5a6b7c8d",
  "task_details": {
    "task_name": "Evaluate AI Responses"
  },
  "batch_items": [
    {
      "rows": [
        {
          "columns": [
            {
              "items": [
                { "type": "dataset_field", "field": "prompt" }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

Validation runs at Batch creation and update time, before any participant-facing tasks are generated. An invalid `batch_items` value is rejected with a `422` response listing every offending item and its position:

```json
{
  "type": "INVALID_BATCH_ITEMS",
  "message": "batch_items validation failed",
  "issues": [
    {
      "page": 0,
      "row": 1,
      "column": 0,
      "item": 0,
      "type": "dataset_field",
      "field": "responze_a",
      "message": "Field not found in dataset schema"
    }
  ]
}
```

Each issue pinpoints the item by its zero-based `page`, `row`, `column`, and `item` index, along with the item `type` and (for `dataset_field` items) the offending `field`.

## Constraints and validation

**Structural**

* Maximum **2 columns** per row.
* No limit on the number of rows.
* No limit on the number of items within a column.
* Each page must contain at least one row; each row at least one column; each column at least one item.

**Dataset fields**

* `field` must match a field in the dataset schema with type `text` or `image_url`.
* `metadata` and `task_group_id` fields are rejected — they are not participant-visible.
* The same `field` may not appear more than once across a page.

**Instructions and content blocks**

* Instruction items are validated against the existing instruction input schemas (the same validation applied to standalone instructions).
* Content block items are validated against the existing content block schemas.

## Relationship to the standalone instructions endpoint

There are two ways to define instructions on a Batch, and they are mutually exclusive:

* **Standalone endpoint (legacy):** `POST /api/v1/data-collection/batches/{batch_id}/instructions` — see [Working with Batches](/api-reference/ai-task-builder/batches). Used when `batch_items` is not set.
* **Inline in `batch_items`:** instruction items defined directly in the layout.

When `batch_items` is set, the inline instructions are the source of truth. The standalone instructions endpoints are **deprecated** for such Batches and reject create and update calls with a `422`.

| Scenario                    | Behaviour                                                                                                           |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `batch_items` not set       | Legacy mode. Define instructions via the standalone `POST /instructions` endpoint; they are displayed sequentially. |
| `batch_items` set           | Instructions are defined inline. Calls to the standalone create/update instructions endpoints return `422`.         |
| `batch_items` set to `null` | Reverts to legacy mode.                                                                                             |

The standalone instructions endpoint is deprecated for Batches that use `batch_items` and is scheduled for removal — manage instructions via `batch_items` instead. `batch_items` is never added automatically to existing Batches.

If the dataset schema changes after a Batch is created and a `dataset_field` reference becomes invalid (for example, the field is removed from the schema), this is surfaced as a warning at schema mutation time.

## Extensibility

The layout model is designed to grow without breaking existing `batch_items` values:

* **New component types** (for example audio and video stimuli, or additional input types) are additive — existing layouts remain valid.
* **Multi-page tasks** are supported by the array structure from the start.
* The wider participant task model (Sections → Pages → Components) maps cleanly onto this structure: each page is a Body page, and each column item is a component.

***

By using AI Task Builder, you agree to our [AI Task Builder Terms](https://prolific.notion.site/Researcher-Terms-7787f102f0c541bdbe2c04b5d3285acb).