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

# Update campaign step

> Change only the fields you send. Type, subject, body and `send_after_days` are copied when someone is enrolled, so edits reach people enrolled afterwards; changing `type` keeps the body. Sending window, timezone, signature and `block_until_task_complete` are read when each step runs, so they also apply to people already enrolled; `applies_to_existing_enrollments` lists which of your changes do. Changing the first email subject also updates the `Re:` subject of later email steps. Needs `campaigns:write`.



## OpenAPI

````yaml /api-reference/openapi-v1.json patch /v1/campaigns/{id}/steps/{step_id}
openapi: 3.1.0
info:
  title: Stardex API (v1)
  version: 1.0.0
  description: >-
    Stardex ATS API — manage candidates, jobs, companies, and recruiting
    workflows.
servers:
  - url: https://api.stardex.ai
    description: Production API server
security:
  - bearerAuth: []
tags:
  - name: Persons
    description: Manage person records — contacts, work history, and custom fields.
  - name: Jobs
    description: Manage job postings — pipeline stages, team members, and custom fields.
  - name: Candidates
    description: Manage candidate records and pipeline stage transitions.
  - name: Companies
    description: Browse and retrieve company records.
  - name: Lists
    description: Create, search, and retrieve saved person and company lists.
  - name: Person Activities
    description: Create and manage activity records (notes, emails, meetings) for persons.
  - name: Team Members
    description: List team members for use in search filters and assignments.
  - name: Custom Fields
    description: Retrieve custom field definitions and tag options for search filters.
  - name: Campaigns
    description: >-
      Create and edit email campaigns, enroll people through enrollment batches,
      and manage who is enrolled.
