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
POST /documents endpoint is available in beta. Feedback welcome at help@corti.ai or via your Corti contact.What is guided synthesis?
Guided synthesis is a single endpoint,POST /documents, that generates a structured document from one of four template-supply paths. Where the classic generation flow requires an interaction and a templateKey, guided synthesis is interaction-optional and consumes the new Sections & Templates authoring API directly — or accepts a fully inline template you’ve never persisted.
It is designed for the following needs:
- Repeatable, governed generation — reference a stored, versioned template by UUID.
- Light-touch overrides — keep your base template, but patch a section’s title, instructions or output schema for a single call.
- Compose at runtime — pick stored sections out of your library and assemble them on the fly.
- Try something new — define everything inline without saving anything first.
templateId and templateVersionId that were used.
The four template-supply paths
You pick one path per call. The four behave differently with respect to whether a new template aggregate is persisted as a side-effect of the call.| Path | Top-level field | Resolves to | Persists a new template? |
|---|---|---|---|
1. Plain templateRef | templateRef (no overrides) | Stored template’s published (or pinned) version | No — the referenced template is used as-is |
2. templateRef + overrides | templateRef.overrides | Stored template with runtime patches | Yes — a new auto-generated template aggregate is saved with inheritedFromId pointing at the base |
| 3. Assembly from stored sections | assemblyTemplate | A new template built from referenced section IDs in declaration order | Yes — auto-generated template aggregate is persisted |
| 4. Fully inline dynamic template | dynamicTemplate | Sections and template defined inline in the request body | Yes — sections and template are persisted as auto-generated resources, immediately published |
Drift-proof snapshots. For every path except plain
templateRef, the auto-generated template aggregate snapshots the fully resolved content at request time. Subsequent edits to base templates or sections do not affect previously generated documents. You can also reuse that auto-generated template in future calls by reading its ID from the response.Path 1 — Plain templateRef
Reference a stored template by UUID. No overrides, no side-effects. The lightest path for production traffic.
Path 2 — templateRef + overrides
Keep your base template, patch instructions / heading / schema for a single call. Auto-generates a drift-proof aggregate.
Path 3 — assemblyTemplate
Build a template on the fly from existing stored sections. Useful for EHR-field-driven note composition.
Path 4 — dynamicTemplate
Define the template and every section inline. Ideal for prototyping and one-off generations.
Input context
Every call needs to tell the model what to reason over. Supply exactly one of:context— an ordered array of explicit context items. Each item is one of three discriminated types (see below).interactionId— when supplied, all non-discarded facts and transcripts already attached to the referenced interaction are passed implicitly as input context.
context and interactionId are currently mutually exclusive — supply one or the other, never both. Combining them to extend the implicit interaction context with extra explicit items is on the roadmap; see the release notes for status.Context item types
type | Required field | Use when |
|---|---|---|
text | text (string) | Pasting a referral letter, dictation, EHR field, or any free-form snippet |
transcript | transcript (minimal shape — transcripts[] of segments, optional metadata.participantsRoles) | Feeding a conversation transcript directly without going through /streams |
facts | fact.text (string, required); fact.group (string, optional) | Passing a single fact derived elsewhere (one fact per item — repeat the item to pass many). group is optional metadata you can carry over (e.g. "history-of-present-illness", "allergies") when migrating from Classic facts or grouping facts by category. |
Mixed context array
Common request shape
All four paths share three top-level fields and differ only in which template-supply field they carry:Shared shape
outputLanguage is required and uses a BCP-47 tag.
Auto-generated template aggregates — 30-day retention
Paths 2, 3 and 4 persist an auto-generated template aggregate as a side-effect of generation — a drift-proof snapshot of the resolved template + sections that were actually used. Path 1 (plaintemplateRef) is the exception: it uses the referenced template as-is and persists nothing new.
Response shape
All four paths return the same response shape: adocument object plus a usageInfo block. When the request uses the default retention policy, the document is also persisted with its own id, createdAt and updatedAt. With X-Corti-Retention-Policy: none, the response is the ephemeral variant — the same document body without the persisted-resource fields.
Response (default retention)
The keys in
stringDocument (and structuredDocument) are section UUIDs, not slugs or section keys. The slug-looking placeholders above stand in for the actual UUIDs. See Mapping response section IDs back to your sections below for how to correlate them to the sections in your request.document.id— the persisted document UUID. Only present on the default-retention response; omitted when the request setsX-Corti-Retention-Policy: none.document.templateId/document.templateVersionId— the template (and version) that was actually used. For Path 1 this is the referenced template; for Paths 2–4 it is the newly persisted auto-generated aggregate. Store these if you want full traceability of what produced each document.document.stringDocument— an object keyed by section ID containing the rendered string output for each section. Always present.document.structuredDocument— present when one or more sections use a non-stringoutputSchema(object, array, etc.). Keyed by section ID; each entry holds the structured object/array as the schema declared.usageInfo.creditsConsumed— credits consumed for this request. Same shape as every other Corti endpoint that returns usage information.
Mapping response section IDs back to your sections
BothstringDocument and structuredDocument are keyed by section ID. For Path 1 (plain templateRef) and Path 2 (templateRef + overrides) those IDs match the sections of the referenced template — you can map them straight back. For Path 3 (assemblyTemplate) and Path 4 (dynamicTemplate) the keys are IDs Corti generates for the auto-saved aggregate. Path 3 carries explicit sectionRefs[].sectionId you can correlate by, but Path 4 is the gotcha: your request supplies an ordered list of SectionGeneration objects with no IDs of your own, so the response keys arrive as opaque server-side IDs with no obvious mapping back to your inline section definitions — meaning you can’t reliably attach the right heading to each rendered section just from the response.
Workaround until this is improved. Use the returned templateVersionId to read the saved aggregate:
sections[] array preserves your request order and carries the resolved section IDs. Build a position → sectionId → heading mapping from that response, then key the rendered output against it.
This is a known DX gap for Path 4 specifically. The roadmap includes returning client-supplied identifiers (or section ordering) directly on the response so the follow-up GET isn’t needed.
When to use which path
- Production ambient flow
- Per-user customization
- EHR-field-driven note
- Prototype / experimental
Use Path 1 (plain
templateRef) with a pinned templateVersionId for reproducibility. No side-effects, fastest path, easiest to audit.Errors and validation
| Status | When it happens |
|---|---|
400 Bad Request | Request body fails basic validation (e.g. missing outputLanguage, malformed JSON). |
404 Not Found | A referenced templateId, templateVersionId or sectionId does not exist. |
422 Unprocessable Entity | Request is structurally valid but semantically rejected — e.g. none of templateRef/assemblyTemplate/dynamicTemplate supplied, the referenced template has no published version, an override targets a section not linked to the base template version, or you supplied more than one of the three. |
502 Bad Gateway | Document generation failed downstream. |
Provide exactly one of
templateRef, assemblyTemplate, dynamicTemplate. Supplying zero or more than one yields a 422.How guided synthesis relates to other endpoints
- It is separate from
POST /interactions/{id}/documents(Documents Classic). The classic endpoint continues to work and is the right choice if you’re still usingtemplateKey-based generation. See Standard Document Generation. - It consumes the new resources authored via the Sections and Templates APIs.
- The
outputSchemareference is shared with section authoring — see the section-creation guide.
Next steps
Create a Section
Author and version the sections you’ll reference in Paths 1–3.
Create a Template
Compose sections into versioned templates ready for Path 1.
Corti Standards
Reference the Corti-curated section and template library from any of the four paths.
Migrate from Classic
Field-by-field mapping from
POST /interactions/{id}/documents to POST /documents.