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

> Personalizes the message of one campaign step for a single lead.

# Personalize Step for Lead

The lead receives this version of the step instead of its shared content, which
stays unchanged for every other lead. Same as **Personalize** in the lemlist
review page.

Every body field is optional and overlays the lead's current version: its
existing personalization, otherwise the step's content. Fields you leave out
are kept; the response returns the full personalized content. Sending only
`variant` puts the lead on that version as is.

* **A/B tests:** a personalized step is no longer A/B tested for that lead. It
  pins the lead to the variant it is written on (before the campaign starts,
  it also decides which sequence variant the lead follows). Switching
  `variant` replaces the lead's personalization of the other variant.
* **Email threads:** on a follow-up email, a non-empty `subject` starts a new
  thread. Leave `subject` out to stay in the thread.
* **Cc:** `cc: []` removes the step's cc for this lead.
* **LinkedIn, SMS and WhatsApp:** messages are plain text; HTML you send is
  converted to text.
* **Supported steps:** email, LinkedIn message, LinkedIn invitation, SMS and
  WhatsApp message. Voice notes and conditions answer `422`, and so do steps
  in a wait-until fallback or in a branch several conditions lead to.
* **Reached steps:** once the lead reached the step (sent, skipped or ignored),
  the request answers `409`.

A reviewer who has the lead open in the lemlist review page at the same time
overwrites this change on their next edit.


## OpenAPI

