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

# Add a sequence step

> Adds one sequence step. `sequenceNumber` is the step's 0-based slot - the same numbering GET /business/campaigns/{campaignId}/steps reports - and must be free (409 STEP_POSITION_TAKEN); existing steps are not shifted on insert, and only DELETE renumbers. `daysBetween` is the wait after the previous step (after the campaign start for step 0). `type: manual` sends your `subject`/`body` as written, with {Variable} tokens and spintax substituted per lead at send time; `type: ai_generated` writes its own topic and title with AI when the step is created and renders each message per lead (do not send `topic`); `type: ai_reply` drafts a reply from the `topic` you supply and parks it for approval. `linkedin_visit` and `linkedin_like` steps carry no message at all. A `linkedin_connection` step may not follow a `linkedin_message` step (422 STEP_ORDER_INVALID). Only the token owner may add steps. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.

Errors:
- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.
- `409` `STEP_POSITION_TAKEN` — A step already occupies this sequenceNumber in the campaign.
- `422` `STEP_ORDER_INVALID` — A linkedin_connection step would follow a linkedin_message step.
- `422` `VALIDATION_FAILED` — Unknown key, missing channel/sequenceNumber/daysBetween, a value out of range, a topic on an ai_generated step, a missing topic on an ai_reply step, or content on a linkedin_visit / linkedin_like step; `param` names the field.
- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).
- `500` `UNEXPECTED_ERROR` — The step could not be stored, or AI topic generation failed for an ai_generated step.

Requires one of the following token scopes: campaigns.



## OpenAPI

````yaml /openapi.json post /business/campaigns/{campaignId}/steps
openapi: 3.1.0
info:
  title: Fuse Business API
  version: 1.0.0
  description: >-
    External API for lists, campaigns, prospect search and contacts.
    Authenticate with your API token as HTTP Basic. All paths are under /api/v1.
servers:
  - url: https://api.tryfuse.ai/api/v1
    description: Production
security:
  - basicAuth: []
tags:
  - name: Lists
  - name: Custom columns
  - name: Smart columns
  - name: Exports
  - name: Campaigns
  - name: Knowledge hubs
  - name: Analytics
  - name: Website intent
  - name: Account
  - name: Prospect search
  - name: Campaign steps
  - name: Scheduled sends
  - name: Campaign templates
  - name: Agents
  - name: Research
  - name: Company search
  - name: Saved searches
  - name: Folders
  - name: Contacts
