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

# Update enrollment step

> Edit one person's email copy before it sends.

## Overview

Replace the subject, fallback subject, or body of one person's email before it
sends. The change applies only to this enrollment and leaves the sequence's
template unchanged. Use it to revise copy that Unify drafted for an
[agentic sequence](/reference/sequences/personalization/agentic-sequences)
before you [approve the enrollment](/developers/api/sequences/enrollments/approve),
or to adjust a scheduled email for one recipient.

Include only the fields you want to change. The request must include at least
one of `subject`, `fallback_subject`, or `body`. Only email steps have copy;
other step types return `400 Bad Request`. Get step IDs from
[List enrollment steps](/developers/api/sequences/enrollments/list-steps).

## Examples

Set `UNIFY_API_KEY` to your API key and replace the example step ID and
`version_id` with values from
[Get enrollment step](/developers/api/sequences/enrollments/get-step).

<AccordionGroup>
  <Accordion title="Rewrite a drafted email">
    This request replaces the email body and keeps the first-name variable from
    the original copy:

    ```bash theme={null}
    curl --request PATCH \
      --url "https://api.unifygtm.com/sequences/v1/enrollment-steps/3f6c2a90-58d1-4e7b-9a43-2c8e1d7b5f06" \
      --header "X-Api-Key: $UNIFY_API_KEY" \
      --header "Content-Type: application/json" \
      --data '{
      "body": "<p>Hi {{variable::person.firstName}},</p><p>Congratulations on the new office in Austin. Would a short call next week be useful?</p>",
      "version_id": "0b7d9e4c-6a21-4f3e-8c55-9d1a2b3c4e5f"
    }'
    ```

    The response returns the step with its new copy and a new
    `email.version_id`.
  </Accordion>

  <Accordion title="Change the subject of a thread">
    Send a subject only to the first email of a thread:

    ```json theme={null}
    {
      "subject": "{{variable::company.name}} and Unify",
      "fallback_subject": "Quick introduction",
      "version_id": "0b7d9e4c-6a21-4f3e-8c55-9d1a2b3c4e5f"
    }
    ```

    Unify uses `fallback_subject` if the variable in `subject` cannot be
    resolved when the email sends.
  </Accordion>
</AccordionGroup>

## Write the copy

`body` is HTML and replaces the step's entire body. Template variables and
[snippets](/reference/sequences/personalization/snippets) appear in the copy as
`{{ ... }}` tokens, such as `{{variable::person.firstName}}`. Keep the tokens you
want to preserve. To add a variable or snippet, copy its token from the
sequence's template, which
[Get sequence step](/developers/api/sequences/sequences/get-step) returns in
`config.body`.

After an update, Unify resolves the tokens in the new copy for this person.
`email.is_ready` is `false` until they are resolved, and the email does not
send before then.

Only the first email of a thread accepts `subject` and `fallback_subject`. Its
`email.is_root_message` is `true`. Later emails reply in the same thread and
reuse its subject, so a subject change on a reply returns `400 Bad Request`.

## Avoid overwriting other edits

Send the `email.version_id` you last read as `version_id`. If the copy changed
after that version, for example because a teammate edited it in Unify, the API
returns `409 Conflict` with `reason` set to `VERSION_OUTDATED`. Get the step
again, apply your change to the latest copy, and retry. Without `version_id`,
the update replaces the current copy regardless of earlier changes.

The API also returns `409 Conflict` once the step has sent or the enrollment has
ended, for example because the person replied or opted out. `reason` identifies
the cause. Only `VERSION_OUTDATED` can be resolved by retrying.


## OpenAPI

````yaml PATCH /sequences/v1/enrollment-steps/{id}
openapi: 3.1.0
info:
  title: Unify Sequences API
  summary: Interact with sequences and sequence enrollments within the Unify platform.
  version: '1'
  termsOfService: https://www.unifygtm.com/legal/terms-and-conditions
  contact:
    name: Unify Support
    url: https://www.unifygtm.com/support
    email: support@unifygtm.com
servers:
  - url: https://api.unifygtm.com
    variables: {}
security:
  - ApiKeyAuth: []
tags:
  - name: Sequences
  - name: Sequence Enrollment Steps
  - name: Sequence Enrollments
