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

# Create a Section

> Author, version and publish reusable sections to compose into templates and to use in guided document generation

<Badge className="accent-badge" shape="rounded">Beta</Badge>

<Note>
  The `/documents/sections` endpoints — including section versions and publish — are available in beta. Feedback welcome at [help@corti.ai](mailto:help@corti.ai) or via your Corti contact.
</Note>

## What is a section?

A **section** is a reusable, versioned building block for document generation. It defines a single piece of structured output — for example a *Clinical Findings* section or an *Allergies* section — with its own:

* **`heading`** — a heading passed to the LLM and used in rendered output.
* **`instructions`** — the prompts that drive content selection, writing style and any miscellaneous guidance.
* **`outputSchema`** — the shape of the output (string, number, boolean, array or object). The schema is also a prompting surface: descriptions, enums, patterns, formats and min/max constraints all flow into how the LLM generates the content.

Sections are first-class resources. You can list, version, publish and reuse them across many templates.

## When to author your own sections

| Scenario                                                                                               | Why a custom section                                          |
| :----------------------------------------------------------------------------------------------------- | :------------------------------------------------------------ |
| You want a section that doesn't exist in the Corti standard library (e.g., a specialty-specific field) | Author once, reuse everywhere                                 |
| You want stable, versioned control over the prompt for a section your customers rely on                | Version & publish lifecycle                                   |
| You want a structured output (object/array with fields) instead of free-text                           | `outputSchema` lets you constrain shape                       |
| You want to fine-tune a Corti default section while still inheriting future improvements               | Use `inheritFromId` — see [Inheritance](/textgen/inheritance) |

## Section lifecycle at a glance

<Steps titleSize="h4">
  <Step title="Create the section">
    `POST /documents/sections` creates the section resource and its **version 0**. By default the new version is automatically published. Set `publish: false` to prevent the new section being returned in `LIST /documents/sections`
  </Step>

  <Step title="Iterate with new versions">
    `POST /documents/sections/{sectionID}/versions` creates a new version with a fresh `generation` config. New versions are *not* automatically published — the previously published version stays live until you explicitly publish a new one.
  </Step>

  <Step title="Publish a version">
    `POST /documents/sections/{sectionID}/versions/{versionID}/publish` sets that version as the published version. Only the published version is referenced by templates and used at generation time.
  </Step>

  <Step title="Use in a template or generation request">
    Reference the section by `id` from a template, or compose sections directly in a `POST /documents` request. See [Create a Template](/textgen/template-creation).
  </Step>
</Steps>

<Note>A section must be **published** before it can be referenced by a published template version or used in generation. `publish: true` is the default on creation.</Note>

## Create your first section

### Minimal request — string output

The simplest section produces a free-text string. You only need `name` and a `generation` block with `heading`, `instructions.contentPrompt` and an `outputSchema` of `type: string`. Optionally add `languages`, `regions`, `specialties` and `labels` if you want the section to be discoverable by those filters.

