Overview
Corti document templates are built from sections, each carrying its own heading, prompts, and output schema. The customization surface lets you change how any section behaves — without rebuilding templates from scratch.
Customization works through three levers:
Lever | Where | Persistence | Use when |
1. Use as-is | Reference a section or template by its UUID | n/a | The resource already does what you need |
2. Inherit |
| Persistent, versioned — and it keeps tracking Corti's improvements on fields you didn't override | The same customization applies to every call (e.g. per organization, customer, or specialty) |
3. Runtime overrides |
| Ephemeral — the request is snapshotted for traceability, but the base resource is untouched | The customization varies between calls (e.g. per user, per encounter) |
💡 Rule of thumb: if the same tweak applies to every call from this customer, create an inheriting resource. If it varies call to call, override at runtime.
The Override Fields
Whether you inherit persistently or override at runtime, the fields are the same:
Field | Purpose |
| Override the section heading (title), e.g. Subjective → Anamnesis |
| Guides what input content belongs in the section |
| Guides tone and style (e.g. telegraphic, plain language) |
| Free-form additional instructions |
| Controls the section's output shape and rendering — typed, not free text |
⚠️ Coming from the previous (Classic) system? The override fields map directly to their new equivalents — see the migration guide on docs.corti.ai for the full mapping.
Classic field | New equivalent |
|
|
|
|
|
|
|
|
|
|
Merge Rules — Important
Overrides obey different merge rules per field, wherever you apply them:
instructionsis per-field partial — any prompt field you omit is inherited from the parent.outputSchemais wholesale — your schema fully replaces the parent's schema. Partial schemas are not merged.Runtime overrides can only patch sections already in the template — to add, remove, or reorder sections, use an assembly request (Path 3) instead.
Best Practices
1. Pick the Right Lever
Don't send the same override on every call forever — that's what inheritance is for. Persisting a customization as an inheriting section or template makes it versioned, publishable, and governed; runtime overrides are for genuine per-call variation.
2. Prevent Contradictions in Your Prompts
❌ Conflicting instructions
contentPrompt: "Include detailed lab results"
miscPrompt: "Do not include lab values"
✅ Best practice — ensure all override fields reinforce the same instruction set. Think of them as layers: content guidance → style guidance → detailed generation instructions. When these align, the model performs significantly better.
3. Use the Right Field for the Right Instruction
A common mistake is packing style, formatting, and content instructions all into miscPrompt.
❌ Not recommended — everything crammed into one field:
miscPrompt: "Write in a friendly tone, use numbered steps, avoid jargon, include medications, and format the output clearly."
✅ Recommended — one responsibility per field:
contentPrompt: "Include medications, dosage instructions, and home care tasks."
writingStylePrompt: "Plain language, numbered steps, action-oriented."
miscPrompt: "Provide instructions the pet owner can follow at home."
Separating responsibilities between fields improves clarity and model performance. The same applies inside an outputSchema: use the section's contentPrompt for overall scope, and each field's description for field-specific rules — descriptions are part of the prompt the model sees, not just metadata.
4. Be Explicit in Your Instructions
Be direct. The model performs best when instructions clearly define what to include, what to exclude, the desired tone, and the expected format.
❌ Vague: "Write a summary of the visit"
✅ Explicit: "Include the presenting complaint, symptom duration, and relevant history. Exclude lab values and technical medical terminology. Write 2–3 sentences in plain language suitable for a pet owner."
5. Use Output Schemas Instead of Free-Text Formatting Instructions
Instead of pleading for a format in prose, declare it in the outputSchema — it's typed, enforced, and unlocks structured output. Common patterns:
You want | Schema |
Running paragraph |
|
Bullet points |
|
Fixed subheadings |
|
One value from a closed set |
|
Remember: outputSchema overrides are wholesale — submit the full schema, not a partial patch.
6. Control the Empty State
When the source material has nothing relevant for a section, don't leave the output to chance:
Set
defaulton string/number/boolean nodes (e.g."Not discussed","Nil")Set
fallbackStringon array/object schemas for a meaningful placeholder instead of an empty string
This keeps the document's structure stable for downstream consumers.
Worked Example: Custom SOAP + Client Summary
A Corti team member built a demo app for veterinary use: one SOAP note for the clinic, and one client-facing summary generated from the same SOAP building blocks — with sections re-tuned for pet owners.
The SOAP note needs no customization — just reference the stored SOAP template (Path 1):
{
"outputLanguage": "en-US",
"interactionId": "<your-interaction-id>",
"templateRef": { "templateId": "<soap-template-id>" }
}The client summary assembles three standard sections (resolved via LIST /documents/sections?lang=en, e.g. label family:corti-subjective) and overrides each (Path 3):
{
"outputLanguage": "en-US",
"interactionId": "<your-interaction-id>",
"assemblyTemplate": {
"name": "Client summary",
"sectionRefs": [
{
"sectionId": "<subjective-section-id>",
"overrides": {
"heading": "Visit Overview",
"instructions": {
"contentPrompt": "Include: reason for visit, presenting complaint, relevant history, patient signalment. Exclude: detailed physical exam findings, lab values, technical medical terms.",
"writingStylePrompt": "Warm, clear, plain language suitable for pet owners. Avoid medical jargon.",
"miscPrompt": "Write a brief, friendly summary of why the pet was brought in today. IMPORTANT: Use ONLY the facts provided. Do NOT invent or assume symptoms. 2-3 sentences."
}
}
},
{
"sectionId": "<assessment-section-id>",
"overrides": {
"heading": "What We Found",
"instructions": {
"contentPrompt": "Include: diagnosis or working diagnosis, key exam findings explained simply, test results in plain language.",
"writingStylePrompt": "Reassuring, clear, plain language for pet owners"
}
}
},
{
"sectionId": "<plan-section-id>",
"overrides": {
"heading": "Care Instructions",
"instructions": {
"contentPrompt": "Include: medications with simple dosing instructions, home care tasks, dietary changes, activity restrictions.",
"writingStylePrompt": "Action-oriented, numbered steps, plain language"
}
}
}
]
}
}Why This Example Works Well
The sections align with clinical structure — Subjective → visit overview, Assessment → findings, Plan → care instructions. Clinical reasoning stays intact; only the output is adapted for a non-clinical audience.
Each override field serves one purpose — heading for the title,
contentPromptfor what belongs (and what doesn't),writingStylePromptfor audience and tone,miscPromptfor behavioral constraints (factual grounding, length).The instructions are explicit — include/exclude lists, audience, length. Clear constraints produce consistent documents.
Summary
When designing customizations:
✔ Pick the right lever — inherit for recurring, override at runtime for per-call
✔ Avoid contradictory instructions
✔ Use each field for its intended purpose
✔ Be explicit about what to include and exclude
✔ Prefer typed outputSchema over free-text formatting instructions
✔ Control empty states with default / fallbackString
✔ Store and reuse recurring customizations as inheriting resources