paths:
  /sequences/v1/enrollment-steps/{id}:
    patch:
      tags:
        - Sequences
        - Sequence Enrollment Steps
      description: |-
        Update the email copy of an enrollment step that has not been sent yet.
        Returns a bad request for steps that are not email steps and for subject
        changes on reply messages. Returns a conflict once the step has finished
        or the enrollment has ended.
      operationId: update_sequence_enrollment_step
      parameters:
        - name: id
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/uuid'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEnrollmentStepRequest'
      responses:
        '200':
          description: Response returned when an enrollment step's email copy is updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateEnrollmentStepSuccessResponse'
        '400':
          description: Response for any operation that results in a bad request error.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  status:
                    type: string
                    enum:
                      - bad_request
                  errors:
                    type: array
                    items:
                      $ref: '#/components/schemas/UResponses.BadRequestError'
                  message:
                    type: string
                description: >-
                  Response for any operation that results in a bad request
                  error.
        '401':
          description: Response for any operation that results in an unauthorized error.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                  - message
                properties:
                  status:
                    type: string
                    enum:
                      - unauthorized
                  message:
                    type: string
                description: >-
                  Response for any operation that results in an unauthorized
                  error.
        '404':
          description: Response returned when an enrollment step cannot be found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnrollmentStepNotFoundResponse'
        '409':
          description: >-
            Response returned when an enrollment step's email copy can no longer
            be

            updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnrollmentStepUpdateConflictResponse'
        '429':
          description: Response for any operation that exceeds a rate limit.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                  - message
                properties:
                  status:
                    type: string
                    enum:
                      - rate_limited
                  message:
                    type: string
                description: Response for any operation that exceeds a rate limit.
        '500':
          description: Response for any operation that results in an internal server error.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                  - message
                properties:
                  status:
                    type: string
                    enum:
                      - error
                  message:
                    type: string
                description: >-
                  Response for any operation that results in an internal server
                  error.
