# CSV manifests

CSV manifests let you describe self-hosted stimuli explicitly. Upload a `.csv` file with one row per stimulus.

```csv
group,condition,url,file_ext
source_1,model_a,https://cdn.example.com/datasets/source_1/model_a.wav,
source_1,model_b,https://cdn.example.com/datasets/source_1/model_b.wav,
source_2,model_a,https://cdn.example.com/datasets/source_2/model_a,
source_2,model_b,https://cdn.example.com/datasets/source_2/model_b,wav
```

## Columns

| Column | Required | Description |
|  --- | --- | --- |
| `group` | Yes | The stimulus group name. Leave empty to use `root`. |
| `condition` | Yes | The condition or stimulus name inside the group. |
| `url` | Yes | The URL of the remote stimulus. |
| `file_ext` | No | File extension used to infer the stimulus type when the URL does not include one. |


The `file_ext` value should not include a leading dot. For example, use `wav`, not `.wav`.

## How groups and stimuli are created

Each row creates one stimulus in the specified group.

```csv
group,condition,url,file_ext
prompt_001,elevenlabs,https://cdn.example.com/audio/001/elevenlabs,wav
prompt_001,cartesia,https://cdn.example.com/audio/001/cartesia,wav
```

Creates:

- Group: `prompt_001`
- Stimuli: `elevenlabs.wav` and `cartesia.wav`


The same `group` and `condition` pair can only appear once in a CSV manifest.

## Embedded frontends

CSV manifests are useful when the stimulus URL points to a hosted frontend rather than a media file. For embedded experiments, the `url` can point to the remote page that should be loaded in the experiment iframe, while `group` and `condition` control how that stimulus is named in Mabyduck.

```csv
group,condition,url,file_ext
task_1,variant_a,https://frontend.example.com/task-1?variant=a,html
task_1,variant_b,https://frontend.example.com/task-1?variant=b,html
```

## Requirements

The CSV file must include a header row with `group`, `condition`, and `url`. The optional `file_ext` header is only needed when you want to provide file extensions explicitly.

The `condition` and `url` fields cannot be empty. In normal use, URLs should start with `https://`.

Localhost and private network URLs are blocked outside development environments.