API Docs

workflows

AdminUpdated Sep 19, 2026
GEThttps://api.chatlychat.com/v1/workflows
List workflows in the workspace (cursor-paginated; ?sort= / ?fields= / ?filter[]= supported)
Parameters
NameInTypeRequiredDescription
qquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows?q=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows?q=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows?q=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows?q=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows?q=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows?q=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows?q="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows
Create or update a workflow
Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "id": "string",
  "name": "string",
  "description": "string",
  "enabled": false,
  "triggerType": "string",
  "triggerConfig": {},
  "graph": {
    "nodes": [
      {
        "id": "string",
        "type": "send_message",
        "params": {}
      }
    ],
    "edges": [
      {
        "from": "string",
        "to": "string",
        "when": "string"
      }
    ]
  },
  "triggerKind": "single",
  "compoundConfig": {
    "events": [
      "string"
    ],
    "windowSeconds": 0,
    "groupingKey": "contact"
  },
  "folderId": "string",
  "tags": [
    "string"
  ],
  "rateLimitConfig": {
    "maxRunsPerMinute": 0,
    "maxRunsPerHour": 0,
    "maxRunsPerDay": 0,
    "maxLlmCostCentsPerDay": 0
  },
  "alertConfig": {
    "onFailureRateAbove": 0,
    "windowMinutes": 5,
    "minRunsInWindow": 10,
    "channels": [
      "string"
    ]
  }
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"id":"string","name":"string","description":"string","enabled":false,"triggerType":"string","triggerConfig":{},"graph":{"nodes":[{"id":"string","type":"send_message","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}]},"triggerKind":"single","compoundConfig":{"events":["string"],"windowSeconds":0,"groupingKey":"contact"},"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"id":"string","name":"string","description":"string","enabled":false,"triggerType":"string","triggerConfig":{},"graph":{"nodes":[{"id":"string","type":"send_message","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}]},"triggerKind":"single","compoundConfig":{"events":["string"],"windowSeconds":0,"groupingKey":"contact"},"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"id": "string", "name": "string", "description": "string", "enabled": False, "triggerType": "string", "triggerConfig": {}, "graph": {"nodes": [{"id": "string", "type": "send_message", "params": {}}], "edges": [{"from": "string", "to": "string", "when": "string"}]}, "triggerKind": "single", "compoundConfig": {"events": ["string"], "windowSeconds": 0, "groupingKey": "contact"}, "folderId": "string", "tags": ["string"], "rateLimitConfig": {"maxRunsPerMinute": 0, "maxRunsPerHour": 0, "maxRunsPerDay": 0, "maxLlmCostCentsPerDay": 0}, "alertConfig": {"onFailureRateAbove": 0, "windowMinutes": 5, "minRunsInWindow": 10, "channels": ["string"]}},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows", strings.NewReader(`{"id":"string","name":"string","description":"string","enabled":false,"triggerType":"string","triggerConfig":{},"graph":{"nodes":[{"id":"string","type":"send_message","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}]},"triggerKind":"single","compoundConfig":{"events":["string"],"windowSeconds":0,"groupingKey":"contact"},"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"id":"string","name":"string","description":"string","enabled":false,"triggerType":"string","triggerConfig":{},"graph":{"nodes":[{"id":"string","type":"send_message","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}]},"triggerKind":"single","compoundConfig":{"events":["string"],"windowSeconds":0,"groupingKey":"contact"},"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"id":"string","name":"string","description":"string","enabled":false,"triggerType":"string","triggerConfig":{},"graph":{"nodes":[{"id":"string","type":"send_message","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}]},"triggerKind":"single","compoundConfig":{"events":["string"],"windowSeconds":0,"groupingKey":"contact"},"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"enabled\":false,\"triggerType\":\"string\",\"triggerConfig\":{},\"graph\":{\"nodes\":[{\"id\":\"string\",\"type\":\"send_message\",\"params\":{}}],\"edges\":[{\"from\":\"string\",\"to\":\"string\",\"when\":\"string\"}]},\"triggerKind\":\"single\",\"compoundConfig\":{\"events\":[\"string\"],\"windowSeconds\":0,\"groupingKey\":\"contact\"},\"folderId\":\"string\",\"tags\":[\"string\"],\"rateLimitConfig\":{\"maxRunsPerMinute\":0,\"maxRunsPerHour\":0,\"maxRunsPerDay\":0,\"maxLlmCostCentsPerDay\":0},\"alertConfig\":{\"onFailureRateAbove\":0,\"windowMinutes\":5,\"minRunsInWindow\":10,\"channels\":[\"string\"]}}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
DELETEhttps://api.chatlychat.com/v1/workflows/{workflowId}
Delete a workflow (hard-delete; cascades runs / revisions / permissions)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
204
Code samples
cURL
curl -X DELETE "https://api.chatlychat.com/v1/workflows/{workflowId}" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}', {
  method: 'DELETE',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "DELETE",
    "https://api.chatlychat.com/v1/workflows/{workflowId}",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.chatlychat.com/v1/workflows/{workflowId}", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}')
