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

# Versioning & publishing

> Iterate, version and publish clinical document sections and templates on the Corti API with an explicit draft-then-promote lifecycle — previously published versions stay live until you explicitly publish a new one

<Badge className="accent-badge" shape="rounded">Beta</Badge>

Sections and templates share the same draft-then-promote lifecycle. Every time you change a section's prompts/schema or a template's instructions/composition, you create a new **version**. New versions are **not** published automatically — your previously published version stays live until you explicitly publish a new one. That gives you safe iteration in production: drafts are private to your project until promotion, and consumers continue to see the previously published version.

<Tip>Treat unpublished versions as drafts. You can `GET` the list of versions, inspect each, and only publish once you're confident.</Tip>

***

## Versioning a section

Once a section exists, iterate by creating new versions.

<CodeGroup>
  ```ts title="JavaScript" expandable theme={null}
  // 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" },
    },
  });
  ```

  ```csharp title="C# .NET" expandable theme={null}
  using Corti;

  // Replace these with your values
  const string SectionId = "<your-section-id>";

  var version = await client.Documents.Sections.Versions.CreateAsync(
      SectionId,
      new GuidedSectionsCreateVersionRequest
      {
          Generation = new GuidedSectionGenerationPartial
          {
              Heading = "Clinical Findings",
              Instructions = new GuidedSectionInstructionsPartial
              {
                  ContentPrompt = "Extract all relevant clinical findings, grouped by body system where applicable.",
                  WritingStylePrompt = "Concise, professional, with grouped subheadings when relevant.",
              },
              OutputSchema = new GuidedStringNode(),
          },
      });
  ```

  ```python title="Python" expandable theme={null}
  import requests

  # Replace these with your values
  ENVIRONMENT = "<eu-or-us>"
  SECTION_ID = "<your-section-id>"
  TENANT = "<your-tenant-name>"
  TOKEN = "<your-access-token>"

  response = requests.post(
      f"https://api.{ENVIRONMENT}.corti.app/v2/documents/sections/{SECTION_ID}/versions",
      headers={
          "Authorization": f"Bearer {TOKEN}",
          "Tenant-Name": TENANT,
          "Content-Type": "application/json",
      },
      json={
          "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"},
          },
      },
  )
  response.raise_for_status()
  version = response.json()
  ```

  ```bash title="cURL" expandable theme={null}
  # Replace these with your values
  ENVIRONMENT="<eu-or-us>"
  SECTION_ID="<your-section-id>"
  TENANT="<your-tenant-name>"
  TOKEN="<your-access-token>"

  curl --request POST \
    --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/sections/${SECTION_ID}/versions" \
    --header "Authorization: Bearer ${TOKEN}" \
    --header "Tenant-Name: ${TENANT}" \
    --header "Content-Type: application/json" \
    --data '{
      "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" }
      }
    }'
  ```
</CodeGroup>

The response returns the new version with an auto-incremented `versionNumber`.

<CodeGroup>
  ```ts title="JavaScript" theme={null}
  // 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);
  ```

  ```csharp title="C# .NET" theme={null}
  using Corti;

  // Replace these with your values
  const string SectionId = "<your-section-id>";
  const string VersionId = "<your-version-id>";

  await client.Documents.Sections.Versions.PublishAsync(SectionId, VersionId);
  ```

  ```python title="Python" theme={null}
  import requests

  # Replace these with your values
  ENVIRONMENT = "<eu-or-us>"
  SECTION_ID = "<your-section-id>"
  TENANT = "<your-tenant-name>"
  TOKEN = "<your-access-token>"
  VERSION_ID = "<your-version-id>"

  response = requests.post(
      f"https://api.{ENVIRONMENT}.corti.app/v2/documents/sections/{SECTION_ID}/versions/{VERSION_ID}/publish",
      headers={
          "Authorization": f"Bearer {TOKEN}",
          "Tenant-Name": TENANT,
      },
  )
  response.raise_for_status()
  status = response.json()
  ```

  ```bash title="cURL" theme={null}
  # Replace these with your values
  ENVIRONMENT="<eu-or-us>"
  SECTION_ID="<your-section-id>"
  TENANT="<your-tenant-name>"
  TOKEN="<your-access-token>"
  VERSION_ID="<your-version-id>"

  curl --request POST \
    --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/sections/${SECTION_ID}/versions/${VERSION_ID}/publish" \
    --header "Authorization: Bearer ${TOKEN}" \
    --header "Tenant-Name: ${TENANT}"
  ```
</CodeGroup>

A successful publish returns `{ "status": "published" }` and the section's `publishedVersion` will reflect the new version on subsequent `GET` calls.

***

## Versioning a template

Once a template exists, iterate by creating new versions. The published version stays live until you explicitly publish a new one.

