> ## Documentation Index
> Fetch the complete documentation index at: https://www.courier.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish a journey

> Publish the current draft as a new version. Body is optional; pass `{ "version": "vN" }` to roll back to a prior version instead. Returns 404 if the journey has no draft to publish.



## OpenAPI

````yaml /openapi-specs/openapi.documented.yml post /journeys/{templateId}/publish
openapi: 3.0.1
info:
  title: Courier
  description: The Courier REST API.
  version: 0.0.1
servers:
  - url: https://api.courier.com
    description: Production
security: []
paths:
  /journeys/{templateId}/publish:
    post:
      tags:
        - Journeys
      summary: Publish a journey
      description: >-
        Publish the current draft as a new version. Body is optional; pass `{
        "version": "vN" }` to roll back to a prior version instead. Returns 404
        if the journey has no draft to publish.
      operationId: journeys_publish
      parameters:
        - in: path
          name: templateId
          schema:
            type: string
            minLength: 1
          required: true
          description: Journey id
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JourneyPublishRequest'
            examples:
              Example1:
                summary: Publish draft
                value: {}
      responses:
        '200':
          description: Published journey
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyResponse'
              examples:
                Example1:
                  summary: Published journey
                  value:
                    id: abc-123
                    name: Welcome Journey
                    state: PUBLISHED
                    enabled: true
                    nodes: []
                    created: 1715000000000
                    creator: user-1
                    updated: 1715000300000
                    updater: user-1
                    published: 1715000400000
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
        '422':
          description: Unprocessable entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableEntity'
      security:
        - BearerAuth: []
      x-codeSamples:
        - lang: JavaScript
          source: |-
            import Courier from '@trycourier/courier';

            const client = new Courier({
              apiKey: process.env['COURIER_API_KEY'], // This is the default and can be omitted
            });

            const journeyResponse = await client.journeys.publish('x');

            console.log(journeyResponse.id);
        - lang: Python
          source: |-
            import os
            from courier import Courier

            client = Courier(
                api_key=os.environ.get("COURIER_API_KEY"),  # This is the default and can be omitted
            )
            journey_response = client.journeys.publish(
                template_id="x",
            )
            print(journey_response.id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/trycourier/courier-go\"\n\t\"github.com/trycourier/courier-go/option\"\n)\n\nfunc main() {\n\tclient := courier.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tjourneyResponse, err := client.Journeys.Publish(\n\t\tcontext.TODO(),\n\t\t\"x\",\n\t\tcourier.JourneyPublishParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", journeyResponse.ID)\n}\n"
        - lang: Java
          source: |-
            package com.courier.example;

            import com.courier.client.CourierClient;
            import com.courier.client.okhttp.CourierOkHttpClient;
            import com.courier.models.journeys.JourneyPublishParams;
            import com.courier.models.journeys.JourneyResponse;

            public final class Main {
                private Main() {}

                public static void main(String[] args) {
                    CourierClient client = CourierOkHttpClient.fromEnv();

                    JourneyResponse journeyResponse = client.journeys().publish("x");
                }
            }
        - lang: Ruby
          source: |-
            require "courier"

            courier = Courier::Client.new(api_key: "My API Key")

            journey_response = courier.journeys.publish("x")

            puts(journey_response)
        - lang: PHP
          source: >-
            <?php


            require_once dirname(__DIR__) . '/vendor/autoload.php';


            use Courier\Client;

            use Courier\Core\Exceptions\APIException;


            $client = new Client(apiKey: getenv('COURIER_API_KEY') ?: 'My API
            Key');


            try {
              $journeyResponse = $client->journeys->publish('x', version: 'v321669910225');

              var_dump($journeyResponse);
            } catch (APIException $e) {
              echo $e->getMessage();
            }
        - lang: C#
          source: |-
            using System;
            using Courier;
            using Courier.Models.Journeys;

            CourierClient client = new();

            JourneyPublishParams parameters = new() { TemplateID = "x" };

            var journeyResponse = await client.Journeys.Publish(parameters);

            Console.WriteLine(journeyResponse);
        - lang: CLI
          source: |-
            courier journeys publish \
              --api-key 'My API Key' \
              --template-id x
components:
  schemas:
    JourneyPublishRequest:
      description: >-
        Request body for publishing a journey. Pass `version` to roll back to a
        prior version; omit to publish the current draft.
      type: object
      properties:
        version:
          type: string
          pattern: ^v\d+$
    JourneyResponse:
      description: A journey, with its current draft or published nodes and metadata.
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        state:
          $ref: '#/components/schemas/JourneyState'
        enabled:
          type: boolean
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/JourneyNode'
        created:
          nullable: true
          type: integer
          format: int64
        creator:
          type: string
          nullable: true
        updated:
          nullable: true
          type: integer
          format: int64
        updater:
          type: string
          nullable: true
        published:
          nullable: true
          type: integer
          format: int64
      required:
        - id
        - name
        - state
        - enabled
        - nodes
        - created
        - creator
        - updated
        - updater
        - published
    BadRequest:
      title: BadRequest
      type: object
      properties:
        type:
          type: string
          enum:
            - invalid_request_error
      required:
        - type
      allOf:
        - $ref: '#/components/schemas/BaseError'
    NotFound:
      title: NotFound
      type: object
      properties:
        type:
          type: string
          enum:
            - invalid_request_error
      required:
        - type
      allOf:
        - $ref: '#/components/schemas/BaseError'
    UnprocessableEntity:
      title: UnprocessableEntity
      type: object
      properties:
        type:
          type: string
          enum:
            - invalid_request_error
      required:
        - type
      allOf:
        - $ref: '#/components/schemas/BaseError'
    JourneyState:
      description: Lifecycle state of a journey.
      type: string
      enum:
        - DRAFT
        - PUBLISHED
    JourneyNode:
      description: >-
        A single node in a journey DAG. Discriminated by `type`, with a
        secondary discriminator on some variants (`trigger_type` for trigger,
        `mode` for delay, `method` for fetch, `scope` for throttle).
      oneOf:
        - $ref: '#/components/schemas/JourneyApiInvokeTriggerNode'
        - $ref: '#/components/schemas/JourneySegmentTriggerNode'
        - $ref: '#/components/schemas/JourneySendNode'
        - $ref: '#/components/schemas/JourneyDelayDurationNode'
        - $ref: '#/components/schemas/JourneyDelayUntilNode'
        - $ref: '#/components/schemas/JourneyFetchGetDeleteNode'
        - $ref: '#/components/schemas/JourneyFetchPostPutNode'
        - $ref: '#/components/schemas/JourneyAINode'
        - $ref: '#/components/schemas/JourneyThrottleStaticNode'
        - $ref: '#/components/schemas/JourneyThrottleDynamicNode'
        - $ref: '#/components/schemas/JourneyBatchNode'
        - $ref: '#/components/schemas/JourneyExitNode'
        - type: object
          title: JourneyBranchNode
          description: >-
            Branch node. Routes to the first entry in `paths[]` whose
            `conditions` match, else falls through to `default.nodes`.
          properties:
            id:
              type: string
              minLength: 1
            type:
              type: string
              enum:
                - branch
            paths:
              type: array
              minItems: 1
              items:
                type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                  conditions:
                    $ref: '#/components/schemas/JourneyConditionsField'
                  nodes:
                    type: array
                    items:
                      $ref: '#/components/schemas/JourneyNode'
                required:
                  - conditions
                  - nodes
            default:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                nodes:
                  type: array
                  items:
                    $ref: '#/components/schemas/JourneyNode'
              required:
                - nodes
          required:
            - type
            - paths
            - default
    BaseError:
      title: BaseError
      type: object
      properties:
        message:
          type: string
          description: A message describing the error that occurred.
      required:
        - message
    JourneyApiInvokeTriggerNode:
      title: API Invoke Trigger
      description: >-
        Trigger fired when the journey is invoked via the API. The optional
        `schema` field is a JSON Schema that validates the invocation payload.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - trigger
        trigger_type:
          type: string
          enum:
            - api-invoke
        schema:
          type: object
          additionalProperties: true
          description: >-
            A JSONSchema object (Draft-07-compatible). Validated at runtime by
            Ajv.
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - trigger_type
    JourneySegmentTriggerNode:
      title: Segment Trigger
      description: Trigger fired by a segment event (`identify`, `group`, or `track`).
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - trigger
        trigger_type:
          type: string
          enum:
            - segment
        request_type:
          type: string
          enum:
            - identify
            - group
            - track
        event_id:
          type: string
          minLength: 1
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - trigger_type
        - request_type
    JourneySendNode:
      title: Send
      description: >-
        Send a notification template to the recipient. Optionally override the
        recipient address, delay the send, or attach `data`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - send
        message:
          type: object
          properties:
            template:
              type: string
              minLength: 1
            to:
              type: object
              properties:
                email_override:
                  type: string
                  minLength: 1
                phone_number_override:
                  type: string
                  minLength: 1
                user_id_override:
                  type: string
                  minLength: 1
            delay:
              type: object
              properties:
                until:
                  type: string
                  minLength: 1
                timezone:
                  type: string
                  minLength: 1
              required:
                - until
            data:
              type: object
              additionalProperties: true
          required:
            - template
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - message
    JourneyDelayDurationNode:
      title: Delay for Duration
      description: Pause the journey run for a fixed `duration`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - delay
        mode:
          type: string
          enum:
            - duration
        duration:
          type: string
          minLength: 1
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - mode
        - duration
    JourneyDelayUntilNode:
      title: Delay Until
      description: Pause the journey run `until` a specific time.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - delay
        mode:
          type: string
          enum:
            - until
        until:
          type: string
          minLength: 1
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - mode
        - until
    JourneyFetchGetDeleteNode:
      title: Fetch (GET/DELETE)
      description: >-
        Issue an HTTP GET or DELETE request and merge the response into the
        journey state per `merge_strategy`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - fetch
        method:
          type: string
          enum:
            - get
            - delete
        url:
          type: string
          minLength: 1
        merge_strategy:
          $ref: '#/components/schemas/JourneyMergeStrategy'
        headers:
          type: object
          additionalProperties:
            type: string
        query_params:
          type: object
          additionalProperties:
            type: string
        response_schema:
          type: object
          additionalProperties: true
          description: >-
            A JSONSchema object (Draft-07-compatible). Validated at runtime by
            Ajv.
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - method
        - url
        - merge_strategy
    JourneyFetchPostPutNode:
      title: Fetch (POST/PUT)
      description: >-
        Issue an HTTP POST or PUT request with a `body` and merge the response
        into the journey state per `merge_strategy`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - fetch
        method:
          type: string
          enum:
            - post
            - put
        url:
          type: string
          minLength: 1
        merge_strategy:
          $ref: '#/components/schemas/JourneyMergeStrategy'
        headers:
          type: object
          additionalProperties:
            type: string
        query_params:
          type: object
          additionalProperties:
            type: string
        response_schema:
          type: object
          additionalProperties: true
          description: >-
            A JSONSchema object (Draft-07-compatible). Validated at runtime by
            Ajv.
        body:
          type: string
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - method
        - url
        - merge_strategy
    JourneyAINode:
      title: AI
      description: >-
        Invoke an AI step with `user_prompt` and optional `web_search`. Returns
        a structured response conforming to `output_schema`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - ai
        model:
          type: string
          minLength: 1
        user_prompt:
          type: string
        web_search:
          type: boolean
        output_schema:
          type: object
          additionalProperties: true
          description: >-
            A JSONSchema object (Draft-07-compatible). Validated at runtime by
            Ajv.
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - output_schema
    JourneyThrottleStaticNode:
      title: Throttle (Static)
      description: >-
        Throttle the journey by a static `scope` (`user` or `global`), allowing
        at most `max_allowed` invocations per `period`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - throttle
        scope:
          type: string
          enum:
            - user
            - global
        max_allowed:
          type: integer
          minimum: 1
        period:
          type: string
          minLength: 1
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - scope
        - max_allowed
        - period
    JourneyThrottleDynamicNode:
      title: Throttle (Dynamic)
      description: >-
        Throttle the journey by a dynamic `throttle_key`, allowing at most
        `max_allowed` invocations per `period`.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - throttle
        scope:
          type: string
          enum:
            - dynamic
        max_allowed:
          type: integer
          minimum: 1
        period:
          type: string
          minLength: 1
        throttle_key:
          type: string
          minLength: 1
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - scope
        - max_allowed
        - period
        - throttle_key
    JourneyBatchNode:
      title: Batch
      description: >-
        Collect events arriving at the node into a single batch and fire one
        downstream step with the aggregated payload. The first event into a
        batch owns the run; later contributing events terminate at the batch
        step. The batch releases when any of `max_items` is reached, a quiet
        window of `wait_period` elapses, or the `max_wait_period` ceiling hits.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - batch
        scope:
          type: string
          enum:
            - user
        wait_period:
          type: string
          minLength: 1
          description: >-
            ISO 8601 duration. Quiet window that releases the batch when it
            elapses with no new contributing events. Must be less than
            `max_wait_period`.
        max_wait_period:
          type: string
          minLength: 1
          description: >-
            ISO 8601 duration. Hard ceiling from the first event into the batch;
            releases the batch unconditionally when it elapses.
        max_items:
          type: integer
          default: 100
          minimum: 1
          maximum: 1000
          description: Releases the batch once this many events have been collected.
        retain:
          type: object
          description: >-
            How to select which collected events to retain in the aggregated
            payload when the batch releases.
          properties:
            type:
              type: string
              enum:
                - first
                - last
                - highest
                - lowest
            count:
              type: integer
              minimum: 0
              maximum: 25
            sort_key:
              type: string
              minLength: 1
              description: >-
                Dot-path into the event payload (e.g. `data.priority`). Required
                when `type` is `highest` or `lowest`.
          required:
            - type
            - count
        category_key:
          type: string
          minLength: 1
          maxLength: 256
          description: >-
            Optional partition key. Events with the same `category_key` are
            batched together; events with different values are batched
            separately.
        conditions:
          $ref: '#/components/schemas/JourneyConditionsField'
      required:
        - type
        - scope
        - wait_period
        - max_wait_period
        - retain
    JourneyExitNode:
      title: Exit
      description: Terminate the journey run.
      type: object
      properties:
        id:
          type: string
          minLength: 1
        type:
          type: string
          enum:
            - exit
      required:
        - type
    JourneyConditionsField:
      description: >-
        Condition spec for a journey node. Accepts a single condition atom, an
        AND/OR group, or an AND/OR nested group. Omit the `conditions` property
        entirely to express "no conditions".
      anyOf:
        - $ref: '#/components/schemas/JourneyConditionAtom'
        - $ref: '#/components/schemas/JourneyConditionGroup'
        - $ref: '#/components/schemas/JourneyConditionNestedGroup'
    JourneyMergeStrategy:
      description: Strategy for merging a fetch response into the journey run state.
      type: string
      enum:
        - overwrite
        - soft-merge
        - replace
        - none
    JourneyConditionAtom:
      title: Single condition
      description: >-
        A single condition expressed as a positional tuple of strings.

        - Binary form (3 elements): `[path, operator, value]` where `operator`
          is one of `is equal`, `is not equal`, `contains`, `does not contain`,
          `starts with`, `ends with`, `greater than`, `greater than or equal`,
          `less than`, `less than or equal`.

          Example: `["user.tier", "is equal", "gold"]`.

        - Unary form (2 elements): `[path, operator]` where `operator` is
          one of `exists`, `does not exist`.

          Example: `["user.email", "exists"]`.

        The first element is a non-empty dot-path. The second element is the
        operator (must come from one of the two operator sets above). For the
        binary form, the third element is the comparison value (string). Runtime
        validation of the operator value and arity is performed by the backend;
        SDKs surface this as a string list.
      type: array
      minItems: 2
      maxItems: 3
      items:
        type: string
    JourneyConditionGroup:
      title: Condition group
      type: object
      description: >-
        A leaf condition group. Exactly one of `AND` or `OR` must be present at
        runtime; each is a list of `JourneyConditionAtom` tuples.
      properties:
        AND:
          type: array
          minItems: 2
          items:
            $ref: '#/components/schemas/JourneyConditionAtom'
        OR:
          type: array
          minItems: 2
          items:
            $ref: '#/components/schemas/JourneyConditionAtom'
    JourneyConditionNestedGroup:
      title: Nested condition group
      type: object
      description: >-
        A nested condition group. Exactly one of `AND` or `OR` must be present
        at runtime; each is a list of `JourneyConditionGroup` items.
      properties:
        AND:
          type: array
          minItems: 2
          items:
            $ref: '#/components/schemas/JourneyConditionGroup'
        OR:
          type: array
          minItems: 2
          items:
            $ref: '#/components/schemas/JourneyConditionGroup'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

````