req = Net::HTTP::Delete.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}"))
    .header("Idempotency-Key", "<value>")
    .method("DELETE", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
PATCHhttps://api.chatlychat.com/v1/workflows/{workflowId}
Patch a workflow (partial update — rate caps, folder, tags, …)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "name": "string",
  "description": "string",
  "enabled": true,
  "folderId": "string",
  "tags": [
    "string"
  ],
  "rateLimitConfig": {
    "maxRunsPerMinute": 0,
    "maxRunsPerHour": 0,
    "maxRunsPerDay": 0,
    "maxLlmCostCentsPerDay": 0
  },
  "alertConfig": {
    "onFailureRateAbove": 0,
    "windowMinutes": 5,
    "minRunsInWindow": 10,
    "channels": [
      "string"
    ]
  }
}
Responses
200
Code samples
cURL
curl -X PATCH "https://api.chatlychat.com/v1/workflows/{workflowId}" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","description":"string","enabled":true,"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}', {
  method: 'PATCH',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"name":"string","description":"string","enabled":true,"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "PATCH",
    "https://api.chatlychat.com/v1/workflows/{workflowId}",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"name": "string", "description": "string", "enabled": True, "folderId": "string", "tags": ["string"], "rateLimitConfig": {"maxRunsPerMinute": 0, "maxRunsPerHour": 0, "maxRunsPerDay": 0, "maxLlmCostCentsPerDay": 0}, "alertConfig": {"onFailureRateAbove": 0, "windowMinutes": 5, "minRunsInWindow": 10, "channels": ["string"]}},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("PATCH", "https://api.chatlychat.com/v1/workflows/{workflowId}", strings.NewReader(`{"name":"string","description":"string","enabled":true,"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name":"string","description":"string","enabled":true,"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}')
req = Net::HTTP::Patch.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"name":"string","description":"string","enabled":true,"folderId":"string","tags":["string"],"rateLimitConfig":{"maxRunsPerMinute":0,"maxRunsPerHour":0,"maxRunsPerDay":0,"maxLlmCostCentsPerDay":0},"alertConfig":{"onFailureRateAbove":0,"windowMinutes":5,"minRunsInWindow":10,"channels":["string"]}}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("PATCH", BodyPublishers.ofString("{\"name\":\"string\",\"description\":\"string\",\"enabled\":true,\"folderId\":\"string\",\"tags\":[\"string\"],\"rateLimitConfig\":{\"maxRunsPerMinute\":0,\"maxRunsPerHour\":0,\"maxRunsPerDay\":0,\"maxLlmCostCentsPerDay\":0},\"alertConfig\":{\"onFailureRateAbove\":0,\"windowMinutes\":5,\"minRunsInWindow\":10,\"channels\":[\"string\"]}}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/runs
List recent runs for a workflow (cursor paginated; ?sort= / ?fields= / ?filter[]= supported)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/runs" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/runs', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/runs",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/runs", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/runs');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/runs')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/runs"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}
Fetch one workflow run with step timeline
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
runIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/runs/{runId}"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events
List recent real trigger payloads (7d) for replay
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
limitquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/replayable-events?limit="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/revisions
List revisions for a workflow (cursor paginated; ?sort= / ?fields= / ?filter[]= supported)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/revisions', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/revisions');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/revisions')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/revisions"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/revisions
Create a draft revision (auto-save)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "nodes": [
    {
      "id": "string",
      "type": "string",
      "params": {}
    }
  ],
  "edges": [
    {
      "from": "string",
      "to": "string",
      "when": "string"
    }
  ],
  "triggerEventKey": "string",
  "notes": "string"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"nodes":[{"id":"string","type":"string","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}],"triggerEventKey":"string","notes":"string"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/revisions', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"nodes":[{"id":"string","type":"string","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}],"triggerEventKey":"string","notes":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"nodes": [{"id": "string", "type": "string", "params": {}}], "edges": [{"from": "string", "to": "string", "when": "string"}], "triggerEventKey": "string", "notes": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/revisions", strings.NewReader(`{"nodes":[{"id":"string","type":"string","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}],"triggerEventKey":"string","notes":"string"}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/revisions');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"nodes":[{"id":"string","type":"string","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}],"triggerEventKey":"string","notes":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/revisions')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"nodes":[{"id":"string","type":"string","params":{}}],"edges":[{"from":"string","to":"string","when":"string"}],"triggerEventKey":"string","notes":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/revisions"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"nodes\":[{\"id\":\"string\",\"type\":\"string\",\"params\":{}}],\"edges\":[{\"from\":\"string\",\"to\":\"string\",\"when\":\"string\"}],\"triggerEventKey\":\"string\",\"notes\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/publish
Publish a revision — flip publishedRevisionId + status=published
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "revisionId": "string",
  "notes": "string"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/publish" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"revisionId":"string","notes":"string"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/publish', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"revisionId":"string","notes":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/publish",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"revisionId": "string", "notes": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/publish", strings.NewReader(`{"revisionId":"string","notes":"string"}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/publish');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"revisionId":"string","notes":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/publish')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"revisionId":"string","notes":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/publish"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"revisionId\":\"string\",\"notes\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/unpublish
Unpublish — clear publishedRevisionId, status=draft
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/unpublish"))
    .header("Idempotency-Key", "<value>")
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/test-run
Synthetic dry-run — walk the graph and return a per-step trace
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "revisionId": "string",
  "triggerPayload": {}
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/test-run" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"revisionId":"string","triggerPayload":{}}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/test-run', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"revisionId":"string","triggerPayload":{}}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/test-run",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"revisionId": "string", "triggerPayload": {}},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/test-run", strings.NewReader(`{"revisionId":"string","triggerPayload":{}}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/test-run');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"revisionId":"string","triggerPayload":{}}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/test-run')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"revisionId":"string","triggerPayload":{}}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/test-run"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"revisionId\":\"string\",\"triggerPayload\":{}}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/stats
Aggregate run metrics for a workflow over a window
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
periodquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/stats?period="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/fire
Manually fire a workflow (operator or external integration)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
idempotency-keyheaderstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "triggerPayload": {},
  "conversationId": "string",
  "contactId": "string",
  "idempotencyKey": "string"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/fire" \
  -H "idempotency-key: <value>" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"triggerPayload":{},"conversationId":"string","contactId":"string","idempotencyKey":"string"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/fire', {
  method: 'POST',
  headers: {
    'idempotency-key': '<value>',
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"triggerPayload":{},"conversationId":"string","contactId":"string","idempotencyKey":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/fire",
    headers={
    "idempotency-key": "<value>",
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"triggerPayload": {}, "conversationId": "string", "contactId": "string", "idempotencyKey": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/fire", strings.NewReader(`{"triggerPayload":{},"conversationId":"string","contactId":"string","idempotencyKey":"string"}`))
	req.Header.Set("idempotency-key", "<value>")
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/fire');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['idempotency-key: <value>', 'Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"triggerPayload":{},"conversationId":"string","contactId":"string","idempotencyKey":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/fire')
req = Net::HTTP::Post.new(uri)
req['idempotency-key'] = '<value>'
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"triggerPayload":{},"conversationId":"string","contactId":"string","idempotencyKey":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/fire"))
    .header("idempotency-key", "<value>")
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"triggerPayload\":{},\"conversationId\":\"string\",\"contactId\":\"string\",\"idempotencyKey\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/runs/live
List in-flight runs (running / waiting_approval / paused)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/runs/live"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all
Cancel every in-flight run for this workflow (admin-only)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/runs/kill-all"))
    .header("Idempotency-Key", "<value>")
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/dlq
List dead-letter queue rows (terminally failed runs; ?sort= / ?fields= / ?filter[]= supported)
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
includeReplayedquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/dlq?includeReplayed="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay
Replay a DLQ row — create a new workflow_run from its payload
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
dlqIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/dlq/{dlqId}/replay"))
    .header("Idempotency-Key", "<value>")
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/runs/{runId}/cancel
Cancel a workflow run (cooperative; honors active step)
Parameters
NameInTypeRequiredDescription
runIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/runs/{runId}/cancel"))
    .header("Idempotency-Key", "<value>")
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflow-folders
List workflow folders in the workspace
Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflow-folders" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflow-folders', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflow-folders",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflow-folders", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflow-folders');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflow-folders')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflow-folders"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflow-folders
Create a workflow folder (root or nested)
Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "name": "string",
  "parentFolderId": "string"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflow-folders" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","parentFolderId":"string"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflow-folders', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"name":"string","parentFolderId":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflow-folders",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"name": "string", "parentFolderId": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflow-folders", strings.NewReader(`{"name":"string","parentFolderId":"string"}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflow-folders');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name":"string","parentFolderId":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflow-folders')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"name":"string","parentFolderId":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflow-folders"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"name\":\"string\",\"parentFolderId\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
DELETEhttps://api.chatlychat.com/v1/workflow-folders/{folderId}
Delete a workflow folder (cascades subtree; workflows orphaned at root)
Parameters
NameInTypeRequiredDescription
folderIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
204
Code samples
cURL
curl -X DELETE "https://api.chatlychat.com/v1/workflow-folders/{folderId}" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflow-folders/{folderId}', {
  method: 'DELETE',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "DELETE",
    "https://api.chatlychat.com/v1/workflow-folders/{folderId}",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.chatlychat.com/v1/workflow-folders/{folderId}", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflow-folders/{folderId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflow-folders/{folderId}')
req = Net::HTTP::Delete.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflow-folders/{folderId}"))
    .header("Idempotency-Key", "<value>")
    .method("DELETE", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/templates
List pre-built workflow templates
Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/templates" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/templates', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/templates",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/templates", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/templates');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/templates')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/templates"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/templates/{slug}
Fetch one workflow template (full graph)
Parameters
NameInTypeRequiredDescription
slugpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/templates/{slug}" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/templates/{slug}', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/templates/{slug}",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/templates/{slug}", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/templates/{slug}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/templates/{slug}')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/templates/{slug}"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/templates/{slug}/install
Clone a template into the workspace — returns the new workflow row
Parameters
NameInTypeRequiredDescription
slugpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "name": "string"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/templates/{slug}/install" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/templates/{slug}/install', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"name":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/templates/{slug}/install",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"name": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/templates/{slug}/install", strings.NewReader(`{"name":"string"}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/templates/{slug}/install');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/templates/{slug}/install')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"name":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/templates/{slug}/install"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"name\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{id}/step-timings
Parameters
NameInTypeRequiredDescription
idpathstringyes
fromRunIdquerystringyes
windowDaysquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{id}/step-timings?fromRunId=&windowDays="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/audit
List audit log entries for one workflow
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
cursorquerystringyes
limitquerystringyes
actionquerystringyes
data_classquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/audit?cursor=&limit=&action=&data_class="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/audit/workflows
List workspace-wide workflow audit entries
Parameters
NameInTypeRequiredDescription
cursorquerystringyes
limitquerystringyes
data_classquerystringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class=')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/audit/workflows?cursor=&limit=&data_class="))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/permissions
List permission grants on a workflow
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/permissions');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/permissions"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/permissions
Grant a permission on a workflow
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "userId": "string",
  "role": "owner",
  "permission": "view"
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"userId":"string","role":"owner","permission":"view"}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"userId":"string","role":"owner","permission":"view"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"userId": "string", "role": "owner", "permission": "view"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions", strings.NewReader(`{"userId":"string","role":"owner","permission":"view"}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/permissions');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"userId":"string","role":"owner","permission":"view"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"userId":"string","role":"owner","permission":"view"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/permissions"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"userId\":\"string\",\"role\":\"owner\",\"permission\":\"view\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
DELETEhttps://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}
Revoke a permission on a workflow
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
permIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X DELETE "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}', {
  method: 'DELETE',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "DELETE",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}')
req = Net::HTTP::Delete.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/permissions/{permId}"))
    .header("Idempotency-Key", "<value>")
    .method("DELETE", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/variants
List A/B variants for a workflow
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/variants" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/variants', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/variants",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/variants", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/variants');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/variants')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/variants"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/variants
Create an A/B variant
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Request body application/json
{
  "revisionId": "string",
  "name": "string",
  "trafficPercent": 0,
  "isControl": false
}
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/variants" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"revisionId":"string","name":"string","trafficPercent":0,"isControl":false}'
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/variants', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"revisionId":"string","name":"string","trafficPercent":0,"isControl":false}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/variants",
    headers={
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"revisionId": "string", "name": "string", "trafficPercent": 0, "isControl": False},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/variants", strings.NewReader(`{"revisionId":"string","name":"string","trafficPercent":0,"isControl":false}`))
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/variants');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"revisionId":"string","name":"string","trafficPercent":0,"isControl":false}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/variants')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"revisionId":"string","name":"string","trafficPercent":0,"isControl":false}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/variants"))
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"revisionId\":\"string\",\"name\":\"string\",\"trafficPercent\":0,\"isControl\":false}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats
Stats for one variant
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
vidpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
200
Code samples
cURL
curl -X GET "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats', {
  method: 'GET',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats')
req = Net::HTTP::Get.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/stats"))
    .header("Idempotency-Key", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner
Pick a winner — set traffic to 100, archive the rest
Parameters
NameInTypeRequiredDescription
workflowIdpathstringyes
vidpathstringyes
Idempotency-KeyheaderstringnoUUIDv4 or 16-128 char opaque token. Required on write endpoints in production. Replays return the cached response with `Idempotency-Replay: true`; reusing the key with a different body returns 409 idempotency_conflict.
Responses
201
Code samples
cURL
curl -X POST "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner" \
  -H "Idempotency-Key: <value>"
TypeScript
const res = await fetch('https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner', {
  method: 'POST',
  headers: {
    'Idempotency-Key': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner",
    headers={
    "Idempotency-Key": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner", nil)
	req.Header.Set("Idempotency-Key", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Idempotency-Key: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner')
req = Net::HTTP::Post.new(uri)
req['Idempotency-Key'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.chatlychat.com/v1/workflows/{workflowId}/variants/{vid}/pick-winner"))
    .header("Idempotency-Key", "<value>")
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Was this page helpful?