Skip to main content

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.

Beta. The /documents/sections endpoints — including section versions and publish — are available in beta. Feedback welcome at help@corti.ai or via your Corti contact.

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

ScenarioWhy 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 onVersion & publish lifecycle
You want a structured output (object/array with fields) instead of free-textoutputSchema lets you constrain shape
You want to fine-tune a Corti default section while still inheriting future improvementsUse inheritFromId (covered below)

Section lifecycle at a glance

1

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
2

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

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

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

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.
// 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" },
  },
});
The response is the created section, including its auto-published version 0:
Section response
{
  "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"
}
Keep the name and description human-friendly — they are not passed to the LLM. The heading and instructions are what the model sees.

Configuring the generation block

instructions

FieldPurpose
contentPrompt (required)What the section should include. In documentationMode: routed_parallel, this also drives which facts get routed to this section.
writingStylePromptTone, register and style (e.g. telegraphic, lay-person, formal narrative).
miscPromptFree-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.
  • booleantrue/false, with an optional default.
  • array — list of items of any schema type; configure itemFormat (bullet, numbered, plain, or custom {item} template), 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}").
The description on a schema node is a prompting field too — use it to give the model targeted guidance that supplements instructions.

Designing Section Output Schemas — full reference

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.

Example — structured object output

A Vital Signs section that returns a structured object with consistent rendering:
Section with object outputSchema
{
  "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:
Section with array outputSchema
{
  "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": "numbered",
      "minItems": 0,
      "maxItems": 5,
      "items": { "type": "string" }
    }
  }
}

Inheriting from an existing section

Instead of writing a section from scratch, you can inherit from an existing one and override only the fields you need. The published version of the referenced section provides the defaults; any field you omit in generation is inherited.
Inherit & override
{
  "name": "HPI (Pediatric)",
  "languages": ["en"],
  "inheritFromId": "<your-section-id>",
  "generation": {
    "instructions": {
      "writingStylePrompt": "Use family-centred language; refer to the patient as 'the child'."
    }
  }
}
Inheritance follows the published version of the referenced section at request time. If the upstream section is republished with improvements, your inherited section will pick them up for any field you have not overridden.
Inheriting from a Corti Standard — silent updates. Corti improves and refines its Corti Standard sections continuously. Updates are typically silent — small prompt refinements and quality fixes ship the same way many small API releases do, without per-change notes. Only clear schema-breaking changes or significant behavior changes are explicitly communicated.Inheritance cannot pin you to a specific upstream version. If your integration requires staying on a specific behavior, do not use inheritFromId against a Corti Standard — instead, re-create the section as your own resource by copying its configuration into a POST /documents/sections request without inheritFromId. The new resource is yours to version; subsequent Corti updates will not reach it.This caveat applies specifically to inheritance from Corti Standards. When inheriting from sections you yourself authored, your project controls the publish cadence — there are no silent updates from Corti to worry about.

Versioning a section

Once a section exists, iterate by creating new versions. New versions are not published automatically — your previously published version stays live until you explicitly publish a new one.
// Replace these with your values
const SECTION_ID = "<your-section-id>";

const version = await client.documents.sections.versions.create(SECTION_ID, {
  generation: {
    heading: "Clinical Findings",
    instructions: {
      contentPrompt: "Extract all relevant clinical findings, grouped by body system where applicable.",
      writingStylePrompt: "Concise, professional, with grouped subheadings when relevant.",
    },
    outputSchema: { type: "string" },
  },
});
The response returns the new version with an auto-incremented versionNumber.
// Replace these with your values
const SECTION_ID = "<your-section-id>";
const VERSION_ID = "<your-version-id>";

await client.documents.sections.versions.publish(SECTION_ID, VERSION_ID);
A successful publish returns { "status": "published" } and the section’s publishedVersion will reflect the new version on subsequent GET calls.
Treat unpublished versions as drafts. You can GET the list of versions, inspect each, and only publish once you’re confident.

Managing sections

ActionEndpoint
List sections (filter by lang, region, specialty, label, published)GET /documents/sections
Get a section (resolved, ready-to-use)GET /documents/sections/{sectionID}
Update metadata (name, description, languages, regions, specialties, labels)PATCH /documents/sections/{sectionID}
Soft-delete a sectionDELETE /documents/sections/{sectionID} — returns 409 Conflict if another section inherits from this one
List versions (raw)GET /documents/sections/{sectionID}/versions
Get a specific version (raw — owned values only)GET /documents/sections/{sectionID}/versions/{versionID}
Soft-delete a versionDELETE /documents/sections/{sectionID}/versions/{versionID}
PATCH /documents/sections/{sectionID} only updates section-level metadata. To change the prompts or output schema, create a new version and publish it.
Resolved vs. raw — what each read returns.
  • GET /documents/sections/{sectionID} returns the section resolved — all inheritance applied, so what you read is the configuration that will be used at generation time. Use this when your consumer just needs the ready-to-use shape.
  • GET /documents/sections/{sectionID}/versions/{versionID} returns the version raw — only the section’s own (overridden) values and the inheritFromId reference. Use this when you need to distinguish inherited fields from fields the section explicitly overrides.
  • LIST /documents/sections/{sectionID}/versions returns the same raw shape as the version GET.
Deletion visibility. After a section is soft-deleted, LIST /documents/sections no longer returns it, but GET /documents/sections/{sectionID} and the version reads continue to work — useful for audit, debugging, and resolving sections still referenced by historical documents.
DELETE returns 409 Conflict if another section inherits from the section you’re trying to delete. Resolve the dependency first (delete or re-parent the inheriting sections) before retrying the delete.

Listing and discovering sections

GET /documents/sections returns all sections accessible to your project — the project in Corti Console that your API key is associated with. Use query params to narrow results:
Query paramBehavior
langBCP-47 language subtag (e.g. fr, de). Repeatable (e.g. ?lang=en&lang=da). Matches sections whose languages[] contains any of the supplied values.
regionISO 3166-1 alpha-3 country code (e.g. BEL, USA). Repeatable. Matches sections whose regions[] contains any of the supplied values.
specialtyClinical specialty (e.g. dermatology, cardiology). Repeatable. Matches sections whose specialties[] contains any of the supplied values.
labelLabel filter in key:value format (e.g. ?label=customer:acme). Repeatable; matches sections that carry any of the given Label entries.
publishedOmit for both, true for published-only, false for unpublished-only.
Empty languages, regions, or specialties on a section means “no tweaks for that dimension” — i.e. the section is generic along that axis. The resource fields are arrays, but each one is optional and empty by default.
// Filter by language, region, specialty, label, and/or publish status.
// All four filter params are repeatable arrays. `label` values use "key:value".
const sections = await client.documents.sections.list({
  lang: ["en"],
  region: ["USA"],
  specialty: ["dermatology"],
  label: ["customer:acme"],
  published: true,
});

Next steps

Create a Template

Compose your sections into a versioned template that can be referenced at generation time.

Corti Standards

Browse the Corti-curated standard sections and templates available to every API client by default — useful as a starting point or as a base for inheritance.