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

# Update Node

> Patch a single sequence node's content — subject, body, delays, or AI extension. Draft campaigns only.

**CLI:**

```bash theme={null}
puffle campaign sequence node update --id <id> --node-id <node-id>
puffle campaign sequence node update --id <id> --node-id <node-id> --subject <subject> --body <body> --body-html <body-html> --signature <signature> --from-name <from-name> --reply-to <reply-to> --cc <cc> --bcc <bcc> --attachments <attachments> --include-message <include-message> --is-reply <is-reply> --delay-days <delay-days> --delay-hours <delay-hours> --delay-minutes <delay-minutes> --ai-node <ai-node>
```

## Overview

Partial update of a single sequence node. Only fields present in the body are applied. **Draft campaigns only** — on any other status the server returns `400` without writing.

Immutable fields:

* `type` — to change a node's kind, delete it and add a new one with [`addSequenceNode`](/api-reference/campaigns/add-sequence-node).
* `position` — to reorder, use the `PATCH` verb on the collection (`moveSequenceNode`).
* `campaign_id` — set at creation.

## Editable fields by node type

| Field                                     | Applies to                               |
| ----------------------------------------- | ---------------------------------------- |
| `subject`                                 | `email`                                  |
| `body`                                    | `connection_request`, `message`, `email` |
| `include_message`                         | `connection_request`                     |
| `is_reply`                                | `email`                                  |
| `delay_days` / `delay_hours`              | `delay`                                  |
| `ai_node.purpose` / `ai_node.output_type` | `ai`                                     |

AI extension fields are silently ignored unless the existing node `type === "ai"`. If the extension row doesn't exist yet, the server creates it; otherwise it's updated in place.

## Related operations

* [Add a sequence node](/api-reference/campaigns/add-sequence-node) — `POST` to insert a new node.
* [Delete a sequence node](/api-reference/campaigns/delete-sequence-node) — `DELETE` the collection with `{ nodeId }` to remove.
* [Get a campaign](/api-reference/campaigns/get-campaign) — returns `sequence_nodes` in ordered form.

## AI agent notes

<Note>
  **Two-step AI node setup.** After `addSequenceNode` with `{ type: "ai" }`, immediately `PUT` the same node with `ai_node: { purpose, output_type }` to populate the extension row. The builder UI does this in one motion; agents should do the same.

  **Delay validation happens at launch.** This endpoint does not enforce the "total delay must be 1 minute to 30 days" rule — that's checked when you call `POST /api/campaigns/{id}/launch`. Read the campaign before launch and make sure the full draft sequence is intentional.

  **Read-after-write.** The response includes the fully-refreshed node with its AI extension flattened into `node.ai_node`. No separate GET needed.
</Note>


## OpenAPI

````yaml put /api/campaigns/{id}/sequence/nodes/{nodeId}
openapi: 3.0.3
info:
  title: Puffle API
  version: 1.0.0
  description: >-
    HTTP API for the Puffle GTM platform - Feed and Lead Finder search
    preparation, campaign-backed Outbound execution, Puffle Agent runs, sender
    management, and Unibox reply workflows. Designed for operation by both
    humans and autonomous AI agents. Agents should start at the [Agent
    Playbook](/guides/agent-playbook) which prescribes a workspace-context check
    (`GET /api/context`) and core user journeys with exact call ordering.
  contact:
    name: Puffle Support
    url: https://puffle.ai
servers:
  - url: https://app.puffle.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Campaigns
    description: >-
      Campaign-backed Outbound execution. These endpoints manage draft,
      launching, active, paused, and completed Outbound runs with sequence
      nodes, contacts, and sender accounts.
  - name: Accounts
    description: Signed-in user account, settings, and workspace context endpoints.
  - name: Billing
    description: Billing customer portal and account billing endpoints.
  - name: Senders
    description: >-
      Connected sender accounts, email inboxes, sending domains, DNS
      verification, warmup, and sender capacity.
  - name: Socials
    description: >-
      Read connected LinkedIn and X accounts, review current and archived posts,
      and reconcile publication status. Creating, editing, scheduling,
      publishing, OAuth connection, analytics, and mentions remain
      dashboard-managed workflows and are not part of the public Bearer-token
      API.
