curl --request PATCH \
--url https://api.sidenet.ai/v1/workflows/{id}/draft \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"definition": {
"steps": {
"classify": {
"kind": "agent",
"config": {
"prompt": "Classify the request.",
"model_slug": "openai/gpt-4o-mini"
}
}
},
"output_text": "Classified as {{ $.steps.classify.category }}."
},
"input_schema": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
},
"required": [
"text"
]
},
"output_schema": {
"type": "object",
"properties": {
"category": {
"type": "string"
}
}
},
"name": "Classify support requests",
"description": "Routes each incoming request to a category."
}
'import requests
url = "https://api.sidenet.ai/v1/workflows/{id}/draft"
payload = {
"definition": {
"steps": { "classify": {
"kind": "agent",
"config": {
"prompt": "Classify the request.",
"model_slug": "openai/gpt-4o-mini"
}
} },
"output_text": "Classified as {{ $.steps.classify.category }}."
},
"input_schema": {
"type": "object",
"properties": { "text": { "type": "string" } },
"required": ["text"]
},
"output_schema": {
"type": "object",
"properties": { "category": { "type": "string" } }
},
"name": "Classify support requests",
"description": "Routes each incoming request to a category."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
definition: {
steps: {
classify: {
kind: 'agent',
config: {prompt: 'Classify the request.', model_slug: 'openai/gpt-4o-mini'}
}
},
output_text: 'Classified as {{ $.steps.classify.category }}.'
},
input_schema: {type: 'object', properties: {text: {type: 'string'}}, required: ['text']},
output_schema: {type: 'object', properties: {category: {type: 'string'}}},
name: 'Classify support requests',
description: 'Routes each incoming request to a category.'
})
};
fetch('https://api.sidenet.ai/v1/workflows/{id}/draft', 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.sidenet.ai/v1/workflows/{id}/draft",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'definition' => [
'steps' => [
'classify' => [
'kind' => 'agent',
'config' => [
'prompt' => 'Classify the request.',
'model_slug' => 'openai/gpt-4o-mini'
]
]
],
'output_text' => 'Classified as {{ $.steps.classify.category }}.'
],
'input_schema' => [
'type' => 'object',
'properties' => [
'text' => [
'type' => 'string'
]
],
'required' => [
'text'
]
],
'output_schema' => [
'type' => 'object',
'properties' => [
'category' => [
'type' => 'string'
]
]
],
'name' => 'Classify support requests',
'description' => 'Routes each incoming request to a category.'
]),
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://api.sidenet.ai/v1/workflows/{id}/draft"
payload := strings.NewReader("{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.sidenet.ai/v1/workflows/{id}/draft")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/workflows/{id}/draft")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}"
response = http.request(request)
puts response.read_body{
"workflow": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"active_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner_kind": "org",
"owner_external_id": "<string>"
},
"draft": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"version_number": 123,
"rev": 123,
"definition": {},
"input_schema": {},
"output_schema": {},
"change_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}Save workflow draft
Partial save of the draft definition/schemas. Runs structural validation only — work-in-progress graphs are allowed. output_schema is optional and NOT enforced at run time — leave it unset unless you need a declared boundary contract; the actual output shape is whatever the last flow position returns (see the step-level schemas: tool outputSchema, agent step output_schema). name and description are the workflow’s own, not the draft’s: they are saved here for convenience but apply immediately to every version, published ones included, and need no publish. The response carries the updated workflow alongside the draft.
curl --request PATCH \
--url https://api.sidenet.ai/v1/workflows/{id}/draft \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"definition": {
"steps": {
"classify": {
"kind": "agent",
"config": {
"prompt": "Classify the request.",
"model_slug": "openai/gpt-4o-mini"
}
}
},
"output_text": "Classified as {{ $.steps.classify.category }}."
},
"input_schema": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
},
"required": [
"text"
]
},
"output_schema": {
"type": "object",
"properties": {
"category": {
"type": "string"
}
}
},
"name": "Classify support requests",
"description": "Routes each incoming request to a category."
}
'import requests
url = "https://api.sidenet.ai/v1/workflows/{id}/draft"
payload = {
"definition": {
"steps": { "classify": {
"kind": "agent",
"config": {
"prompt": "Classify the request.",
"model_slug": "openai/gpt-4o-mini"
}
} },
"output_text": "Classified as {{ $.steps.classify.category }}."
},
"input_schema": {
"type": "object",
"properties": { "text": { "type": "string" } },
"required": ["text"]
},
"output_schema": {
"type": "object",
"properties": { "category": { "type": "string" } }
},
"name": "Classify support requests",
"description": "Routes each incoming request to a category."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
definition: {
steps: {
classify: {
kind: 'agent',
config: {prompt: 'Classify the request.', model_slug: 'openai/gpt-4o-mini'}
}
},
output_text: 'Classified as {{ $.steps.classify.category }}.'
},
input_schema: {type: 'object', properties: {text: {type: 'string'}}, required: ['text']},
output_schema: {type: 'object', properties: {category: {type: 'string'}}},
name: 'Classify support requests',
description: 'Routes each incoming request to a category.'
})
};
fetch('https://api.sidenet.ai/v1/workflows/{id}/draft', 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.sidenet.ai/v1/workflows/{id}/draft",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'definition' => [
'steps' => [
'classify' => [
'kind' => 'agent',
'config' => [
'prompt' => 'Classify the request.',
'model_slug' => 'openai/gpt-4o-mini'
]
]
],
'output_text' => 'Classified as {{ $.steps.classify.category }}.'
],
'input_schema' => [
'type' => 'object',
'properties' => [
'text' => [
'type' => 'string'
]
],
'required' => [
'text'
]
],
'output_schema' => [
'type' => 'object',
'properties' => [
'category' => [
'type' => 'string'
]
]
],
'name' => 'Classify support requests',
'description' => 'Routes each incoming request to a category.'
]),
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://api.sidenet.ai/v1/workflows/{id}/draft"
payload := strings.NewReader("{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.sidenet.ai/v1/workflows/{id}/draft")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/workflows/{id}/draft")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"definition\": {\n \"steps\": {\n \"classify\": {\n \"kind\": \"agent\",\n \"config\": {\n \"prompt\": \"Classify the request.\",\n \"model_slug\": \"openai/gpt-4o-mini\"\n }\n }\n },\n \"output_text\": \"Classified as {{ $.steps.classify.category }}.\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"text\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"text\"\n ]\n },\n \"output_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": \"Classify support requests\",\n \"description\": \"Routes each incoming request to a category.\"\n}"
response = http.request(request)
puts response.read_body{
"workflow": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"active_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner_kind": "org",
"owner_external_id": "<string>"
},
"draft": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"version_number": 123,
"rev": 123,
"definition": {},
"input_schema": {},
"output_schema": {},
"change_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}Authorizations
Organization API key, generated in studio.sidenet.ai. Backend only — never in a browser.
Path Parameters
"4c2f9e18-7a63-4d05-b1e8-93a7c0f2d641"
Body
The steps + flow graph. Validate it against GET /v1/workflows/definition-schema. Its optional top-level output_text is the result-message template posted after a successful run — {{ $.input. }} / {{ $.steps.. }} placeholders resolve against the run. Omitted, the built-in result summary writes the message: a model reads the run and writes the answer, rendering rich-UI components; steer it with output_summary.instructions, or disable it with output_summary.enabled: false for a plain completion notice with the output attached.
{
"steps": {
"classify": {
"kind": "agent",
"config": {
"prompt": "Classify the request.",
"model_slug": "openai/gpt-4o-mini"
}
}
},
"output_text": "Classified as {{ $.steps.classify.category }}."
}
{
"type": "object",
"properties": { "text": { "type": "string" } },
"required": ["text"]
}
{
"type": "object",
"properties": { "category": { "type": "string" } }
}
The workflow's name. Workflow-level, not versioned — it takes effect immediately, with no publish.
"Classify support requests"
The workflow's description. Workflow-level, not versioned — same immediate effect as name. Send null to clear it.
"Routes each incoming request to a category."
Response
The saved draft
The workflow row, reflecting any name / description change in this save.
Show child attributes
Show child attributes
The whole draft after the merge, not just the fields you sent. rev has been bumped by the DB. Saving does not publish: the active version keeps running until POST /v1/workflows/{id}/publish and /activate.
Show child attributes
Show child attributes