paths:
  /business/campaigns/{campaignId}/steps:
    post:
      tags:
        - Campaign steps
      summary: Add a sequence step
      description: >-
        Adds one sequence step. `sequenceNumber` is the step's 0-based slot -
        the same numbering GET /business/campaigns/{campaignId}/steps reports -
        and must be free (409 STEP_POSITION_TAKEN); existing steps are not
        shifted on insert, and only DELETE renumbers. `daysBetween` is the wait
        after the previous step (after the campaign start for step 0). `type:
        manual` sends your `subject`/`body` as written, with {Variable} tokens
        and spintax substituted per lead at send time; `type: ai_generated`
        writes its own topic and title with AI when the step is created and
        renders each message per lead (do not send `topic`); `type: ai_reply`
        drafts a reply from the `topic` you supply and parks it for approval.
        `linkedin_visit` and `linkedin_like` steps carry no message at all. A
        `linkedin_connection` step may not follow a `linkedin_message` step (422
        STEP_ORDER_INVALID). Only the token owner may add steps. Rate limit: 30
        requests/minute and 1,000/day per token owner, shared by every campaign,
        scheduled-send, campaign-template and knowledge-hub endpoint.


        Errors:

        - `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it
        belongs to another account (including a campaign delegated to you or
        shared by your team's visibility settings), or it has been deleted.

        - `409` `STEP_POSITION_TAKEN` — A step already occupies this
        sequenceNumber in the campaign.

        - `422` `STEP_ORDER_INVALID` — A linkedin_connection step would follow a
        linkedin_message step.

        - `422` `VALIDATION_FAILED` — Unknown key, missing
        channel/sequenceNumber/daysBetween, a value out of range, a topic on an
        ai_generated step, a missing topic on an ai_reply step, or content on a
        linkedin_visit / linkedin_like step; `param` names the field.

        - `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or
        1,000 in a day, for this token owner (the bucket is shared by every
        /business/campaigns, /business/scheduled-sends,
        /business/campaign-templates and /business/knowledge-hubs call).

        - `500` `UNEXPECTED_ERROR` — The step could not be stored, or AI topic
        generation failed for an ai_generated step.


        Requires one of the following token scopes: campaigns.
      operationId: createCampaignStep
      parameters:
        - name: campaignId
          in: path
          required: true
          description: >-
            The campaign's id (24-character hex ObjectId), as returned by POST
            /business/campaigns or as the campaignId of a GET
            /business/campaigns row.
          schema:
            type: string
            description: >-
              The campaign's id (24-character hex ObjectId), as returned by POST
              /business/campaigns or as the campaignId of a GET
              /business/campaigns row.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                channel:
                  type: string
                  enum:
                    - email
                    - linkedin_connection
                    - linkedin_message
                    - linkedin_visit
                    - linkedin_like
                    - inmail
                    - dialer
                    - todo
                  description: >-
                    Step channel: email, linkedin_connection (connection
                    request), linkedin_message (message to an accepted
                    connection), linkedin_visit (profile visit, no content),
                    linkedin_like (reaction to a recent post, no content),
                    inmail (LinkedIn InMail, consumes InMail credits), dialer
                    (phone-call task for a rep) or todo (free-form human task).
                    A linkedin_connection step cannot come after a
                    linkedin_message step (422 STEP_ORDER_INVALID).
                type:
                  type: string
                  enum:
                    - manual
                    - ai_generated
                    - ai_reply
                  default: manual
                  description: >-
                    manual (default) sends your subject/body as written;
                    ai_generated writes a topic and title with AI at creation
                    and renders each message per lead at send time (send no
                    topic — it is generated); ai_reply is an AI-drafted reply
                    that waits for approval and needs a topic.
                sequenceNumber:
                  type: integer
                  minimum: 0
                  maximum: 50
                  description: >-
                    The step's 0-based slot in the sequence — the same numbering
                    GET /business/campaigns/{campaignId}/steps reports, so 0 is
                    the first step. Must be unused in this campaign (409
                    STEP_POSITION_TAKEN); existing steps are not shifted on
                    insert (only DELETE renumbers).
                daysBetween:
                  type: integer
                  minimum: 0
                  maximum: 90
                  description: >-
                    Whole days to wait after the previous step (or after the
                    campaign start for the first step) before this one is due,
                    0-90.
                subject:
                  type: string
                  maxLength: 500
                  description: >-
                    Subject line for a manual step (up to 500 characters, may be
                    empty); becomes the step title. Rejected on linkedin_visit
                    and linkedin_like steps, which carry no message.
                body:
                  description: >-
                    Message body for a manual step (up to 20000 characters;
                    {Variable} tokens and spintax substitute at send time). On a
                    linkedin_connection step this is the invitation note, capped
                    at LinkedIn's 200-character limit. Rejected on
                    linkedin_visit and linkedin_like steps, which carry no
                    message.
                topic:
                  type: string
                  minLength: 1
                  maxLength: 500
                  description: >-
                    Free text: what this step should say, in your own words —
                    there is no fixed set of topics. 1-500 characters. Required
                    for ai_reply, rejected for ai_generated (which generates its
                    own) and for linkedin_visit / linkedin_like steps. Stored
                    but not rendered on a manual step.
                cc:
                  type: array
                  items:
                    type: string
                    format: email
                    maxLength: 320
                    description: A bare email address, up to 320 characters.
                  maxItems: 10
                  description: >-
                    Accepted values: bare email addresses such as
                    ops@example.com — a display name or angle brackets is
                    rejected, up to 320 characters each. Every address you list
                    is copied on every send of this step, up to 10 addresses.
                    Only an email step actually sends them: on any other channel
                    the value is stored and never used.
              required:
                - channel
                - sequenceNumber
                - daysBetween
      responses:
        '201':
          description: Success
          headers:
            RateLimit-Limit:
              schema:
                type: integer
              description: Requests permitted in the current window.
            RateLimit-Remaining:
              schema:
                type: integer
              description: Requests remaining in the current window.
            RateLimit-Reset:
              schema:
                type: integer
              description: Seconds until the current window resets.
          content:
            application/json:
              schema:
                type: object
                properties:
                  step:
                    type: object
                    properties:
                      id:
                        type: string
                      channel:
                        type:
                          - string
                          - 'null'
                        enum:
                          - email
                          - linkedin_connection
                          - linkedin_message
                          - linkedin_visit
                          - linkedin_like
                          - inmail
                          - dialer
                          - todo
                          - null
                      type:
                        type:
                          - string
                          - 'null'
                        enum:
                          - manual
                          - ai_generated
                          - ai_reply
                          - null
                        description: How the step's message is produced.
                      sequenceNumber:
                        type:
                          - integer
                          - 'null'
                        description: 0-based slot in the sequence.
                      daysBetween:
                        type:
                          - integer
                          - 'null'
                        description: Whole days to wait after the previous step.
                      title:
                        type:
                          - string
                          - 'null'
                        description: >-
                          Editor label; set from the subject on a manual step
                          and generated with the topic on an AI step.
                      topic:
                        type:
                          - string
                          - 'null'
                        description: >-
                          Brief an AI step writes each message from; null on an
                          unwritten manual step.
                      subject:
                        type:
                          - string
                          - 'null'
                        description: >-
                          Manual subject line; null when the step has no
                          template yet or is AI-written.
                      body:
                        type:
                          - string
                          - 'null'
                        description: >-
                          Manual message body; null when the step has no
                          template yet or is AI-written.
                      cc:
                        type: array
                        items:
                          type: string
                        description: >-
                          Addresses copied on every send of this step (email
                          only).
                    required:
                      - id
                      - channel
                      - type
                      - sequenceNumber
                      - daysBetween
                      - title
                      - topic
                      - subject
                      - body
                      - cc
                required:
                  - step
              example:
                step:
                  id: 6a8dce2ef83628aea1088041
                  channel: email
                  type: manual
                  sequenceNumber: 1
                  daysBetween: 2
                  title: probe step subject
                  topic: null
                  subject: Following up on BrightPay's finance hiring
                  body: >-
                    <p>Hi {Contact First Name}, circling back on my note last
                    week.</p>
                  cc:
                    - ops@yourcompany.com
        '400':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - basicAuth: []
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            param:
              type:
                - string
                - 'null'
            doc_url:
              type:
                - string
                - 'null'
            request_id:
              type:
                - string
                - 'null'
          required:
            - code
            - message
      required:
        - error
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: >-
        Your API token (`af_…`) as the Basic-auth username, with an empty
        password.

````