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.
Why migrate
The Guided surface is the path forward. Documents Classic will be deprecated once Beta reaches general availability — see the callout above. Migrating before the sunset gives you time to validate parity and gain the new capabilities. Documents Classic uses string keys (templateKey: "corti-soap", key: "corti-hpi") and a fixed override surface (nameOverride, writingStyleOverride, formatRuleOverride, additionalInstructionsOverride, contentOverride) attached to POST /interactions/{id}/documents.
The new API treats sections and templates as first-class, UUID-addressable, versioned resources and moves generation to POST /documents — interaction-optional, with a single consistent request shape across four template-supply paths. Concretely you gain:
- Typed, schema-controlled outputs (
outputSchema) instead of free-text formatting rules — see Section Schemas. - Versioning & publish lifecycle for your own sections and templates — see Create a Section.
- Drift-proof generation snapshots — every call records the resolved template aggregate it used.
- Interaction-optional context — pass explicit
context(text / transcript / facts) or aninteractionId— they are currently mutually exclusive; combining is on the roadmap.
Mental-model shift
Three things change about how you think about templates and sections:- String keys → UUIDs.
templateKey: "corti-soap"becomestemplateId: "<some-uuid>". Section keys behave the same way. - Per-locale UUIDs. Each Corti Standard section and template is published as a separate resource per locale. The English
corti-hpiand the Germancorti-hpishare the samekeybut have different UUIDs. Your discovery step must include thelangfilter. - Source-aware library.
LIST /documents/sectionsandLIST /documents/templatesreturn your own resources alongside Corti Standards. Each item carries asourcefield —cortifor Corti Standards,userfor API-client–authored resources in your project — so you can filter client-side. Server-side query params today arelang,region,specialty,labelandpublished. See Corti Standards.
Endpoint mapping
| Classic | New |
|---|---|
GET /templates | LIST /documents/templates (filter via lang, region, specialty, label; filter on source client-side to scope to Corti Standards vs. your own) |
GET /templates/{key} | GET /documents/templates/{templateID} (after resolving the key + locale to a UUID via the list endpoint) |
GET /templateSections | LIST /documents/sections (same filtering) |
POST /interactions/{id}/documents (with templateKey) | POST /documents — Path 1 (plain templateRef) |
POST /interactions/{id}/documents (with template.sections[] + overrides) | POST /documents — Path 2 (templateRef + overrides) or Path 3 (assemblyTemplate) — see below |
Field mapping — Classic overrides → new
Where a Classic override sat undertemplate.sections[].keyOverride, the new equivalent lives under overrides.sections[].generation.* on a templateRef or assemblyTemplate request.
| Classic field | New equivalent | Notes |
|---|---|---|
template.description | overrides.instructions.prompt (Path 2) or assemblyTemplate.instructions.prompt (Path 3) | Template-level prompt |
template.additionalInstructionsOverride | overrides.instructions.prompt | Template-level |
sections[].key | sections[].sectionId (Path 2) / sectionRefs[].sectionId (Path 3) | Per-locale UUID — resolve once via LIST /documents/sections?lang=... (filter on source: "corti" client-side if scoping to Standards) |
sections[].nameOverride | sections[].generation.heading | Section heading override |
sections[].writingStyleOverride | sections[].generation.instructions.writingStylePrompt | |
sections[].contentOverride | sections[].generation.instructions.contentPrompt | |
sections[].additionalInstructionsOverride | sections[].generation.instructions.miscPrompt | Free-form section-level guidance |
sections[].formatRuleOverride | No 1:1 — use outputSchema | See note below |
outputLanguage | outputLanguage | Unchanged |
name | n/a on the request — track in your own system if needed | The response carries the auto-generated templateId you can use to identify the call |
context: [{ type: "facts" | "transcript" | "string", data: ... }] | context: [{ type: "text" | "transcript" | "facts", ... }] or interactionId | Context input is more flexible in the new API. Classic accepts exactly one context.type per call — facts or transcript or string, never mixed. The Beta surface lets you combine context types in a single context array (e.g. a referral letter as text + a transcript + a few facts items in one call). Alternatively, supply interactionId to pull all non-discarded facts and transcripts attached to that interaction implicitly — no manual context wiring. context and interactionId are mutually exclusive today (combining them is on the roadmap). Note on facts: in the new API each facts item carries one fact (vs. Classic’s data[] array). The documented fact shape requires only text; group is supported as an optional free-form string. See Input context. |
About formatRuleOverride
Classic used formatRuleOverride as a free-text format instruction (e.g. “single paragraph in running text” or “use fixed subheadings: Diagnosis:[content]\n\nAssessment:[content]”). The new API replaces this with typed outputSchema formatting primitives:
array.itemFormat(bullet,numbered,plain, or custom{item})object.fieldFormat— per-field iteration template using generic{key}/{value}placeholders (e.g."{key}: {value}\n"inline,"{key}\n{value}\n"block), or a fully custom layout referencing specific field keys (e.g."{test}: {result}")
- Fork the section with a new
outputSchema(Recipe 2 of the Customization Cookbook). One-time setup; persistent. - Override
outputSchemaat runtime on the guided-synthesis call. Note thatoutputSchemaoverrides are wholesale — you must submit the full schema, not a partial. See Customization Cookbook — override semantics.
formatRuleOverride use cases.
Discovery — resolve Classic keys to UUIDs
Migration starts with a one-time discovery step: for each(key, locale) pair you use in Classic, find the corresponding UUID in the new API.
id, key, languages, regions, specialties and publishedVersion. Build a (key, locale [, region, specialty]) → sectionId map in your service. Do the same for templates via LIST /documents/templates?lang=.... If you want to scope to Corti Standards only, filter the response on source === "corti" client-side.
Step-by-step migration
Inventory your Classic usage
For each
POST /interactions/{id}/documents call in your codebase, note:- which
templateKey(or inlinetemplate.sections[]) you use, - which
outputLanguagevalues you support, - which override fields are populated and whether they’re constant per integration or vary per request,
- any use of
documentationMode,disableGuardrailsor theX-Corti-Retention-Policyheader.
Build the key → UUID map
For every
(Corti Standard key, locale) pair from step 1, call LIST /documents/sections?lang=... and LIST /documents/templates?lang=... (filter on source === "corti" client-side) and persist the mapping in your service. If your Classic integration used region- or specialty-specific variants, also pass region and specialty filters.Pick a path per call site
- If you used
templateKeywith no overrides → Path 1 (plaintemplateRef). - If you used
templateKeywith overrides or inlinetemplate.sections[]that maps cleanly onto an existing template → Path 2 (templateRef+overrides). - If you assembled sections inline at request time (no stored template) → Path 3 (
assemblyTemplate). - If you want to start fully fresh with inline section definitions → Path 4 (
dynamicTemplate). - See Guided Synthesis — the four paths.
Translate the request
Apply the field-mapping table above. The biggest change is moving from
template.sections[].key + *Override to overrides.sections[].sectionId + generation.*. See the side-by-side example below.Update response handling
Classic responses returned a document with
sections[] (each with key, name, text). The new POST /documents response wraps everything in a document object — its templateId, templateVersionId, and document.stringDocument (a {sectionId: renderedString} map — keyed by section UUID, not slug/key) and/or document.structuredDocument, plus a top-level usageInfo.creditsConsumed. See Guided Synthesis — response shape.Decide your interaction story
Classic was always interaction-scoped. The new endpoint is interaction-optional. If you still want facts/transcripts attached to an interaction to flow in implicitly, pass
interactionId. If you’d rather pass everything explicitly, supply a context array. The two are mutually exclusive today — combining them is on the roadmap.Worked example — Classic → new, side by side
The Classic snippet below assembles four sections with overrides on three of them. Compare it to the new equivalent.Before (Classic)
POST /interactions/{id}/documents — Classic
After (new — Path 3 assemblyTemplate)
This Classic call assembled sections inline, so Path 3 is the right target. (If you’d instead been calling a stored template by templateKey, you’d use Path 2.)
formatRuleOverride on corti-assessment and corti-plan does not have a runtime equivalent on its own — for that you’d either supply a full outputSchema in the override (wholesale replacement) or create an inheriting section ahead of time with the desired schema. The example below uses inline outputSchema overrides to keep the migration in one request.
POST /documents — Path 3 (assemblyTemplate)
Behavior notes on the example
- One fact per
contextitem in the new API. Classic packed all facts under a singledata[]; the new shape uses one item withtype: "facts"and a singlefactper item. nameOverride→heading,writingStyleOverride→writingStylePrompt,additionalInstructionsOverride→miscPrompt,contentOverride→contentPrompt— mechanical renames.formatRuleOverriderewrites as anoutputSchema— wholesale replacement of the section’s schema for this call. The example usesfieldFormatto lock the fixed subheadings, and a plainstringschema to force single-paragraph prose.- The response is
document.stringDocument(anddocument.structuredDocumentfor the assessment section because its schema is an object) — not the Classicsections[]array. The wrapping shape is{ document: { ... }, usageInfo: { creditsConsumed } }.
Features being aligned
A handful of Classic features don’t yet have a public equivalent onPOST /documents:
documentationMode: routed_parallel— the Documentation Mode flag.X-Corti-Retention-Policy: noneheader — opt-out of database persistence per request.disableGuardrails— toggle documentation guardrails per request.
Quick reference
Guided Synthesis
Full reference for
POST /documents and the four template-supply paths.Customization Cookbook
Seven recipes from “use Corti Standards as-is” to “your own + customer inheritance + per-call override.”
Section Schemas
Schema patterns that replace Classic
formatRuleOverride and unlock typed outputs.Corti Standards
The library and discovery patterns you’ll use to resolve Classic keys to UUIDs.