Compose published sections into a versioned, reusable template
Beta
The /documents/templates endpoints — including template versions and publish — are available in beta. Feedback welcome at help@corti.ai or via your Corti contact.
A template combines one or more published sections with a top-level instruction and exposes a single, versioned resource that can be referenced at generation time. Where a section is the building block, a template is the assembled note: e.g. a Post-Consultation Note template made up of Chief Complaint, History of Present Illness, Assessment, and Plan sections.A template has:
Metadata — name, description, language, labels. Metadata is not passed to the LLM.
instructions.prompt — a template-level prompt that applies to all sections during generation (e.g. setting overall tone, framing the encounter, or referencing the audience for the note).
sections[] — references to existing sections by sectionId, plus an orderIndex controlling the order they appear in the generated document.
Templates, like sections, are versioned and publishable. Only the published version is used at generation time.
The section’s id (UUID). You can obtain this from the create response or by listing sections via GET /documents/sections.
Only published sections can be referenced in a published template version. If you reference an unpublished section, the template version will fail to publish until that section is published.
The template below references two sections you’ve already published. orderIndex starts at 0 and controls section order in the output.
// Replace these with your values — section IDs come from LIST /documents/sectionsconst SECTION_ID_1 = "<your-section-id>";const SECTION_ID_2 = "<your-section-id>";const template = await client.documents.templates.create({ name: "Post-Consultation Note", languages: ["en"], description: "Standard note produced after a patient consultation.", labels: [{ key: "category", value: "consultation" }], generation: { instructions: { prompt: "Produce a structured clinical note from the consultation. Refer to the patient by their pronouns when known.", }, sections: [ { sectionId: SECTION_ID_1, orderIndex: 0 }, { sectionId: SECTION_ID_2, orderIndex: 1 }, ], },});
using Corti;// Replace these with your valuesconst string SectionId1 = "<your-section-id>";const string SectionId2 = "<your-section-id>";var template = await client.Documents.Templates.CreateAsync( new GuidedTemplatesCreateFromScratchRequest { Name = "Post-Consultation Note", Languages = new[] { "en" }, Description = "Standard note produced after a patient consultation.", Labels = new[] { new GuidedLabel { Key = "category", Value = "consultation" } }, Generation = new GuidedTemplatesCreateFromScratchRequestGeneration { Instructions = new GuidedTemplateInstructions { Prompt = "Produce a structured clinical note from the consultation. Refer to the patient by their pronouns when known.", }, Sections = new[] { new GuidedTemplatesVersionSectionRequest { SectionId = SectionId1, OrderIndex = 0 }, new GuidedTemplatesVersionSectionRequest { SectionId = SectionId2, OrderIndex = 1 }, }, }, });
import requests# Replace these with your valuesENVIRONMENT = "<eu-or-us>"SECTION_ID_1 = "<your-section-id>"SECTION_ID_2 = "<your-section-id>"TENANT = "<your-tenant-name>"TOKEN = "<your-access-token>"response = requests.post( f"https://api.{ENVIRONMENT}.corti.app/v2/documents/templates", headers={ "Authorization": f"Bearer {TOKEN}", "Tenant-Name": TENANT, "Content-Type": "application/json", }, json={ "name": "Post-Consultation Note", "languages": ["en"], "description": "Standard note produced after a patient consultation.", "labels": [{"key": "category", "value": "consultation"}], "generation": { "instructions": { "prompt": "Produce a structured clinical note from the consultation. Refer to the patient by their pronouns when known.", }, "sections": [ {"sectionId": SECTION_ID_1, "orderIndex": 0}, {"sectionId": SECTION_ID_2, "orderIndex": 1}, ], }, },)response.raise_for_status()template = response.json()
# Replace these with your valuesENVIRONMENT="<eu-or-us>"SECTION_ID_1="<your-section-id>"SECTION_ID_2="<your-section-id>"TENANT="<your-tenant-name>"TOKEN="<your-access-token>"curl --request POST \ --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/templates" \ --header "Authorization: Bearer ${TOKEN}" \ --header "Tenant-Name: ${TENANT}" \ --header "Content-Type: application/json" \ --data "{ \"name\": \"Post-Consultation Note\", \"languages\": [\"en\"], \"description\": \"Standard note produced after a patient consultation.\", \"labels\": [{ \"key\": \"category\", \"value\": \"consultation\" }], \"generation\": { \"instructions\": { \"prompt\": \"Produce a structured clinical note from the consultation. Refer to the patient by their pronouns when known.\" }, \"sections\": [ { \"sectionId\": \"${SECTION_ID_1}\", \"orderIndex\": 0 }, { \"sectionId\": \"${SECTION_ID_2}\", \"orderIndex\": 1 } ] } }"
The response is the created template with the auto-published version 0. On GET /documents/templates/{templateID} the response is resolved — each referenced section is fully expanded with all inheritance applied, ready to be consumed as-is. The version reads (GET /documents/templates/{templateID}/versions/{versionID} and LIST /documents/templates/{templateID}/versions) return the raw template version — only the values the template itself owns, plus the section references. Use the version reads when you need to distinguish inherited fields from fields this template explicitly overrides.
Template response
{ "id": "<your-template-id>", "source": "user", "name": "Post-Consultation Note", "languages": ["en"], "regions": [], "specialties": [], "description": "Standard note produced after a patient consultation.", "labels": [{ "key": "category", "value": "consultation" }], "publishedVersion": { "id": "<your-version-id>", "versionNumber": 0, "generation": { "instructions": { "prompt": "Produce a structured clinical note from the consultation. Refer to the patient by their pronouns when known." }, "sections": [ { "id": "<your-section-id>", "name": "Chief Complaint", "...": "..." }, { "id": "<your-section-id>", "name": "History of Present Illness", "...": "..." } ] } }, "createdAt": "2026-05-12T10:00:00Z", "updatedAt": "2026-05-12T10:00:00Z"}
How template instructions interact with section instructions
A template’s generation.instructions.prompt is applied at the top level, alongside each section’s own instructions. Use it for cross-section guidance that you don’t want to repeat in every section:
Overall persona, audience or register (e.g. “Write for a referring specialist”).
Encounter framing (e.g. “This is a follow-up visit, not a new consultation”).
Patient or scenario context that all sections should respect.
Keep section-specific guidance in the section. Keep template-wide guidance in the template prompt. Mixing them makes templates harder to reuse — and harder for the LLM to disambiguate when instructions conflict.
Author once, reuse everywhere. A single well-tuned corti-hpi-style section can power multiple templates. Avoid embedding section-specific guidance in templates.
Prefer narrow, focused sections. Sections that try to do too much are harder to reuse and harder to constrain via outputSchema.
Use labels for discovery. Labels are how you (and downstream consumers) filter sections and templates at list time.
Use inheritance for variants. Pediatric, geriatric or specialty-specific variants of a base template are a good fit for inheritFromId.