Skip to main content
POST
/
api
/
campaigns
/
{id}
/
sequence
/
nodes
Add Node
curl --request POST \
  --url https://app.puffle.ai/api/campaigns/{id}/sequence/nodes \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "position": 4503599627370495,
  "subject": "<string>",
  "body": "<string>",
  "signature": "<string>",
  "include_message": true,
  "is_reply": true,
  "delay_days": 4503599627370495,
  "delay_hours": 4503599627370495,
  "delay_minutes": 4503599627370495
}
'
{
  "sequence_nodes": [
    {
      "id": "<string>",
      "campaign_id": "<string>",
      "position": 4503599627370495,
      "subject": "<string>",
      "body": "<string>",
      "body_html": "<string>",
      "signature": "<string>",
      "from_name": "<string>",
      "reply_to": "<string>",
      "cc": "<string>",
      "bcc": "<string>",
      "attachments": [
        "<unknown>"
      ],
      "include_message": true,
      "is_reply": true,
      "delay_days": 4503599627370495,
      "delay_hours": 4503599627370495,
      "delay_minutes": 4503599627370495,
      "ai_node": {}
    }
  ]
}
CLI:
puffle campaign sequence node add --id <id> --type <type>
puffle campaign sequence node add --id <id> --type <type> --position <position> --subject <subject> --body <body> --signature <signature> --include-message <include-message> --is-reply <is-reply> --delay-days <delay-days> --delay-hours <delay-hours> --delay-minutes <delay-minutes>

Overview

Inserts a new node into the campaign sequence. Draft campaigns only — every mutation on this collection is gated on status === "draft". This collection exposes three verbs:
VerbOperationPurpose
POSTaddSequenceNodeInsert a new node (this page). Omit position to drop it right before the terminal end node.
PATCHmoveSequenceNodeReorder an existing node — see Move a sequence node.
DELETEdeleteSequenceNodeRemove a node — see Delete a sequence node.
To edit a node’s content (subject, body, delay values, AI purpose), use updateSequenceNode against the singular /sequence/nodes/{nodeId} route. Type is immutable after creation — to change it, delete and re-add. Every mutation on this collection is backed by an atomic Postgres RPC with row-level locking, so concurrent adds, moves, and deletes can’t corrupt the position ordering.

AI agent notes

Typical build order.
  1. POST /api/campaigns to create a draft.
  2. Loop over your desired nodes and POST /api/campaigns/{id}/sequence/nodes for each — omit position and every node lands just before the auto-inserted terminal end.
  3. When done, POST /api/campaigns/{id}/launch.
Channel validation. The parent campaign’s type determines which node kinds are legal:
  • linkedin campaigns accept connection_request, message, delay, ai, end.
  • email campaigns accept email, delay, ai, end.
Read-back fallback. The response is normally { sequence_nodes: [...] } — the full list, already ordered. On the rare occasion the post-mutation read-back fails, the server returns { mutated: true, node_id }. In that case refetch via GET /api/campaigns/{id}.Position omitted = before the end. Don’t set position unless you specifically need to insert somewhere other than the natural end-of-sequence slot. The server handles ordering.AI nodes. Adding { type: "ai" } creates the base row; populate purpose and output_type with a follow-up PUT /api/campaigns/{id}/sequence/nodes/{nodeId} call.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

id
string
required

Campaign UUID

Body

application/json
type
enum<string>
required
Available options:
connection_request,
message,
email,
delay,
ai,
end
position
integer | null
Required range: 0 <= x <= 9007199254740991
subject
string | null
body
string | null
signature
string | null
include_message
boolean | null
is_reply
boolean | null
delay_days
integer | null
Required range: 0 <= x <= 9007199254740991
delay_hours
integer | null
Required range: 0 <= x <= 9007199254740991
delay_minutes
integer | null
Required range: 0 <= x <= 9007199254740991
{key}
any

Response

Node inserted. Returns the fresh ordered list, or a mutation fallback when read-back fails.

sequence_nodes
object[]
required