paths:
  /api/campaigns/{id}/sequence/nodes/{nodeId}:
    put:
      tags:
        - Campaigns
      summary: Update Node
      description: >-
        Partial update of a single sequence node's content and, for AI nodes,
        its AI extension. Draft campaigns only.
      operationId: updateSequenceNode
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            description: Campaign UUID
        - name: nodeId
          in: path
          required: true
          schema:
            type: string
            description: Sequence node UUID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                subject:
                  type: string
                  nullable: true
                body:
                  type: string
                  nullable: true
                body_html:
                  type: string
                  nullable: true
                signature:
                  type: string
                  nullable: true
                from_name:
                  type: string
                  nullable: true
                reply_to:
                  type: string
                  nullable: true
                cc:
                  type: string
                  nullable: true
                bcc:
                  type: string
                  nullable: true
                attachments:
                  type: array
                  items: {}
                  nullable: true
                include_message:
                  type: boolean
                  nullable: true
                is_reply:
                  type: boolean
                  nullable: true
                delay_days:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                  nullable: true
                delay_hours:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                  nullable: true
                delay_minutes:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                  nullable: true
                ai_node:
                  type: object
                  properties:
                    purpose:
                      type: string
                      nullable: true
                    cta:
                      type: string
                      nullable: true
                    context:
                      type: string
                      nullable: true
                    title:
                      type: string
                      nullable: true
                    skeleton:
                      type: object
                      properties:
                        subject:
                          type: string
                          minLength: 1
                        body:
                          type: string
                          minLength: 1
                        blocks:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                                minLength: 1
                              strategy:
                                type: string
                                minLength: 1
                              personalization:
                                type: object
                                properties:
                                  fields:
                                    type: array
                                    items:
                                      type: string
                                  approach:
                                    type: string
                                  fallback:
                                    type: string
                                required:
                                  - fields
                                  - approach
                                  - fallback
                                additionalProperties: false
                                nullable: true
                              suggestion:
                                type: string
                            required:
                              - name
                              - strategy
                              - personalization
                            additionalProperties: false
                        exampleSubject:
                          type: string
                        exampleBody:
                          type: string
                      required:
                        - subject
                        - body
                        - blocks
                      additionalProperties: false
                      nullable: true
                    output_type:
                      type: string
                      enum:
                        - email
                        - message
                  additionalProperties: false
              additionalProperties: false
      responses:
        '200':
          description: Node updated successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  node:
                    type: object
                    properties:
                      id:
                        type: string
                        description: String value with endpoint-specific validation.
                      campaign_id:
                        type: string
                        description: String value with endpoint-specific validation.
                      position:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      type:
                        type: string
                        enum:
                          - connection_request
                          - message
                          - email
                          - delay
                          - ai
                          - end
                      subject:
                        type: string
                        nullable: true
                      body:
                        type: string
                        nullable: true
                      body_html:
                        type: string
                        nullable: true
                      signature:
                        type: string
                        nullable: true
                      from_name:
                        type: string
                        nullable: true
                      reply_to:
                        type: string
                        nullable: true
                      cc:
                        type: string
                        nullable: true
                      bcc:
                        type: string
                        nullable: true
                      attachments:
                        type: array
                        items: {}
                        nullable: true
                      include_message:
                        type: boolean
                        nullable: true
                      is_reply:
                        type: boolean
                        nullable: true
                      delay_days:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                        nullable: true
                      delay_hours:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                        nullable: true
                      delay_minutes:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                        nullable: true
                      ai_node:
                        type: object
                        properties:
                          output_type:
                            type: string
                            enum:
                              - email
                              - message
                        required:
                          - output_type
                        additionalProperties: {}
                        nullable: true
                    required:
                      - id
                      - campaign_id
                      - position
                      - type
                    additionalProperties: false
                required:
                  - node
                additionalProperties: false
        '400':
          description: Campaign is not in draft status.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '404':
          description: Campaign or node not found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: pk_live_...

````