````yaml put /campaigns/{campaignId}/leads/{leadIdOrEmail}/steps/{stepId}/personalization
openapi: 3.0.0
info:
  title: lemlist API
  version: 1.0.0
  description: >-
    Welcome to the lemlist Developer Documentation.


    lemlist is very customizable and open. You'll find on this page all the API
    and integration you can do with lemlist.


    # Rate Limit


    lemlist's API rate limits requests in order to prevent abuse and overload of
    our services.  

    Rate limits are applied on all routes and per API key performing the
    request.  

    The rate limits are **20** requests per **2** seconds.  

    The response provides any information you may need about it:


    | Header | Description |

    | --- | --- |

    | Retry-After | The number of seconds in which you can retry |

    | X-RateLimit-Limit | The maximum requests in that time |

    | X-RateLimit-Remaining | The number of remaining requests you can make |

    | X-RateLimit-Reset | The date when the rate limit will reset |


    _Example of values for the rate limit headers_


    ``` json

    {
        "Retry-After": 2,
        "X-RateLimit-Limit": 20,
        "X-RateLimit-Remaining": 7,
        "X-RateLimit-Reset" : "Tue Feb 16 2021 09:02:42 GMT+0100 (Central European Standard Time)"
    }

     ```

    # Definitions


    ## Team


    A team is the entity of lemlist that can handle users and billing.


    ## Credits


    Credits are the coins a team uses to enrich emails, LinkedIn URLs, etc. via
    the enrich route. Each enrichment feature needs a certain amount of credits
    to run.


    ## User


    You use a user account to connect to lemlist and send messages via the
    connected emails or LinkedIn account.


    ## Campaign


    A campaign is the entity to automate outreach. A campaign has multiple
    sequences composed of steps.


    ## Lead


    A lead is a person that you try to contact via a campaign.


    ## Activity


    An activity is the history of all the steps.


    ## Unsubscribe


    An unsubscribe occurs when a person decides they don't want to receive
    emails from you anymore.


    # Authentication


    All API routes use the dedicated subdomain `api.lemlist.com`.


    lemlist uses API keys to allow access to the API. You can get your lemlist
    API key at our [integration
    page](https://app.lemlist.com/settings/integrations).


    You need to add the `Authorization` header using the `Basic` authentication
    type. `login:password` **where the login is always empty and the password is
    the API key**.


    ⚠️ **Don't forget to add the semicolon (**`:`**) before your API key in curl
    command.**


    > To authorize, use this code: 
      

    ``` shell

    curl https://api.lemlist.com/api/team \
      --user ":YourApiKey"

     ```

    **Make sure to replace** **`YourApiKey`** **with your API key.**


    # Give feedback


    If you want to report a bug, ask for data, or share with us a use case,
    please fill this [form](https://lemlist.typeform.com/to/mfVlkyGf). It will
    help us centralize your needs!
servers:
  - url: https://api.lemlist.com/api
security:
  - basicAuth: []
paths:
  /campaigns/{campaignId}/leads/{leadIdOrEmail}/steps/{stepId}/personalization:
    parameters:
      - name: campaignId
        in: path
        required: true
        description: The unique identifier of the campaign
        example: cam_Example1A2b3C4d5E
        schema:
          type: string
      - name: leadIdOrEmail
        in: path
        required: true
        description: The unique identifier or email of the lead
        example: lea_Example6F7g8H9i0J
        schema:
          type: string
      - name: stepId
        in: path
        required: true
        description: >-
          The unique identifier of the step, from GET
          /campaigns/{campaignId}/sequences
        example: stp_Example1K2l3M4n5O
        schema:
          type: string
    put:
      tags:
        - Leads
      summary: Personalize Step for Lead
      description: >-
        Personalize the message of one campaign step for a single lead. The lead
        receives this version instead of the step's shared content, and is no
        longer A/B tested on this step.
      parameters: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                variant:
                  type: string
                  enum:
                    - A
                    - B
                  description: >-
                    A/B variant to write on. Defaults to the variant the lead is
                    already on: the winner once one is picked, else the variant
                    already personalized, else the variant of the lead's
                    scheduled task, else A.
                subject:
                  type: string
                  description: >-
                    Email steps only. On a follow-up email, a non-empty subject
                    starts a new thread; omit it to stay in the thread.
                message:
                  type: string
                  description: >-
                    The message body. HTML on email steps; plain text on
                    LinkedIn, SMS and WhatsApp steps (HTML is converted to
                    text). Cannot be blank, except on a LinkedIn invitation.
                cc:
                  type: array
                  items:
                    type: string
                  description: >-
                    Email steps only. An empty array removes the cc for this
                    lead.
                plainText:
                  type: boolean
                  description: Email steps only. Send this lead a plain-text email.
                altMessage:
                  type: string
                  minLength: 1
                  description: >-
                    LinkedIn invitation and LinkedIn message steps only. The
                    connection-request note, 300 characters at most on an
                    invitation.
                altMessagePremium:
                  type: string
                  minLength: 1
                  maxLength: 300
                  description: >-
                    LinkedIn message steps only. The note sent from a premium
                    account.
            example:
              message: <p>Hi {{firstName}}, a quick follow-up on my last email.</p>
      responses:
        '200':
          description: >-
            The step is personalized for the lead. `content` is the full
            personalized content, the fields you did not send included.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StepPersonalization'
        '400':
          description: >-
            A path identifier is malformed (`ROUTE_BAD_REQUEST`), the body is
            invalid (`VALIDATION_ERROR`), or no API key was supplied (plain
            text).
          content:
            application/json:
              example:
                error: Validation error
                code: VALIDATION_ERROR
            text/plain:
              example: no api key provided
        '401':
          description: >-
            Unauthorized - invalid or missing API key, or a key that is not
            linked to a user (`ROUTE_UNAUTHORIZED`).
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '404':
          description: >-
            `REVIEW_DRAFT_CAMPAIGN_NOT_FOUND`, `REVIEW_DRAFT_LEAD_NOT_FOUND`,
            `REVIEW_DRAFT_STEP_NOT_FOUND` or `REVIEW_DRAFT_TEMPLATE_NOT_FOUND` -
            the campaign, the lead or the step does not exist in this workspace,
            or the step has no message.
          content:
            application/json:
              example:
                error: Lead not found in this campaign
                code: REVIEW_DRAFT_LEAD_NOT_FOUND
        '405':
          description: Method not allowed - this endpoint only accepts PUT and DELETE
        '409':
          description: >-
            `REVIEW_DRAFT_STEP_ALREADY_REACHED` - the lead already reached this
            step (sent, skipped or ignored); or `CAMPAIGN_AI_DISCONTINUED`.
          content:
            application/json:
              example:
                error: >-
                  The lead already reached this step: its message can no longer
                  be personalized
                code: REVIEW_DRAFT_STEP_ALREADY_REACHED
        '422':
          description: >-
            `REVIEW_DRAFT_STEP_UNSUPPORTED` (voice notes, conditions and
            non-message steps), `REVIEW_DRAFT_BRANCH_UNSUPPORTED` (a step in a
            wait-until fallback, or in a branch several conditions lead to),
            `REVIEW_DRAFT_VARIANT_UNAVAILABLE` (no variant B, or the other
            variant won), `REVIEW_DRAFT_FIELD_UNSUPPORTED` (a field the step
            type does not carry), `REVIEW_DRAFT_CONTENT_EMPTY` (a blank message,
            or a blank LinkedIn note) or `REVIEW_DRAFT_CONTENT_TOO_LONG` (a
            LinkedIn note over 300 characters).
          content:
            application/json:
              example:
                error: >-
                  This A/B variant is not available on the step (no variant B,
                  or the other variant won)
                code: REVIEW_DRAFT_VARIANT_UNAVAILABLE
        '429':
          description: Rate limit exceeded - 20 requests per 2 seconds per API key
components:
  schemas:
    StepPersonalization:
      type: object
      description: >-
        A lead's personalized version of one campaign step. It pins the lead to
        the A/B variant it is written on.
      properties:
        leadId:
          type: string
          description: The lead the step is personalized for
        stepId:
          type: string
          description: The personalized step
        variant:
          type: string
          enum:
            - A
            - B
          description: The A/B variant the lead is pinned to
        emailTemplateId:
          type: string
          description: >-
            The step content the personalization overrides (variant A or B of
            the step)
        content:
          type: object
          description: >-
            The full personalized content. Only the fields of the step type are
            present.
          properties:
            subject:
              type: string
              description: Email steps. An empty subject keeps a follow-up in its thread.
            message:
              type: string
            cc:
              type: array
              items:
                type: string
            plainText:
              type: boolean
            altMessage:
              type: string
              description: >-
                LinkedIn invitation and message steps: the connection-request
                note
            altMessagePremium:
              type: string
              description: 'LinkedIn message steps: the note sent from a premium account'
      example:
        leadId: lea_Example6F7g8H9i0J
        stepId: stp_Example1K2l3M4n5O
        variant: A
        emailTemplateId: etp_Example6P7q8R9s0T
        content:
          subject: ''
          message: <p>Hi {{firstName}}, a quick follow-up on my last email.</p>
          cc:
            - jane@example.com
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

````