curl --request POST \
--url https://api.sidenet.ai/v1/workflows/{id}/run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": {
"text": "My order never arrived"
},
"groupId": "grp_84f20c19",
"groupName": "Acme — production",
"runtimeAuth": {
"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63": {
"token": "per-request CRM token"
}
},
"stream": false,
"notify_thread": false,
"thread_title": "Refund triage — 21 Aug"
}
'import requests
url = "https://api.sidenet.ai/v1/workflows/{id}/run"
payload = {
"input": { "text": "My order never arrived" },
"groupId": "grp_84f20c19",
"groupName": "Acme — production",
"runtimeAuth": { "8d3b1a75-6c02-4e59-b84f-27a9d5e10c63": { "token": "per-request CRM token" } },
"stream": False,
"notify_thread": False,
"thread_title": "Refund triage — 21 Aug"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: {text: 'My order never arrived'},
groupId: 'grp_84f20c19',
groupName: 'Acme — production',
runtimeAuth: {'8d3b1a75-6c02-4e59-b84f-27a9d5e10c63': {token: 'per-request CRM token'}},
stream: false,
notify_thread: false,
thread_title: 'Refund triage — 21 Aug'
})
};
fetch('https://api.sidenet.ai/v1/workflows/{id}/run', 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}/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'input' => [
'text' => 'My order never arrived'
],
'groupId' => 'grp_84f20c19',
'groupName' => 'Acme — production',
'runtimeAuth' => [
'8d3b1a75-6c02-4e59-b84f-27a9d5e10c63' => [
'token' => 'per-request CRM token'
]
],
'stream' => false,
'notify_thread' => false,
'thread_title' => 'Refund triage — 21 Aug'
]),
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}/run"
payload := strings.NewReader("{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.sidenet.ai/v1/workflows/{id}/run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/workflows/{id}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}"
response = http.request(request)
puts response.read_body{
"status": "completed",
"environment": "production",
"version": 2,
"traceId": "0af7651916cd43dd8448eb211c80319c",
"run_id": "ee9f71cb-8981-4fde-a6cc-b3c98c7add97",
"result": {
"category": "refund",
"orderId": "ord_10482"
},
"text": null
}Run workflow
Runs a workflow version. ?version=active (default), draft, or v{n}. Body: { input, groupId?, groupName?, runtimeAuth? } — input is the workflow input, groupId/groupName select the group the run is attributed to (like /v1/chat), and runtimeAuth supplies per-request credentials for tool steps (custom + MCP). Drafts are validated at run time and rejected with 422 if invalid. The run executes as an end user: call it with that user’s session token. Pass stream: true to receive Server-Sent Events instead of a single JSON body: each workflow stream event is emitted as a data: line, and the stream ends with a run-complete event carrying the same payload as the non-streaming response (run-error on failure). Pre-run errors (400/404/422) are returned as plain JSON either way. Every response carries run_id, the run’s row in the run log — read it back later with GET /v1/workflow-runs/{run_id} (its output, text, status and trace). result.runId is the same value.
curl --request POST \
--url https://api.sidenet.ai/v1/workflows/{id}/run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": {
"text": "My order never arrived"
},
"groupId": "grp_84f20c19",
"groupName": "Acme — production",
"runtimeAuth": {
"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63": {
"token": "per-request CRM token"
}
},
"stream": false,
"notify_thread": false,
"thread_title": "Refund triage — 21 Aug"
}
'import requests
url = "https://api.sidenet.ai/v1/workflows/{id}/run"
payload = {
"input": { "text": "My order never arrived" },
"groupId": "grp_84f20c19",
"groupName": "Acme — production",
"runtimeAuth": { "8d3b1a75-6c02-4e59-b84f-27a9d5e10c63": { "token": "per-request CRM token" } },
"stream": False,
"notify_thread": False,
"thread_title": "Refund triage — 21 Aug"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: {text: 'My order never arrived'},
groupId: 'grp_84f20c19',
groupName: 'Acme — production',
runtimeAuth: {'8d3b1a75-6c02-4e59-b84f-27a9d5e10c63': {token: 'per-request CRM token'}},
stream: false,
notify_thread: false,
thread_title: 'Refund triage — 21 Aug'
})
};
fetch('https://api.sidenet.ai/v1/workflows/{id}/run', 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}/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'input' => [
'text' => 'My order never arrived'
],
'groupId' => 'grp_84f20c19',
'groupName' => 'Acme — production',
'runtimeAuth' => [
'8d3b1a75-6c02-4e59-b84f-27a9d5e10c63' => [
'token' => 'per-request CRM token'
]
],
'stream' => false,
'notify_thread' => false,
'thread_title' => 'Refund triage — 21 Aug'
]),
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}/run"
payload := strings.NewReader("{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.sidenet.ai/v1/workflows/{id}/run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/workflows/{id}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": {\n \"text\": \"My order never arrived\"\n },\n \"groupId\": \"grp_84f20c19\",\n \"groupName\": \"Acme — production\",\n \"runtimeAuth\": {\n \"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63\": {\n \"token\": \"per-request CRM token\"\n }\n },\n \"stream\": false,\n \"notify_thread\": false,\n \"thread_title\": \"Refund triage — 21 Aug\"\n}"
response = http.request(request)
puts response.read_body{
"status": "completed",
"environment": "production",
"version": 2,
"traceId": "0af7651916cd43dd8448eb211c80319c",
"run_id": "ee9f71cb-8981-4fde-a6cc-b3c98c7add97",
"result": {
"category": "refund",
"orderId": "ord_10482"
},
"text": null
}Authorizations
Session token (snat_…) minted by POST /v1/token. Carries the organization and the end user; safe in a browser.
Path Parameters
"4c2f9e18-7a63-4d05-b1e8-93a7c0f2d641"
Query Parameters
active (default) | draft | v{n}
Body
The workflow input: an object whose keys are the fields the version's input_schema declares (validated against that schema by the run). Omit it to run with {}.
Show child attributes
Show child attributes
{ "text": "My order never arrived" }
Optional stable caller-supplied group id. When sent, group matching is by this id; a differing groupName renames the group.
1 - 255"grp_84f20c19"
Optional group name. Without groupId this matches by name; alongside groupId it is display-only (rename on change).
"Acme — production"
Runtime authentication map: { [providerNameOrId]: { credentials } } — used by tool steps (custom + MCP)
Show child attributes
Show child attributes
{
"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63": { "token": "per-request CRM token" }
}
When true, respond with Server-Sent Events: one data: line per workflow stream event (step start/output/result, nested agent events, …), ending with a run-complete (or run-error) event that carries the same payload as the non-streaming JSON response.
false
When true (active version only), the run also files its result as a new conversation in the user's thread list — exactly like a scheduled run: pre-titled, marked unread, with the inputs, the output and the run's text output. The response then carries run_id and thread_id; stream is ignored. Use it to trigger a workflow from your own UI without a chat turn.
false
With notify_thread: the conversation title (default " — ").
1 - 200"Refund triage — 21 Aug"
Response
Run completed (JSON), or — with stream: true — a text/event-stream of workflow events ending in run-complete/run-error. The run-complete event carries exactly the JSON body documented here.
completed. A failed run answers 500 with {error, details}.
Which environment the run was attributed to.
The version number that ran — 0 when you ran the draft.
Correlates this run with its observability trace. Also returned as the X-Request-Id / X-Trace-Id response headers.
The workflow's own output, shaped by the version's output_schema — so this varies per workflow. Steps that produce no output leave it empty. Its runId is the same id as run_id below.
The run's row in the run log: GET /v1/workflow-runs/{run_id} returns its status, output, text and request id. Present on every response — success or failure, any version, streaming (run-complete / run-error) or not — and real as soon as the response arrives (the row is opened before the run starts). The same value as result.runId. Null only when the run log could not be written.
With notify_thread: the conversation the result was filed in.
The run's text output. With notify_thread: the text posted to the thread — the workflow's output_text rendered against this run, else a completion notice with the output attached. Without it: the rendered output_text, or null when the version declares none.