> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trycurious.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Format and requirements

> The structural contract arm content must satisfy (types, lengths, enums, arrays) and the phrase rules every arm follows; both fixed for an experiment's life.

Two declaration fields bound what a variant may be. The **format** says what shape the content has; the **requirements** say what phrases it must or must not contain. Every generated variant satisfies both, and a declared arm that violates either is skipped with a warning.

## Format

Content is a string, a number, or an object of named fields, nested up to four container levels. The format is a field spec, or an object of named field specs, mirroring the content:

```json theme={null}
"format": {
  "headline": { "type": "text", "max_characters": 90 },
  "body": { "type": "html" },
  "price": { "type": "number", "min": 9, "max": 99 },
  "tone": { "type": "enum", "values": ["warm", "direct"] },
  "bullets": { "type": "array", "items": { "type": "text", "max_characters": 60 }, "max_items": 5 }
}
```

| Spec | Fields | Notes |
| - | - | - |
| `text`, `html` | `min_characters`, `max_characters` | Character bounds, `min` at most `max`. |
| `number` | `min`, `max` | Bounds are enforced on content. Required when a reward reads `arm.<field>`. |
| `enum` | `values` | The value is one of `values`, which are strings. |
| `array` | `items`, `min_items`, `max_items` | Homogeneous. Defaults to 20 items; `max_items` may be declared up to 100. `items` is required. |
| object | named specs | A field whose value is itself an object of specs. |

Three names are impossible in content: `type` (it marks a typed spec), `__proto__`, and anything nested deeper than four levels. Content values are never booleans or nulls.

**Omitted, the format is inferred from the control** on the first call: a string control is a text field, an object control is an object of text fields, and so on. **Declared, the control must match it.** The format is what makes a variant servable by your renderer without a code change, so it is fixed for the experiment's life: a changed format supersedes the experiment. An omitted format on a later call carries the running one forward.

The type of the element never constrains the format; a provided control is the ground truth about what your renderer displays.

## Requirements

```json theme={null}
"requirements": {
  "forbidden_phrases": ["Limited Time", "Act now"],
  "required_phrases": ["Acme"]
}
```

Phrase rules every arm must satisfy. Generated variants obey them; a declared arm that breaks one is skipped with an `arm_invalid` warning. Character and length limits belong in the format, not here. Requirements are fixed for the experiment's life: a tightened rule would make existing arms non-compliant, so a change supersedes the experiment.

## Instructions

Prose guidance for future variants (`"instructions": "Optimize for enterprise buyers evaluating an upgrade. No hype."`) is neither a format nor a requirement. It updates in place and shapes the next generation round without touching existing arms.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.