paths:
  /v1/campaigns/{id}/steps/{step_id}:
    patch:
      tags:
        - Campaigns
      summary: Update campaign step
      description: >-
        Change only the fields you send. Type, subject, body and
        `send_after_days` are copied when someone is enrolled, so edits reach
        people enrolled afterwards; changing `type` keeps the body. Sending
        window, timezone, signature and `block_until_task_complete` are read
        when each step runs, so they also apply to people already enrolled;
        `applies_to_existing_enrollments` lists which of your changes do.
        Changing the first email subject also updates the `Re:` subject of later
        email steps. Needs `campaigns:write`.
      operationId: updateCampaignStep
      parameters:
        - schema:
            type: string
            format: uuid
            description: Campaign ID.
          required: true
          description: Campaign ID.
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: Step ID.
          required: true
          description: Step ID.
          name: step_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignStepUpdateRequest'
            example:
              time_window_start: '08:00'
      responses:
        '200':
          description: Step updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignStepUpdateResponse'
              example:
                success: true
                data:
                  step:
                    id: 5b0f3c8e-2a71-4d0e-9a51-6f0c2d7e1a43
                    order: 1
                    type: email
                    send_after_days: 0
                    subject: '{{search_name}} role at {{search_client}}'
                    body_html: >-
                      <div>Hi
                      {{first_name}},</div><div><br></div><div>{{ai:opening_line}}
                      I'm hiring a <strong>{{search_name}}</strong> at
                      {{search_client}}.
                      {{personalization_line}}</div><div><br></div><div>You can
                      see the role <a target="_blank" rel="noopener noreferrer
                      nofollow" href="{{application_link}}">here</a>. Open to a
                      chat?</div><div><br></div><div>{{sender_first_name}}</div>
                    timezone: Europe/London
                    time_window_start: '08:00'
                    time_window_end: '17:00'
                    include_signature: true
                    block_until_task_complete: false
                    ai_variables:
                      - name: opening_line
                        description: >-
                          One sentence on the most relevant thing they have
                          built or led recently.
                    attachments:
                      - file_name: Monzo backend engineering role.pdf
                        content_type: application/pdf
                        size_bytes: 184320
                    created_at: '2026-10-13T10:15:00.000Z'
                    updated_at: '2026-10-14T08:30:00.000Z'
                  applies_to_existing_enrollments:
                    - time_window_start
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses.
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Machine-readable error code (e.g. "VALIDATION_ERROR",
                          "NOT_FOUND").
                      message:
                        type: string
                        description: Human-readable error description.
                      details:
                        type: object
                        additionalProperties: {}
                        description: >-
                          Extra facts about the error when they help you fix it,
                          such as a limit and when it resets.
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '403':
          description: No access to campaigns, or the API key lacks the permission
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses.
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Machine-readable error code (e.g. "VALIDATION_ERROR",
                          "NOT_FOUND").
                      message:
                        type: string
                        description: Human-readable error description.
                      details:
                        type: object
                        additionalProperties: {}
                        description: >-
                          Extra facts about the error when they help you fix it,
                          such as a limit and when it resets.
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses.
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Machine-readable error code (e.g. "VALIDATION_ERROR",
                          "NOT_FOUND").
                      message:
                        type: string
                        description: Human-readable error description.
                      details:
                        type: object
                        additionalProperties: {}
                        description: >-
                          Extra facts about the error when they help you fix it,
                          such as a limit and when it resets.
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses.
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Machine-readable error code (e.g. "VALIDATION_ERROR",
                          "NOT_FOUND").
                      message:
                        type: string
                        description: Human-readable error description.
                      details:
                        type: object
                        additionalProperties: {}
                        description: >-
                          Extra facts about the error when they help you fix it,
                          such as a limit and when it resets.
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
components:
  schemas:
    CampaignStepUpdateRequest:
      type: object
      properties:
        type:
          type: string
          enum:
            - email
            - manual
            - text
            - linkedin_message
            - linkedin_connection
            - call
          description: >-
            Change the step type. The body is kept; people already enrolled keep
            the type they were enrolled with.
        send_after_days:
          type: integer
          minimum: 0
          maximum: 365
          description: >-
            Days to wait after the previous step (or after enrollment, for the
            first step).
        subject:
          type:
            - string
            - 'null'
          maxLength: 998
          description: >-
            Email subject, or the InMail subject for LinkedIn message steps.
            Only the first email step has its own subject: later email steps
            always use "Re: <first subject>" so they land in the same thread (a
            "Re:" on the first email is removed). Editing a later email's
            subject is rejected. Can use {{variables}}.
        body_html:
          type: string
          maxLength: 100000
          description: >-
            Step body as HTML (paragraphs, headings, line breaks, bold, italic,
            underline, strikethrough, highlight, links, lists and images). Each
            <p> is followed by an empty line, as in the campaign builder; use
            <br> for a line break without a gap. Images need a public https URL
            and are shown as their own block. Can use {{variables}}, including
            inside link URLs. For non-email steps this is the task or message
            text; LinkedIn connection notes are limited to 300 characters.
        timezone:
          type:
            - string
            - 'null'
          description: >-
            IANA timezone for the sending window, for example Europe/London.
            Defaults to the timezone of the campaign owner's first connected
            mailbox. Without one, the step sends in New York business hours
            (America/New_York).
        time_window_start:
          type:
            - string
            - 'null'
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          description: >-
            Start of the sending window for email steps, in 24-hour HH:MM. Left
            empty, the step sends between 09:00 and 17:00 in its timezone.
        time_window_end:
          type:
            - string
            - 'null'
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          description: >-
            End of the sending window for email steps, in 24-hour HH:MM. Must
            differ from time_window_start.
        include_signature:
          type: boolean
          description: Add the sender's email signature to this email step.
        block_until_task_complete:
          type: boolean
          description: >-
            For task steps (not emails): hold the rest of the campaign until
            this task is marked complete. Turning it off releases anyone already
            waiting on the step.
        ai_variables:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                minLength: 1
                maxLength: 64
                description: >-
                  The name used in the template, without the ai: prefix.
                  {{ai:opening_line}} has the name opening_line.
              description:
                type: string
                minLength: 1
                maxLength: 1000
                description: >-
                  What the AI should write for each person, for example "One
                  sentence on their most relevant recent work". The value is
                  inserted exactly as written, so use the variable only where
                  that text fits: a sentence on its own, never mid-sentence.
            required:
              - name
              - description
          maxItems: 20
          description: >-
            A description for every {{ai:name}} used in this step. Descriptions
            for names not used in the step are ignored.
    CampaignStepUpdateResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          type: object
          properties:
            step:
              $ref: '#/components/schemas/CampaignStep'
            applies_to_existing_enrollments:
              type: array
              items:
                type: string
              description: >-
                Changed fields that also apply to people already enrolled.
                Subject, body and timing changes only apply to people enrolled
                after this edit.
          required:
            - step
            - applies_to_existing_enrollments
      required:
        - success
        - data
    CampaignStep:
      type: object
      properties:
        id:
          type: string
          format: uuid
        order:
          type: integer
          description: 1-based position in the campaign.
        type:
          type: string
          enum:
            - email
            - manual
            - text
            - linkedin_message
            - linkedin_connection
            - call
        send_after_days:
          type: integer
        subject:
          type:
            - string
            - 'null'
        body_html:
          type: string
        timezone:
          type:
            - string
            - 'null'
        time_window_start:
          type:
            - string
            - 'null'
          description: >-
            HH:MM. null means the default sending hours, 09:00–17:00 in the
            step's timezone.
        time_window_end:
          type:
            - string
            - 'null'
          description: >-
            HH:MM. null means the default sending hours, 09:00–17:00 in the
            step's timezone.
        include_signature:
          type: boolean
        block_until_task_complete:
          type: boolean
        ai_variables:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                minLength: 1
                maxLength: 64
                description: >-
                  The name used in the template, without the ai: prefix.
                  {{ai:opening_line}} has the name opening_line.
              description:
                type: string
                minLength: 1
                maxLength: 1000
                description: >-
                  What the AI should write for each person, for example "One
                  sentence on their most relevant recent work". The value is
                  inserted exactly as written, so use the variable only where
                  that text fits: a sentence on its own, never mid-sentence.
            required:
              - name
              - description
        attachments:
          type: array
          items:
            type: object
            properties:
              file_name:
                type: string
              content_type:
                type:
                  - string
                  - 'null'
              size_bytes:
                type: integer
            required:
              - file_name
              - content_type
              - size_bytes
          description: >-
            Files sent with this step, added in the campaign builder.
            Attachments cannot be added through the API.
        created_at:
          type: string
        updated_at:
          type:
            - string
            - 'null'
      required:
        - id
        - order
        - type
        - send_after_days
        - subject
        - body_html
        - timezone
        - time_window_start
        - time_window_end
        - include_signature
        - block_until_task_complete
        - ai_variables
        - attachments
        - created_at
        - updated_at
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Authenticate with a Bearer token: API key, OAuth token, or session
        token.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.