components:
  schemas:
    uuid:
      type: string
      format: uuid
      description: String UUID value.
    UpdateEnrollmentStepRequest:
      anyOf:
        - type: object
          properties:
            subject:
              type: string
            fallback_subject:
              type: string
            body:
              type: string
              minLength: 1
              maxLength: 200000
            version_id:
              $ref: '#/components/schemas/uuid'
          required:
            - subject
        - type: object
          properties:
            subject:
              type: string
            fallback_subject:
              type: string
            body:
              type: string
              minLength: 1
              maxLength: 200000
            version_id:
              $ref: '#/components/schemas/uuid'
          required:
            - fallback_subject
        - type: object
          properties:
            subject:
              type: string
            fallback_subject:
              type: string
            body:
              type: string
              minLength: 1
              maxLength: 200000
            version_id:
              $ref: '#/components/schemas/uuid'
          required:
            - body
      description: >-
        Request body for updating the email copy of an enrollment step. At least

        one of `subject`, `fallback_subject` or `body` must be provided.


        - `subject` and `fallback_subject` are only accepted on root messages.

        - `body` is HTML. Template variables and snippets are written as `{{ ...
        }}`

        tokens. Must not be blank.

        - `version_id` is the copy version the edit is based on. The update is

        rejected with a conflict when the copy has changed since that version.
    UpdateEnrollmentStepSuccessResponse:
      type: object
      allOf:
        - $ref: '#/components/schemas/EnrollmentStep'
      description: Response returned when an enrollment step's email copy is updated.
    UResponses.BadRequestError:
      type: object
      required:
        - code
      properties:
        code:
          type: string
        path:
          type: array
          items:
            anyOf:
              - type: string
              - type: integer
        object_api_name:
          type: string
        attribute_api_name:
          type: string
      allOf:
        - type: object
          unevaluatedProperties: {}
      description: Validation error detail returned for bad request responses.
    EnrollmentStepNotFoundResponse:
      type: object
      allOf:
        - type: object
          required:
            - status
            - message
          properties:
            status:
              type: string
              enum:
                - not_found
            message:
              type: string
          description: Response for any operation that results in a not found error.
      description: Response returned when an enrollment step cannot be found.
    EnrollmentStepUpdateConflictResponse:
      type: object
      required:
        - reason
      properties:
        reason:
          $ref: '#/components/schemas/EnrollmentStepUpdateConflictReason'
      allOf:
        - type: object
          required:
            - status
            - message
          properties:
            status:
              type: string
              enum:
                - state_conflict
            message:
              type: string
          description: Response for any operation that results in a conflict error.
      description: |-
        Response returned when an enrollment step's email copy can no longer be
        updated.
    EnrollmentStep:
      type: object
      required:
        - id
        - created_at
        - updated_at
        - enrollment_id
        - sequence_id
        - step_id
        - type
        - status
        - step_number
        - is_blocked
        - is_bounced
        - is_canceled
        - is_opted_out
        - is_paused
        - is_replied
        - started_at
        - ended_at
        - email
      properties:
        id:
          $ref: '#/components/schemas/uuid'
        created_at:
          $ref: '#/components/schemas/datetime'
        updated_at:
          $ref: '#/components/schemas/datetime'
        enrollment_id:
          $ref: '#/components/schemas/uuid'
        sequence_id:
          $ref: '#/components/schemas/uuid'
        step_id:
          $ref: '#/components/schemas/uuid'
          description: ID of the sequence step this enrollment step was created from.
        type:
          $ref: '#/components/schemas/SequenceEnrollmentStepType'
        status:
          $ref: '#/components/schemas/SequenceEnrollmentStepStatus'
        step_number:
          anyOf:
            - type: integer
            - type: 'null'
          minimum: 1
          description: >-
            Position of the step in the enrollment, starting at 1. Null until
            the

            step is expected to run or has finished.
        is_blocked:
          type: boolean
        is_bounced:
          type: boolean
        is_canceled:
          type: boolean
        is_opted_out:
          type: boolean
        is_paused:
          type: boolean
        is_replied:
          type: boolean
        started_at:
          anyOf:
            - $ref: '#/components/schemas/datetime'
            - type: 'null'
        ended_at:
          anyOf:
            - $ref: '#/components/schemas/datetime'
            - type: 'null'
        email:
          anyOf:
            - $ref: '#/components/schemas/EnrollmentStepEmail'
            - type: 'null'
          description: Email copy for email steps. Null for other step types.
      description: One step of a person's enrollment in a sequence.
    EnrollmentStepUpdateConflictReason:
      type: string
      enum:
        - STEP_COMPLETED
        - PERSON_REPLIED
        - PERSON_OPTED_OUT
        - PERSON_EXCLUDED
        - ENROLLMENT_CANCELED
        - ENROLLMENT_ENDED
        - VERSION_OUTDATED
      description: Reason an enrollment step's email copy can no longer be updated.
    datetime:
      type: string
      format: date-time
      description: String value representing an RFC 3339 datetime.
    SequenceEnrollmentStepType:
      type: string
      enum:
        - AUTOMATIC_EMAIL
        - MANUAL_EMAIL
        - ACTION_ITEM
        - ZAPIER
        - PHONE_CALL
        - MANUAL_LINKEDIN_PROFILE_VIEW
        - MANUAL_LINKEDIN_CONNECTION
        - MANUAL_LINKEDIN_MESSAGE
      description: Type of a sequence enrollment step.
    SequenceEnrollmentStepStatus:
      type: string
      enum:
        - NOT_STARTED
        - SCHEDULED
        - PENDING
        - FINISHED
        - CANCELED
        - ERRORED
        - UNREACHABLE
      description: Status of an individual sequence enrollment step.
    EnrollmentStepEmail:
      type: object
      required:
        - version_id
        - subject
        - fallback_subject
        - body
        - is_ready
        - is_edited
        - is_root_message
        - is_blocked
        - scheduled_send_at
        - sent_at
      properties:
        version_id:
          $ref: '#/components/schemas/uuid'
          description: >-
            ID of the current version of the copy. Changes every time the copy
            is

            updated.
        subject:
          anyOf:
            - type: string
            - type: 'null'
        fallback_subject:
          anyOf:
            - type: string
            - type: 'null'
          description: |-
            Subject used at send time when `subject` still contains unresolved
            template variables.
        body:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            HTML body of the email. Template variables and snippets are kept as

            `{{ ... }}` tokens and are resolved at send time. Null while the
            copy is

            being prepared.
        is_ready:
          type: boolean
          description: >-
            False while template variables and snippets are still being
            resolved.

            The email is not sent until the copy is ready.
        is_edited:
          type: boolean
          description: True when the copy was changed after it was first generated.
        is_root_message:
          type: boolean
          description: >-
            True for the first email of a thread. Subjects can only be set on
            root

            messages. Replies reuse the thread's subject.
        is_blocked:
          type: boolean
          description: |-
            True when the email cannot be sent in its current state, for example
            because of unresolved template variables or a mailbox problem.
        scheduled_send_at:
          anyOf:
            - $ref: '#/components/schemas/datetime'
            - type: 'null'
        sent_at:
          anyOf:
            - $ref: '#/components/schemas/datetime'
            - type: 'null'
      description: Email copy prepared for one enrollment step.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````

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