# Text answer

> Ask an open-ended question answered in the respondent's own words, optionally about a media subject shown above the answer box.

Text-answer tasks present a question and a free-text box. Instead of selecting from predefined options, annotators write their answer in their own words.

Each datapoint can optionally carry a single **media subject** — one already-uploaded video, image, or audio clip rendered **above** the question, so annotators describe or react to what they see. For video and audio subjects, the annotator must observe most of the clip before they can submit.

## When to use it

- Open-ended feedback ("What did you like or dislike about this product?")
- Descriptions of media ("Describe what happens in this clip")
- Qualitative follow-ups that structured options can't capture
- Verbatims for downstream analysis (samples surface in reports and Ask&nbsp;Your&nbsp;Report)

## Datapoint shape

A plain open question sends an empty `media` object; the question itself lives in the job `instruction` (or the step instruction inside a [chain](/docs/chains)):

```json
{
  "media": {},
  "context": "The tagline: “Just do it.”"
}
```

<ParamTable
  title="datapoint"
  params={[
    { name: "context", type: "string", required: false, description: "Optional content the respondent reacts to. Add {context} to the instruction to display it." },
    { name: "media.subject", type: "array of { url | media_id, type? }", required: false, description: "Optional. 0 or 1 already-uploaded media item, rendered above the question. Reference it by a dp:// url or media_id — not a public https URL (see below)." }
  ]}
/>

### Adding a media subject

To ask about a clip or image, upload it first with `POST /media`, then reference the returned handle from the datapoint's `media.subject` — the same two-step flow as a [multiple-choice subject](/docs/task-types/multiple-choice):

```json
{
  "context": "Describe what the worker is doing.",
  "media": {
    "subject": [
      { "media_id": "b6a1cd3f-1234-4a2b-9c8d-0e1f2a3b4c5d" }
    ]
  }
}
```

<DocCallout type="warning" title="The subject must be an uploaded item, not a public URL">
The text-answer subject does **not** accept a public `https` URL — it must be a `dp://` reference or a `media_id` from `POST /media`. Always upload the subject first and reference it by `dp://` url or `media_id`.
</DocCallout>

A subject does not change the submission format or `response_options`; annotators still submit only their written answer.

## Input configuration

All of `response_options` is optional:

```json
{
  "task_type": "text_answer",
  "response_options": {
    "min_length": 10,
    "max_length": 500,
    "placeholder": "Type your answer…"
  }
}
```

<ParamTable
  title="response_options"
  params={[
    { name: "min_length", type: "int", description: "Minimum answer length in characters. Answers are trimmed before checking; empty answers are always rejected." },
    { name: "max_length", type: "int", description: "Maximum answer length in characters. Must be ≥ min_length when both are set." },
    { name: "placeholder", type: "string", description: "Placeholder text shown in the empty answer box." }
  ]}
/>

## Result shape

Free text can't be tallied into votes, so the aggregation reports how many people answered plus a bounded sample of the verbatims (up to 50):

```json
{
  "datapoint_index": 0,
  "total_responses": 12,
  "samples": [
    "The pacing feels rushed in the second half.",
    "Loved the colors, but the ending was confusing."
  ],
  "media": [
    {
      "media_id": "b6a1cd3f-1234-4a2b-9c8d-0e1f2a3b4c5d",
      "type": "video",
      "role": "subject",
      "url": "/media/v2/b6a1cd3f-1234-4a2b-9c8d-0e1f2a3b4c5d?sig=..."
    }
  ]
}
```

Every individual answer is available row-by-row via `GET /jobs/{id}/responses`, and the report's question block lists the verbatims.

## Example

```bash
curl -X POST https://api.trydatapoint.com/data-labelling/v1/jobs \
  -H "X-API-Key: $DATAPOINT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "clip-descriptions-v1",
    "instruction": "Watch the clip, then describe what happens.",
    "task_type": "text_answer",
    "response_options": { "min_length": 10, "max_length": 500 },
    "max_responses_per_datapoint": 10,
    "datapoints": [
      {
        "media": {
          "subject": [
            { "media_id": "b6a1cd3f-1234-4a2b-9c8d-0e1f2a3b4c5d" }
          ]
        }
      }
    ]
  }'
```

## Common errors

| Status | Cause |
|---|---|
| `400` | `min_length` / `max_length` not a non-negative integer, or `min_length` > `max_length`. |
| `400` | `media.subject` has 2+ items (0 or 1 allowed). |
| `400` | A subject references media you don't own, or a public URL instead of an uploaded item. |
| `422` | `max_responses_per_datapoint` outside range, or a required top-level field is missing or malformed. |

## Next

- [Multiple choice](/docs/task-types/multiple-choice): when the answer space is discrete and known in advance
- [Chains](/docs/chains): follow a structured step with an open-ended "why?"
- [API Reference: Jobs](/docs/api/jobs): full endpoint reference
