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

# Create or update a workflow

> Create a new workflow or update an existing one. If an `id` is provided in the request body, the workflow will be updated; otherwise, a new workflow will be created.



## OpenAPI

````yaml /openapi/openapi.yaml post /bots/{botId}/workflows
openapi: 3.0.3
info:
  title: Annie API
  description: >
    ### Overview


    The Annie API is a (mostly) RESTful API. Typically, both POST bodies and
    responses are JSON-encoded.


    Note: The documenation is Work In Progress and is subject to change.


    ### Base URL


    The base URL for the Annie API is https://api.helloannie.com/.


    Examples in this document may abbreviate this to `/`.


    ### Versioning


    Routes are prefixed with a version number i.e. `v1`. The version will change
    when there is a non-backwards compatible or other significant change to the
    api.


    ### Authentication


    The Annie API supports two authentication methods API Keys and OAuth Access
    Tokens:


    #### API Keys


    API Keys are long-lived tokens that can be generated from the Developer
    Portal on your organization page. API keys are prefixed with `annie-sk-v2-`
    and can be used directly in the `Authorization` header.


    ```

    curl -H "Authorization: Bearer annie-sk-xxxxx"
    https://api.helloannie.com/...

    ```


    #### OAuth Tokens


    OAuth tokens are short-lived access tokens generated using the OAuth 2.0
    Client Credentials flow (Machine-to-Machine). OAuth clients provide scoped
    permissions and are ideal for server-to-server integrations.


    **Creating an OAuth Client**


    OAuth clients can be created in the Developer Portal on your organization
    page. When creating a client, you'll receive:


    - `client_id`: Your OAuth client identifier

    - `client_secret`: Your OAuth client secret (store this securely)


    **Generating an OAuth Token**


    To generate an OAuth access token, make a POST request to the Annie OAuth
    token endpoint:


    **Endpoint:** `https://annie-external-api.us.auth0.com/oauth/token`


    **Example Request:**


    ```bash

    curl -X POST https://annie-external-api.us.auth0.com/oauth/token \
      -H "Content-Type: application/json" \
      -d '{
        "grant_type": "client_credentials",
        "client_id": "your-client-id",
        "client_secret": "your-client-secret",
        "audience": "https://api.helloannie.com"
      }'
    ```


    The `access_token` from the response should be used in the `Authorization`
    header when making requests to the Annie API:


    ```

    curl -H "Authorization: Bearer eyJhbGciOiJSUzI..."
    https://api.helloannie.com/v1/...

    ```


    ### API Response Structure


    The Annie API returns status codes consistent with standard HTTP
    conventions. Success and Error responses follow the below structure:


    ```

    {
      "success": boolean
      "data": {}
      "message": string // optional
    }

    ```


    ### Rate Limiting


    The Annie API enforces rate limits to ensure stability and fair usage. The
    default rate limit is **60 requests per minute** per organization. This
    limit is applied per endpoint pattern (e.g. `GET /v1/bots/:id`).


    When the rate limit is exceeded, the API responds with HTTP `429 Too Many
    Requests`.


    Response headers include:


    - `X-RateLimit-Limit`: The maximum number of requests allowed in the current
    window.

    - `X-RateLimit-Remaining`: The number of requests remaining in the current
    window.

    - `X-RateLimit-Reset`: The time at which the current rate limit window
    resets (in UTC epoch seconds).


    If you exceed the limit, the response will contain a `Retry-After` header
    indicating how many seconds to wait before retrying.


    ### Pagination


    The Annie API does not currently support pagination. All results are
    returned at once.
  version: v1
servers:
  - url: https://api.helloannie.com/v1
security: []
paths:
  /bots/{botId}/workflows:
    post:
      tags:
        - Workflows
      summary: Create or update a workflow
      description: >-
        Create a new workflow or update an existing one. If an `id` is provided
        in the request body, the workflow will be updated; otherwise, a new
        workflow will be created.
      operationId: postV1BotsByBotIdWorkflows
      parameters:
        - name: botId
          in: path
          required: true
          schema:
            format: uuid
            description: The ID of the bot to create/update the workflow for
            type: string
      requestBody:
        description: Request body for creating or updating a workflow
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowUpsertRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/WorkflowUpsertRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/WorkflowUpsertRequest'
      responses:
        '200':
          description: Response containing the created or updated workflow
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowUpsertResponse'
        '400':
          description: The request was invalid or malformed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResponse'
        '403':
          description: You do not have permission to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
        '404':
          description: The requested resource was not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
        '409':
          description: The request conflicts with another in-progress operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConflictResponse'