<CodeGroup>
  ```ts title="JavaScript" expandable theme={null}
  // Replace these with your values
  const ACCESS_TOKEN = "<your-access-token>";

  const section = await client.documents.sections.create({
    name: "Clinical Findings",
    languages: ["en"],
    description: "Summarises the key clinical findings from the interaction.",
    labels: [{ key: "category", value: "clinical" }],
    generation: {
      heading: "Clinical Findings",
      instructions: {
        contentPrompt: "Extract all relevant clinical findings mentioned during the interaction.",
        writingStylePrompt: "Use concise, professional medical language.",
      },
      outputSchema: { type: "string" },
    },
  });
  ```

  ```csharp title="C# .NET" expandable theme={null}
  using Corti;

  var section = await client.Documents.Sections.CreateAsync(
      new GuidedSectionsCreateFromScratchRequest
      {
          Name = "Clinical Findings",
          Languages = new[] { "en" },
          Description = "Summarises the key clinical findings from the interaction.",
          Labels = new[] { new GuidedLabel { Key = "category", Value = "clinical" } },
          Generation = new GuidedSectionGeneration
          {
              Heading = "Clinical Findings",
              Instructions = new GuidedSectionInstructions
              {
                  ContentPrompt = "Extract all relevant clinical findings mentioned during the interaction.",
                  WritingStylePrompt = "Use concise, professional medical language.",
              },
              OutputSchema = new GuidedStringNode(),
          },
      });
  ```

  ```python title="Python" expandable theme={null}
  import requests

  # Replace these with your values
  ENVIRONMENT = "<eu-or-us>"
  TENANT = "<your-tenant-name>"
  TOKEN = "<your-access-token>"

  response = requests.post(
      f"https://api.{ENVIRONMENT}.corti.app/v2/documents/sections",
      headers={
          "Authorization": f"Bearer {TOKEN}",
          "Tenant-Name": TENANT,
          "Content-Type": "application/json",
      },
      json={
          "name": "Clinical Findings",
          "languages": ["en"],
          "description": "Summarises the key clinical findings from the interaction.",
          "labels": [{"key": "category", "value": "clinical"}],
          "generation": {
              "heading": "Clinical Findings",
              "instructions": {
                  "contentPrompt": "Extract all relevant clinical findings mentioned during the interaction.",
                  "writingStylePrompt": "Use concise, professional medical language.",
              },
              "outputSchema": {"type": "string"},
          },
      },
  )
  response.raise_for_status()
  section = response.json()
  ```

  ```bash title="cURL" expandable theme={null}
  # Replace these with your values
  ENVIRONMENT="<eu-or-us>"
  TENANT="<your-tenant-name>"
  TOKEN="<your-access-token>"

  curl --request POST \
    --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/sections" \
    --header "Authorization: Bearer ${TOKEN}" \
    --header "Tenant-Name: ${TENANT}" \
    --header "Content-Type: application/json" \
    --data '{
      "name": "Clinical Findings",
      "languages": ["en"],
      "description": "Summarises the key clinical findings from the interaction.",
      "labels": [{ "key": "category", "value": "clinical" }],
      "generation": {
        "heading": "Clinical Findings",
        "instructions": {
          "contentPrompt": "Extract all relevant clinical findings mentioned during the interaction.",
          "writingStylePrompt": "Use concise, professional medical language."
        },
        "outputSchema": { "type": "string" }
      }
    }'
  ```
</CodeGroup>

The response is the created section, including its auto-published version 0:

```json title="Section response" expandable theme={null}
{
  "id": "<your-section-id>",
  "source": "user",
  "name": "Clinical Findings",
  "languages": ["en"],
  "regions": [],
  "specialties": [],
  "description": "Summarises the key clinical findings from the interaction.",
  "labels": [{ "key": "category", "value": "clinical" }],
  "publishedVersion": {
    "id": "<your-version-id>",
    "versionNumber": 0,
    "generation": {
      "heading": "Clinical Findings",
      "instructions": {
        "contentPrompt": "Extract all relevant clinical findings mentioned during the interaction.",
        "writingStylePrompt": "Use concise, professional medical language."
      },
      "outputSchema": { "type": "string" }
    }
  },
  "createdAt": "2026-05-12T10:00:00Z",
  "updatedAt": "2026-05-12T10:00:00Z"
}
```

<Tip>Keep the `name` and `description` human-friendly — they are *not* passed to the LLM. The `heading` and `instructions` are what the model sees.</Tip>

## Configuring the `generation` block

### `instructions`

| Field                        | Purpose                                                                                                                            |
| :--------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| `contentPrompt` *(required)* | What the section should include. In `documentationMode: routed_parallel`, this also drives which facts get routed to this section. |
| `writingStylePrompt`         | Tone, register and style (e.g. telegraphic, lay-person, formal narrative).                                                         |
| `miscPrompt`                 | Free-form prompt for anything that doesn't fit content or style — e.g. formatting nuances, fixed disclaimers, edge-case handling.  |

### `outputSchema`

`outputSchema` declares the *shape* and also acts as an additional prompting surface. The discriminator is `type`:

