Remove a workflow node
Removes one action node from its outcome chain and re-links around it: the node before it is joined to the node after it, so the chain survives. Branch (if) nodes, and nodes that lead to more than one next step, cannot be removed here. Remove them in the dashboard workflow editor or with PUT /workflow.
Required API key scope: campaign_workflows:write.
DELETE
/
api
/
agent-builder
/
agents
/
{id}
/
campaign
/
workflow
/
nodes
/
{nodeId}
cURL
curl --request DELETE \
--url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId} \
--header 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"workflow": {
"locationId": "loc_abc123",
"campaignId": "cmp_123",
"campaignConfig": {
"callbackMode": "ai"
},
"nodes": {
"tag_booked": {
"id": "tag_booked",
"type": "add-tag",
"config": {
"tags": [
"booked_via_ai"
]
}
},
"sms_reminder": {
"id": "sms_reminder",
"type": "send-sms",
"config": {
"message": "Thanks for booking! See you soon."
}
}
},
"edges": [
{
"id": "e_booked",
"source": "tag_booked",
"target": "sms_reminder"
}
],
"dispositionEntries": {
"SUCCESS": "tag_booked"
},
"version": 3,
"createdAt": "2026-07-01T09:15:22.000Z",
"updatedAt": "2026-07-14T16:04:11.000Z"
}
}{
"success": false,
"error": "VALIDATION",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "InsufficientScope",
"message": "This access key does not allow this action. Please ask your account admin to change its permissions.",
"requiredScope": "campaign_workflows:write"
}{
"success": false,
"error": "NOT_FOUND",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "CONFLICT",
"message": "This changed while you were working on it. Please refresh and try again."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}Authorizations
Path Parameters
Query Parameters
Response
The updated workflow.
⌘I
cURL
curl --request DELETE \
--url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId} \
--header 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow/nodes/{nodeId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"workflow": {
"locationId": "loc_abc123",
"campaignId": "cmp_123",
"campaignConfig": {
"callbackMode": "ai"
},
"nodes": {
"tag_booked": {
"id": "tag_booked",
"type": "add-tag",
"config": {
"tags": [
"booked_via_ai"
]
}
},
"sms_reminder": {
"id": "sms_reminder",
"type": "send-sms",
"config": {
"message": "Thanks for booking! See you soon."
}
}
},
"edges": [
{
"id": "e_booked",
"source": "tag_booked",
"target": "sms_reminder"
}
],
"dispositionEntries": {
"SUCCESS": "tag_booked"
},
"version": 3,
"createdAt": "2026-07-01T09:15:22.000Z",
"updatedAt": "2026-07-14T16:04:11.000Z"
}
}{
"success": false,
"error": "VALIDATION",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "InsufficientScope",
"message": "This access key does not allow this action. Please ask your account admin to change its permissions.",
"requiredScope": "campaign_workflows:write"
}{
"success": false,
"error": "NOT_FOUND",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "CONFLICT",
"message": "This changed while you were working on it. Please refresh and try again."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}