<CodeGroup>
  ```ts title="JavaScript" expandable theme={null}
  // Replace these with your values
  const SECTION_ID_1 = "<your-section-id>";
  const SECTION_ID_2 = "<your-section-id>";
  const SECTION_ID_NEW = "<your-section-id>";
  const TEMPLATE_ID = "<your-template-id>";

  const version = await client.documents.templates.versions.create(TEMPLATE_ID, {
    generation: {
      instructions: {
        prompt: "Produce a structured consultation note. Address the patient in second person.",
      },
      sections: [
        { sectionId: SECTION_ID_1, orderIndex: 0 },
        { sectionId: SECTION_ID_2, orderIndex: 1 },
        { sectionId: SECTION_ID_NEW, orderIndex: 2 },
      ],
    },
  });
  ```

  ```csharp title="C# .NET" expandable theme={null}
  using Corti;

  // Replace these with your values
  const string SectionId1 = "<your-section-id>";
  const string SectionId2 = "<your-section-id>";
  const string SectionIdNew = "<your-section-id>";
  const string TemplateId = "<your-template-id>";

  var version = await client.Documents.Templates.Versions.CreateAsync(
      TemplateId,
      new GuidedTemplatesCreateVersionRequest
      {
          Generation = new GuidedTemplatesVersionGeneration
          {
              Instructions = new GuidedTemplateInstructionsPartial
              {
                  Prompt = "Produce a structured consultation note. Address the patient in second person.",
              },
              Sections = new[]
              {
                  new GuidedTemplatesVersionSectionRequest { SectionId = SectionId1, OrderIndex = 0 },
                  new GuidedTemplatesVersionSectionRequest { SectionId = SectionId2, OrderIndex = 1 },
                  new GuidedTemplatesVersionSectionRequest { SectionId = SectionIdNew, OrderIndex = 2 },
              },
          },
      });
  ```

  ```python title="Python" expandable theme={null}
  import requests

  # Replace these with your values
  ENVIRONMENT = "<eu-or-us>"
  SECTION_ID_1 = "<your-section-id>"
  SECTION_ID_2 = "<your-section-id>"
  SECTION_ID_NEW = "<your-section-id>"
  TEMPLATE_ID = "<your-template-id>"
  TENANT = "<your-tenant-name>"
  TOKEN = "<your-access-token>"

  response = requests.post(
      f"https://api.{ENVIRONMENT}.corti.app/v2/documents/templates/{TEMPLATE_ID}/versions",
      headers={
          "Authorization": f"Bearer {TOKEN}",
          "Tenant-Name": TENANT,
          "Content-Type": "application/json",
      },
      json={
          "generation": {
              "instructions": {
                  "prompt": "Produce a structured consultation note. Address the patient in second person.",
              },
              "sections": [
                  {"sectionId": SECTION_ID_1, "orderIndex": 0},
                  {"sectionId": SECTION_ID_2, "orderIndex": 1},
                  {"sectionId": SECTION_ID_NEW, "orderIndex": 2},
              ],
          },
      },
  )
  response.raise_for_status()
  version = response.json()
  ```

  ```bash title="cURL" expandable theme={null}
  # Replace these with your values
  ENVIRONMENT="<eu-or-us>"
  SECTION_ID_1="<your-section-id>"
  SECTION_ID_2="<your-section-id>"
  SECTION_ID_NEW="<your-section-id>"
  TEMPLATE_ID="<your-template-id>"
  TENANT="<your-tenant-name>"
  TOKEN="<your-access-token>"

  curl --request POST \
    --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/templates/${TEMPLATE_ID}/versions" \
    --header "Authorization: Bearer ${TOKEN}" \
    --header "Tenant-Name: ${TENANT}" \
    --header "Content-Type: application/json" \
    --data "{
      \"generation\": {
        \"instructions\": {
          \"prompt\": \"Produce a structured consultation note. Address the patient in second person.\"
        },
        \"sections\": [
          { \"sectionId\": \"${SECTION_ID_1}\", \"orderIndex\": 0 },
          { \"sectionId\": \"${SECTION_ID_2}\", \"orderIndex\": 1 },
          { \"sectionId\": \"${SECTION_ID_NEW}\", \"orderIndex\": 2 }
        ]
      }
    }"
  ```
</CodeGroup>

<CodeGroup>
  ```ts title="JavaScript" theme={null}
  // Replace these with your values
  const TEMPLATE_ID = "<your-template-id>";
  const VERSION_ID = "<your-version-id>";

  await client.documents.templates.versions.publish(TEMPLATE_ID, VERSION_ID);
  ```

  ```csharp title="C# .NET" theme={null}
  using Corti;

  // Replace these with your values
  const string TemplateId = "<your-template-id>";
  const string VersionId = "<your-version-id>";

  await client.Documents.Templates.Versions.PublishAsync(TemplateId, VersionId);
  ```

  ```python title="Python" theme={null}
  import requests

  # Replace these with your values
  ENVIRONMENT = "<eu-or-us>"
  TEMPLATE_ID = "<your-template-id>"
  TENANT = "<your-tenant-name>"
  TOKEN = "<your-access-token>"
  VERSION_ID = "<your-version-id>"

  response = requests.post(
      f"https://api.{ENVIRONMENT}.corti.app/v2/documents/templates/{TEMPLATE_ID}/versions/{VERSION_ID}/publish",
      headers={
          "Authorization": f"Bearer {TOKEN}",
          "Tenant-Name": TENANT,
      },
  )
  response.raise_for_status()
  status = response.json()
  ```

  ```bash title="cURL" theme={null}
  # Replace these with your values
  ENVIRONMENT="<eu-or-us>"
  TEMPLATE_ID="<your-template-id>"
  TENANT="<your-tenant-name>"
  TOKEN="<your-access-token>"
  VERSION_ID="<your-version-id>"

  curl --request POST \
    --url "https://api.${ENVIRONMENT}.corti.app/v2/documents/templates/${TEMPLATE_ID}/versions/${VERSION_ID}/publish" \
    --header "Authorization: Bearer ${TOKEN}" \
    --header "Tenant-Name: ${TENANT}"
  ```
</CodeGroup>

A successful publish returns `{ "status": "published" }` and subsequent `GET /documents/templates/{templateID}` reflects the new `publishedVersion`.

<Note>Publishing a template version validates that every referenced section has a published version. Fix any unpublished sections before retrying the publish.</Note>