components:
  schemas:
    WorkflowUpsertRequest:
      additionalProperties: false
      type: object
      required:
        - title
        - description
        - steps
      properties:
        id:
          format: uuid
          description: >-
            The workflow ID. If provided, the workflow will be updated;
            otherwise, a new workflow will be created.
          type: string
        title:
          description: Title of the workflow
          type: string
        description:
          description: Optional description of the workflow
          type: string
          nullable: true
        enabled:
          default: true
          description: Whether the workflow is enabled
          type: boolean
        usageContext:
          description: Context describing when this workflow should be used
          type: string
          nullable: true
        order:
          default: 0
          description: Order of the workflow
          type: number
        steps:
          description: Steps in the workflow
          type: array
          items:
            type: object
            required:
              - title
              - description
              - instructions
              - order
            properties:
              title:
                description: Title of the step
                type: string
              description:
                description: Optional description of the step
                type: string
                nullable: true
              instructions:
                description: Instructions for the step
                type: string
              examples:
                description: Example phrases for the step
                type: array
                items:
                  type: string
              order:
                description: Order of the step within its parent
                example: 0
                type: number
              action:
                description: Action tool name (e.g., SEND_TEXT, TRANSFER_CALL)
                type: string
              actionMetadata:
                description: >-
                  Metadata for supported actions. SEND_TEXT and SEND_EMAIL
                  accept either an existing patientMessageTemplateId or inline
                  template fields. TRANSFER_CALL accepts either a saved
                  forwardingNumberId or inline name, phoneNumber, and optional
                  extension.
                anyOf:
                  - additionalProperties: false
                    description: Metadata for the SEND_TEXT action.
                    type: object
                    required:
                      - templateName
                      - templateBody
                    properties:
                      templateName:
                        minLength: 1
                        description: >-
                          Template name for SEND_TEXT or SEND_EMAIL actions. May
                          include {{variable}} placeholders.
                        example: Appointment Confirmation
                        type: string
                      templateBody:
                        minLength: 1
                        description: >-
                          Template body for SEND_TEXT or SEND_EMAIL actions. May
                          include {{variable}} placeholders.
                        example: Your appointment is scheduled for tomorrow at 3 PM.
                        type: string
                    title: SEND_TEXT
                  - additionalProperties: false
                    description: Metadata for the SEND_EMAIL action.
                    type: object
                    required:
                      - templateName
                      - templateBody
                    properties:
                      templateName:
                        minLength: 1
                        description: >-
                          Template name for SEND_TEXT or SEND_EMAIL actions. May
                          include {{variable}} placeholders.
                        example: Appointment Reminder Email
                        type: string
                      templateBody:
                        minLength: 1
                        description: >-
                          Template body for SEND_TEXT or SEND_EMAIL actions. May
                          include {{variable}} placeholders.
                        example: >-
                          This is a reminder that your appointment is tomorrow
                          at 3 PM.
                        type: string
                      templateSubject:
                        minLength: 1
                        description: >-
                          Optional email subject for SEND_EMAIL actions. May
                          include {{variable}} placeholders.
                        example: Your Upcoming Appointment
                        type: string
                    title: SEND_EMAIL
                  - additionalProperties: false
                    description: >-
                      SEND_TEXT or SEND_EMAIL using an existing patient message
                      template ID.
                    type: object
                    required:
                      - patientMessageTemplateId
                    properties:
                      patientMessageTemplateId:
                        minLength: 1
                        description: >-
                          ID of an existing patient message template for
                          SEND_TEXT or SEND_EMAIL actions.
                        type: string
                    title: >-
                      SEND_TEXT or SEND_EMAIL using an existing patient
                      message...
                  - additionalProperties: false
                    description: >-
                      TRANSFER_CALL (forwarding number) — use a saved forwarding
                      number ID.
                    type: object
                    required:
                      - forwardingNumberId
                    properties:
                      forwardingNumberId:
                        format: uuid
                        description: >-
                          ID of a saved forwarding number to use for the
                          transfer.
                        type: string
                    title: TRANSFER_CALL (forwarding number)
                  - additionalProperties: false
                    description: >-
                      TRANSFER_CALL (inline) — provide name, phoneNumber, and
                      optional extension directly.
                    type: object
                    required:
                      - name
                      - phoneNumber
                    properties:
                      name:
                        minLength: 1
                        description: >-
                          Display name for the transfer destination. May include
                          {{variable}} placeholders.
                        example: Front Desk
                        type: string
                      phoneNumber:
                        minLength: 1
                        description: >-
                          Phone number to transfer to in E.164 format (for
                          example, +15551234567). May include {{variable}}
                          placeholders.
                        example: '+15551234567'
                        type: string
                      extension:
                        minLength: 1
                        description: >-
                          Optional extension to dial after the transfer
                          connects. Supports DTMF characters 0-9, *, #, A-D, w,
                          W. You may also use {{variable}} placeholders; after
                          resolution, the final extension must be 1-20 DTMF
                          characters.
                        example: '123'
                        type: string
                    title: TRANSFER_CALL (inline)
              childSteps:
                type: array
                items:
                  type: object
                  required:
                    - title
                    - description
                    - instructions
                    - order
                  properties:
                    title:
                      description: Title of the step
                      type: string
                    description:
                      description: Optional description of the step
                      type: string
                      nullable: true
                    instructions:
                      description: Instructions for the step
                      type: string
                    examples:
                      description: Example phrases for the step
                      type: array
                      items:
                        type: string
                    order:
                      description: Order of the step within its parent
                      example: 0
                      type: number
                    action:
                      description: Action tool name (e.g., SEND_TEXT, TRANSFER_CALL)
                      type: string
                    actionMetadata:
                      description: >-
                        Metadata for supported actions. SEND_TEXT and SEND_EMAIL
                        accept either an existing patientMessageTemplateId or
                        inline template fields. TRANSFER_CALL accepts either a
                        saved forwardingNumberId or inline name, phoneNumber,
                        and optional extension.
                      anyOf:
                        - additionalProperties: false
                          description: Metadata for the SEND_TEXT action.
                          type: object
                          required:
                            - templateName
                            - templateBody
                          properties:
                            templateName:
                              minLength: 1
                              description: >-
                                Template name for SEND_TEXT or SEND_EMAIL
                                actions. May include {{variable}} placeholders.
                              example: Appointment Confirmation
                              type: string
                            templateBody:
                              minLength: 1
                              description: >-
                                Template body for SEND_TEXT or SEND_EMAIL
                                actions. May include {{variable}} placeholders.
                              example: >-
                                Your appointment is scheduled for tomorrow at 3
                                PM.
                              type: string
                          title: SEND_TEXT
                        - additionalProperties: false
                          description: Metadata for the SEND_EMAIL action.
                          type: object
                          required:
                            - templateName
                            - templateBody
                          properties:
                            templateName:
                              minLength: 1
                              description: >-
                                Template name for SEND_TEXT or SEND_EMAIL
                                actions. May include {{variable}} placeholders.
                              example: Appointment Reminder Email
                              type: string
                            templateBody:
                              minLength: 1
                              description: >-
                                Template body for SEND_TEXT or SEND_EMAIL
                                actions. May include {{variable}} placeholders.
                              example: >-
                                This is a reminder that your appointment is
                                tomorrow at 3 PM.
                              type: string
                            templateSubject:
                              minLength: 1
                              description: >-
                                Optional email subject for SEND_EMAIL actions.
                                May include {{variable}} placeholders.
                              example: Your Upcoming Appointment
                              type: string
                          title: SEND_EMAIL
                        - additionalProperties: false
                          description: >-
                            SEND_TEXT or SEND_EMAIL using an existing patient
                            message template ID.
                          type: object
                          required:
                            - patientMessageTemplateId
                          properties:
                            patientMessageTemplateId:
                              minLength: 1
                              description: >-
                                ID of an existing patient message template for
                                SEND_TEXT or SEND_EMAIL actions.
                              type: string
                          title: >-
                            SEND_TEXT or SEND_EMAIL using an existing patient
                            message...
                        - additionalProperties: false
                          description: >-
                            TRANSFER_CALL (forwarding number) — use a saved
                            forwarding number ID.
                          type: object
                          required:
                            - forwardingNumberId
                          properties:
                            forwardingNumberId:
                              format: uuid
                              description: >-
                                ID of a saved forwarding number to use for the
                                transfer.
                              type: string
                          title: TRANSFER_CALL (forwarding number)
                        - additionalProperties: false
                          description: >-
                            TRANSFER_CALL (inline) — provide name, phoneNumber,
                            and optional extension directly.
                          type: object
                          required:
                            - name
                            - phoneNumber
                          properties:
                            name:
                              minLength: 1
                              description: >-
                                Display name for the transfer destination. May
                                include {{variable}} placeholders.
                              example: Front Desk
                              type: string
                            phoneNumber:
                              minLength: 1
                              description: >-
                                Phone number to transfer to in E.164 format (for
                                example, +15551234567). May include {{variable}}
                                placeholders.
                              example: '+15551234567'
                              type: string
                            extension:
                              minLength: 1
                              description: >-
                                Optional extension to dial after the transfer
                                connects. Supports DTMF characters 0-9, *, #,
                                A-D, w, W. You may also use {{variable}}
                                placeholders; after resolution, the final
                                extension must be 1-20 DTMF characters.
                              example: '123'
                              type: string
                          title: TRANSFER_CALL (inline)
    WorkflowUpsertResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
      properties:
        success:
          enum:
            - true
          type: boolean
        data:
          additionalProperties: false
          description: A workflow exported in portable JSON format
          type: object
          required:
            - id
            - title
            - description
            - enabled
            - usageContext
            - steps
          properties:
            id:
              format: uuid
              description: The PromptBlock ID
              type: string
            title:
              type: string
            description:
              type: string
              nullable: true
            enabled:
              type: boolean
            usageContext:
              type: string
              nullable: true
            steps:
              type: array
              items:
                type: object
                required:
                  - title
                  - description
                  - instructions
                  - examples
                  - order
                  - childSteps
                properties:
                  title:
                    type: string
                  description:
                    type: string
                    nullable: true
                  instructions:
                    type: string
                  examples:
                    type: array
                    items:
                      type: string
                  order:
                    example: 0
                    type: number
                  action:
                    type: string
                  actionMetadata:
                    description: >-
                      Metadata for supported actions. TRANSFER_CALL uses inline
                      destination fields in exported workflows and templates.
                    anyOf:
                      - additionalProperties: false
                        description: Metadata for the SEND_TEXT action.
                        type: object
                        required:
                          - templateName
                          - templateBody
                        properties:
                          templateName:
                            minLength: 1
                            description: >-
                              Template name for SEND_TEXT or SEND_EMAIL actions.
                              May include {{variable}} placeholders.
                            example: Appointment Confirmation
                            type: string
                          templateBody:
                            minLength: 1
                            description: >-
                              Template body for SEND_TEXT or SEND_EMAIL actions.
                              May include {{variable}} placeholders.
                            example: >-
                              Your appointment is scheduled for tomorrow at 3
                              PM.
                            type: string
                        title: SEND_TEXT
                      - additionalProperties: false
                        description: Metadata for the SEND_EMAIL action.
                        type: object
                        required:
                          - templateName
                          - templateBody
                        properties:
                          templateName:
                            minLength: 1
                            description: >-
                              Template name for SEND_TEXT or SEND_EMAIL actions.
                              May include {{variable}} placeholders.
                            example: Appointment Reminder Email
                            type: string
                          templateBody:
                            minLength: 1
                            description: >-
                              Template body for SEND_TEXT or SEND_EMAIL actions.
                              May include {{variable}} placeholders.
                            example: >-
                              This is a reminder that your appointment is
                              tomorrow at 3 PM.
                            type: string
                          templateSubject:
                            minLength: 1
                            description: >-
                              Optional email subject for SEND_EMAIL actions. May
                              include {{variable}} placeholders.
                            example: Your Upcoming Appointment
                            type: string
                        title: SEND_EMAIL
                      - additionalProperties: false
                        description: >-
                          TRANSFER_CALL (inline) — provide name, phoneNumber,
                          and optional extension directly.
                        type: object
                        required:
                          - name
                          - phoneNumber
                        properties:
                          name:
                            minLength: 1
                            description: >-
                              Display name for the transfer destination. May
                              include {{variable}} placeholders.
                            example: Front Desk
                            type: string
                          phoneNumber:
                            minLength: 1
                            description: >-
                              Phone number to transfer to in E.164 format (for
                              example, +15551234567). May include {{variable}}
                              placeholders.
                            example: '+15551234567'
                            type: string
                          extension:
                            minLength: 1
                            description: >-
                              Optional extension to dial after the transfer
                              connects. Supports DTMF characters 0-9, *, #, A-D,
                              w, W. You may also use {{variable}} placeholders;
                              after resolution, the final extension must be 1-20
                              DTMF characters.
                            example: '123'
                            type: string
                        title: TRANSFER_CALL (inline)
                  childSteps:
                    type: array
                    items:
                      type: object
                      required:
                        - title
                        - description
                        - instructions
                        - examples
                        - order
                      properties:
                        title:
                          type: string
                        description:
                          type: string
                          nullable: true
                        instructions:
                          type: string
                        examples:
                          type: array
                          items:
                            type: string
                        order:
                          example: 0
                          type: number
                        action:
                          type: string
                        actionMetadata:
                          description: >-
                            Metadata for supported actions. TRANSFER_CALL uses
                            inline destination fields in exported workflows and
                            templates.
                          anyOf:
                            - additionalProperties: false
                              description: Metadata for the SEND_TEXT action.
                              type: object
                              required:
                                - templateName
                                - templateBody
                              properties:
                                templateName:
                                  minLength: 1
                                  description: >-
                                    Template name for SEND_TEXT or SEND_EMAIL
                                    actions. May include {{variable}}
                                    placeholders.
                                  example: Appointment Confirmation
                                  type: string
                                templateBody:
                                  minLength: 1
                                  description: >-
                                    Template body for SEND_TEXT or SEND_EMAIL
                                    actions. May include {{variable}}
                                    placeholders.
                                  example: >-
                                    Your appointment is scheduled for tomorrow
                                    at 3 PM.
                                  type: string
                              title: SEND_TEXT
                            - additionalProperties: false
                              description: Metadata for the SEND_EMAIL action.
                              type: object
                              required:
                                - templateName
                                - templateBody
                              properties:
                                templateName:
                                  minLength: 1
                                  description: >-
                                    Template name for SEND_TEXT or SEND_EMAIL
                                    actions. May include {{variable}}
                                    placeholders.
                                  example: Appointment Reminder Email
                                  type: string
                                templateBody:
                                  minLength: 1
                                  description: >-
                                    Template body for SEND_TEXT or SEND_EMAIL
                                    actions. May include {{variable}}
                                    placeholders.
                                  example: >-
                                    This is a reminder that your appointment is
                                    tomorrow at 3 PM.
                                  type: string
                                templateSubject:
                                  minLength: 1
                                  description: >-
                                    Optional email subject for SEND_EMAIL
                                    actions. May include {{variable}}
                                    placeholders.
                                  example: Your Upcoming Appointment
                                  type: string
                              title: SEND_EMAIL
                            - additionalProperties: false
                              description: >-
                                TRANSFER_CALL (inline) — provide name,
                                phoneNumber, and optional extension directly.
                              type: object
                              required:
                                - name
                                - phoneNumber
                              properties:
                                name:
                                  minLength: 1
                                  description: >-
                                    Display name for the transfer destination.
                                    May include {{variable}} placeholders.
                                  example: Front Desk
                                  type: string
                                phoneNumber:
                                  minLength: 1
                                  description: >-
                                    Phone number to transfer to in E.164 format
                                    (for example, +15551234567). May include
                                    {{variable}} placeholders.
                                  example: '+15551234567'
                                  type: string
                                extension:
                                  minLength: 1
                                  description: >-
                                    Optional extension to dial after the
                                    transfer connects. Supports DTMF characters
                                    0-9, *, #, A-D, w, W. You may also use
                                    {{variable}} placeholders; after resolution,
                                    the final extension must be 1-20 DTMF
                                    characters.
                                  example: '123'
                                  type: string
                              title: TRANSFER_CALL (inline)
    BadRequestResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    ForbiddenResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    NotFoundResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    ConflictResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string

````