Insert a new node into a draft campaign’s sequence. Also the home page for moving and deleting nodes on the same collection.
status === "draft".
This collection exposes three verbs:
| Verb | Operation | Purpose |
|---|---|---|
POST | addSequenceNode | Insert a new node (this page). Omit position to drop it right before the terminal end node. |
PATCH | moveSequenceNode | Reorder an existing node — see Move a sequence node. |
DELETE | deleteSequenceNode | Remove a node — see Delete a sequence node. |
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.
POST /api/campaigns to create a draft.POST /api/campaigns/{id}/sequence/nodes for each — omit position and every node lands just before the auto-inserted terminal end.POST /api/campaigns/{id}/launch.type determines which node kinds are legal:linkedin campaigns accept connection_request, message, delay, ai, end.email campaigns accept email, delay, ai, end.{ 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.Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Campaign UUID
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Draft-only. Any caller-supplied id is stripped — the server generates the node UUID. Extra fields are tolerated and forwarded to the RPC.
Kind of node to create. Required. Channel must match the parent campaign.
connection_request, message, email, delay, ai, end 0-indexed insert position. If omitted or null, the node is inserted immediately before the terminal end node.
0 <= x <= 9007199254740991Email subject template. email nodes only.
Message body template — supports %first_name%, %company%, etc. Used by connection_request, message, and email nodes.
connection_request only. If true, the invite includes a message body (<=300 chars).
email only. If true, the email is sent as a reply on the previous email's thread.
delay only. Days to wait before advancing.
0 <= x <= 9007199254740991delay only. Hours to wait before advancing.
0 <= x <= 9007199254740991delay only. Minutes to wait before advancing.
0 <= x <= 9007199254740991Node inserted. Returns the fresh ordered list of sequence nodes. If the post-mutation read-back fails, falls back to { mutated: true, node_id }.
Successful mutation response. The server re-fetches the full sequence and returns it so clients don't have to round-trip a GET.
Fresh ordered list of nodes after the mutation. Absent (replaced by mutated: true + optional node_id) only if the server's best-effort read-back after the mutation failed.