* **`string`** — free text, optionally constrained by `default`, `enum`, or `pattern`.
* **`number`** — integer or float, optionally constrained by `enum`, `minimum`, `maximum`, `default`.
* **`boolean`** — `true`/`false`, with an optional `default`.
* **`array`** — list of items of any schema type; configure `itemFormat` (a format string that must contain the `{item}` placeholder, e.g. `"- {item}\n"`), and `minItems`/`maxItems`.
* **`object`** — multi-field structured output. Declare `fields[]` (each with its own `key`, `description`, `value` schema). Control rendering with `fieldFormat` — either as a per-field iteration template using generic `{key}` / `{value}` placeholders (e.g. `"{key}: {value}\n"` inline, `"{key}\n{value}\n"` block) or as a fully custom layout referencing specific field keys (e.g. `"{test}: {result}"`).

<Note>The `description` on a schema node is a prompting field too — use it to give the model targeted guidance that supplements `instructions`.</Note>

<Card title="Designing Section Output Schemas — full reference" href="/textgen/section-schemas" icon="braces">
  The summary above is just the shape. For required-vs-optional fields per node type, the regex/enum/default behavior on `string`, the `itemFormat` and `fieldFormat` rendering primitives (both per-field iteration and fully custom layouts), and copy-paste clinical examples (fixed subheadings with explicit defaults, dynamic organ-system labels, mixed-type test results, EHR placeholders, prefixes like `Rp.`), see the **[Section Schemas guide](/textgen/section-schemas)**.
</Card>

### Example — structured object output

A *Vital Signs* section that returns a structured object with consistent rendering:

```json title="Section with object outputSchema" expandable theme={null}
{
  "name": "Vital Signs",
  "languages": ["en"],
  "labels": [
    { "key": "category", "value": "clinical" },
    { "key": "category", "value": "exam" }
  ],
  "generation": {
    "heading": "Vitals",
    "instructions": {
      "contentPrompt": "Extract vitals discussed during the encounter: blood pressure, heart rate, respiratory rate, temperature and SpO2. Omit any that were not mentioned.",
      "writingStylePrompt": "Telegraphic — values only, no narrative."
    },
    "outputSchema": {
      "type": "object",
      "fieldFormat": "**{key}**: {value}",
      "fields": [
        { "key": "Blood pressure", "description": "Systolic/diastolic in mmHg.", "value": { "type": "string", "pattern": "^\\d{2,3}/\\d{2,3}$" } },
        { "key": "Heart rate", "description": "Beats per minute.", "value": { "type": "number", "minimum": 0, "maximum": 300 } },
        { "key": "Respiratory rate", "description": "Breaths per minute.", "value": { "type": "number", "minimum": 0, "maximum": 80 } },
        { "key": "Temperature", "description": "In °C.", "value": { "type": "number" } },
        { "key": "SpO2", "description": "Percent oxygen saturation.", "value": { "type": "number", "minimum": 0, "maximum": 100 } }
      ]
    }
  }
}
```

### Example — array of items

A *Diagnoses* section returning a numbered list, capped at five items:

```json title="Section with array outputSchema" expandable theme={null}
{
  "name": "Diagnoses",
  "languages": ["en"],
  "generation": {
    "heading": "Diagnoses",
    "instructions": {
      "contentPrompt": "List the diagnoses discussed or established during the encounter, most relevant first."
    },
    "outputSchema": {
      "type": "array",
      "itemFormat": "* {item}\n",
      "minItems": 0,
      "maxItems": 5,
      "items": { "type": "string" }
    }
  }
}
```

## Next steps

<Columns cols={2}>
  <Card title="Inheritance" href="/textgen/inheritance" icon="layers">
    Create inheriting variants of this section to scale across customers, departments and specialties.
  </Card>

  <Card title="Versioning & publishing" href="/textgen/versioning" icon="git-branch">
    Iterate by creating new versions and publishing them on your own cadence.
  </Card>

  <Card title="Manage & discover" href="/textgen/management-discoverability" icon="folder-search">
    Read resolved-vs-raw, update metadata, delete with inheritance guards, filter LIST results.
  </Card>

  <Card title="Create a Template" href="/textgen/template-creation" icon="puzzle">
    Compose your sections into a versioned template that can be referenced at generation time.
  </Card>
</Columns>
