curl --request PUT \
--url https://your-instance.example.com/api/workflows/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "New Lead Welcome (v2)",
"description": "Greet new leads, assign an agent, and create a follow-up task.",
"enabled": true
}
'import requests
url = "https://your-instance.example.com/api/workflows/{id}"
payload = {
"name": "New Lead Welcome (v2)",
"description": "Greet new leads, assign an agent, and create a follow-up task.",
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'New Lead Welcome (v2)',
description: 'Greet new leads, assign an agent, and create a follow-up task.',
enabled: true
})
};
fetch('https://your-instance.example.com/api/workflows/{id}', 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://your-instance.example.com/api/workflows/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'New Lead Welcome (v2)',
'description' => 'Greet new leads, assign an agent, and create a follow-up task.',
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-instance.example.com/api/workflows/{id}"
payload := strings.NewReader("{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://your-instance.example.com/api/workflows/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/workflows/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Workflow created successfully",
"data": {
"_id": "64d2f9c5e8a1d4e001a0b1c2",
"name": "New Lead Welcome",
"description": "Greet new leads and assign them to a leasing agent.",
"organizationId": "64a1b2c3d4e5f60012345678",
"userId": "64a1b2c3d4e5f60012345679",
"nodes": [],
"edges": [],
"viewport": {
"x": 0,
"y": 0,
"zoom": 1
},
"enabled": false,
"createdAt": "2026-04-12T14:22:10.000Z",
"updatedAt": "2026-04-12T14:22:10.000Z"
}
}{
"success": false,
"message": "Workflow not found"
}{
"success": false,
"message": "Workflow not found"
}Update a workflow
Updates editable fields on a Workflow scoped to the caller organization. Nodes, edges, viewport, name, description, and enabled flag are all replaceable. Renames must keep the name unique within the organization.
curl --request PUT \
--url https://your-instance.example.com/api/workflows/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "New Lead Welcome (v2)",
"description": "Greet new leads, assign an agent, and create a follow-up task.",
"enabled": true
}
'import requests
url = "https://your-instance.example.com/api/workflows/{id}"
payload = {
"name": "New Lead Welcome (v2)",
"description": "Greet new leads, assign an agent, and create a follow-up task.",
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'New Lead Welcome (v2)',
description: 'Greet new leads, assign an agent, and create a follow-up task.',
enabled: true
})
};
fetch('https://your-instance.example.com/api/workflows/{id}', 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://your-instance.example.com/api/workflows/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'New Lead Welcome (v2)',
'description' => 'Greet new leads, assign an agent, and create a follow-up task.',
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-instance.example.com/api/workflows/{id}"
payload := strings.NewReader("{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://your-instance.example.com/api/workflows/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/workflows/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"New Lead Welcome (v2)\",\n \"description\": \"Greet new leads, assign an agent, and create a follow-up task.\",\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Workflow created successfully",
"data": {
"_id": "64d2f9c5e8a1d4e001a0b1c2",
"name": "New Lead Welcome",
"description": "Greet new leads and assign them to a leasing agent.",
"organizationId": "64a1b2c3d4e5f60012345678",
"userId": "64a1b2c3d4e5f60012345679",
"nodes": [],
"edges": [],
"viewport": {
"x": 0,
"y": 0,
"zoom": 1
},
"enabled": false,
"createdAt": "2026-04-12T14:22:10.000Z",
"updatedAt": "2026-04-12T14:22:10.000Z"
}
}{
"success": false,
"message": "Workflow not found"
}{
"success": false,
"message": "Workflow not found"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Partial update — only the supplied fields are written; omitted fields are left untouched.
New workflow name. Must remain unique within the caller organization.
Replacement free-text description. Send an empty string to clear.
Replacement node array — fully overwrites the current canvas nodes when supplied.
Replacement edge array — fully overwrites the current canvas edges when supplied.
Replacement camera state (x, y, zoom) for the canvas.
Show child attributes
Show child attributes
When false, the trigger system skips this workflow even when conditions match.
Response
Workflow updated successfully
Returned by create/update/toggle. Wraps the resulting WorkflowDocument plus a status message.
true A Workflow document — visual builder canvas (nodes + edges) plus enabled flag and metadata.
Show child attributes
Show child attributes
{
"_id": "64d2f9c5e8a1d4e001a0b1c2",
"name": "New Lead Welcome",
"description": "Greet new leads and assign them to a leasing agent.",
"organizationId": "64a1b2c3d4e5f60012345678",
"userId": "64a1b2c3d4e5f60012345679",
"nodes": [
{
"id": "n1",
"type": "trigger",
"position": { "x": 50, "y": 50 },
"data": { "event": "application.created" }
},
{
"id": "n2",
"type": "sendMessage",
"position": { "x": 250, "y": 50 },
"data": { "template": "welcome-sms" }
}
],
"edges": [
{
"id": "e1",
"source": "n1",
"target": "n2"
}
],
"viewport": { "x": 0, "y": 0, "zoom": 1 },
"enabled": true,
"createdAt": "2026-04-12T14:22:10.000Z",
"updatedAt": "2026-04-22T10:14:00.000Z"
}