Building a webhook integration? Read the webhook guide for signatures, retries, event schemas, and troubleshooting.
apiDeterministic

Update campaign workflow

PUT /api/campaigns/{campaignId}/workflow

Replace the complete delivery graph of an exact draft campaign. Read get-campaign first and pass its updated_at as expectedUpdatedAt. Saves the graph in Advanced Mode so old Easy Mode steps cannot return. Rejects stale edits and non-draft campaigns. Does not start the campaign or send anything. Use this to remove unwanted steps; update-workflow edits separate Agent Workflows. Campaign delivery graphs are distinct from Agent Workflows. Supply the complete nodes and edges to create-campaign or update-campaign-workflow. Start -> optional icp_scoring -> outreach. If scoring is present, all outreach paths must pass qualified; not_qualified ends without sending. Scoring must precede all sends or email campaign pushes. connection_request has accepted and no_response outputs. accepted continues to optional messages or End. no_response fires after wait_for_response_days and can go to optional cancel_invitation -> End, or an explicitly requested InMail/email fallback. Never withdraw an accepted invitation. message, template_message, enhanced_message and inmail have replied and no_reply outputs. Every replied output goes directly to End. no_reply waits reply_wait_days, then goes to an optional follow-up or End. Do not add a second delay for that same waiting period. Withdrawal, scoring, InMail, follow-ups and email destinations are optional; never add them unless requested. A connection-only graph wires accepted and no_response to End. instantly, smartlead and emailbison require credential_id and campaign_id for the selected external campaign. InMail requires a Sales Navigator sender; open profiles can use free InMail subject to provider limits. No cycles, dangling outputs or unreachable nodes. Every branch terminates at End. Saving creates a draft only; inspect the saved graph and obtain launch authorization before starting.

Parameters

workspaceId
string
Optional workspace ID or slug. Required when this credential can access multiple workspaces and no workspace was configured on the client.
workflow_definitionrequired
object
Campaign delivery graphs are distinct from Agent Workflows. Supply the complete nodes and edges to create-campaign or update-campaign-workflow. Start -> optional icp_scoring -> outreach. If scoring is present, all outreach paths must pass qualified; not_qualified ends without sending. Scoring must precede all sends or email campaign pushes. connection_request has accepted and no_response outputs. accepted continues to optional messages or End. no_response fires after wait_for_response_days and can go to optional cancel_invitation -> End, or an explicitly requested InMail/email fallback. Never withdraw an accepted invitation. message, template_message, enhanced_message and inmail have replied and no_reply outputs. Every replied output goes directly to End. no_reply waits reply_wait_days, then goes to an optional follow-up or End. Do not add a second delay for that same waiting period. Withdrawal, scoring, InMail, follow-ups and email destinations are optional; never add them unless requested. A connection-only graph wires accepted and no_response to End. instantly, smartlead and emailbison require credential_id and campaign_id for the selected external campaign. InMail requires a Sales Navigator sender; open profiles can use free InMail subject to provider limits. No cycles, dangling outputs or unreachable nodes. Every branch terminates at End. Saving creates a draft only; inspect the saved graph and obtain launch authorization before starting.
expectedUpdatedAtrequired
string
No description.
campaignIdrequired
string
No description.

Example

REST requestbash
curl -X PUT "https://app.pipeline.help/api/campaigns/00000000-0000-4000-8000-000000000000/workflow" \
-H "Authorization: Bearer $PIPELINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"workflow_definition":{"nodes":[{"id":"00000000-0000-4000-8000-000000000000","type":"start","position":{"x":1,"y":1},"data":{}}],"edges":[{"id":"00000000-0000-4000-8000-000000000000","source":"example","target":"example"}]},"expectedUpdatedAt":"2026-01-01T00:00:00.000Z"}'

Response

Success response schemajson schema
{
"type": "object",
"properties": {
"campaign": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"draft",
"active",
"paused",
"completed",
"scheduled",
"preparing",
"preparing_review"
]
},
"total_prospects": {
"type": "number"
},
"prospects_completed": {
"type": "number"
},
"prospects_active": {
"type": "number"
},
"auto_generated": {
"type": "boolean"
},
"source_tracker_id": {
"type": [
"string",
"null"
]
},
"brief_id": {
"type": [
"string",
"null"
]
},
"created_by": {
"type": "string"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"workflow_definition": {
"type": "object",
"properties": {
"nodes": {
"type": "array",
"items": {
"type": "object"
}
},
"edges": {
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"nodes",
"edges"
]
},
"assigned_accounts": {
"type": "array",
"items": {
"type": "string"
}
},
"started_at": {
"type": "string"
},
"completed_at": {
"type": "string"
},
"archived_at": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"workspace_id",
"name",
"status"
]
}
},
"required": [
"campaign"
]
}

HTTP errors

401
Missing or invalid API key.
403
Authenticated but not permitted for the workspace or resource.
404
The requested resource was not found.
Pipeline REST API reference | Pipeline