List Instruction Bots (retired)
curl --request GET \
--url https://app.tuco.ai/api/instructions \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tuco.ai/api/instructions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tuco.ai/api/instructions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.tuco.ai/api/instructions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.tuco.ai/api/instructions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.tuco.ai/api/instructions")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tuco.ai/api/instructions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"goalBots": [
{
"_id": "<string>",
"name": "<string>",
"description": "<string>",
"goal": "<string>",
"status": "<string>",
"stages": [
{}
],
"settings": {},
"entry": {},
"stats": {},
"createdAt": "<string>"
}
]
}Goal Bots
List Instruction Bots (retired)
The stage-based engine that used to answer on /api/goal-bots. Being retired — build on goal bots instead.
GET
/
api
/
instructions
List Instruction Bots (retired)
curl --request GET \
--url https://app.tuco.ai/api/instructions \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tuco.ai/api/instructions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tuco.ai/api/instructions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.tuco.ai/api/instructions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.tuco.ai/api/instructions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.tuco.ai/api/instructions")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tuco.ai/api/instructions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"goalBots": [
{
"_id": "<string>",
"name": "<string>",
"description": "<string>",
"goal": "<string>",
"status": "<string>",
"stages": [
{}
],
"settings": {},
"entry": {},
"stats": {},
"createdAt": "<string>"
}
]
}Instruction bots are being retired. They are the older stage-based engine: a lead is
enrolled into one and walks a sequence of stages. The engine that replaced them —
goal bots — has no stages and no enrolment: you tag a
lead and the bot handles their replies.Build new work on goal bots. These endpoints stay up for integrations already using them.
Authentication
Pass your workspace API key as a Bearer token, or use a Clerk session token.Authorization: Bearer tuco_xxxxxxxxxxxxx
Example
curl "https://app.tuco.ai/api/instructions" \
-H "Authorization: Bearer tuco_xxxxxxxxxxxxx"
Success (200 OK)
{
"goalBots": [
{
"_id": "6a970c3429603484fb08b211",
"name": "Escalate Wedding Lead",
"description": "Recognise when a wedding lead should be handled by a human...",
"goal": "Hand the conversation to a human when it exceeds the bot's authority",
"status": "active",
"stages": [ /* ordered stages */ ],
"stats": { "totalEnrolled": 12, "inProgress": 3 },
"createdAt": "2026-09-01T12:04:52.188Z"
}
]
}
The response key is
goalBots, not instructions — a historical name from before the engines
split. These are instruction bots, and their ids are not interchangeable with
goal bot ids: the two live in different collections.Response
object[]
Non-archived instruction bots, newest first.
Show Instruction bot fields
Show Instruction bot fields
string
Instruction id. Use it on the enrol routes.
string
Display name.
string
Optional description.
string
What the bot is trying to achieve.
string
active, draft or paused. Only active bots accept enrolments.object[]
The ordered stages the lead walks.
object
Tone, model and per-conversation reply cap.
object
How leads enter, including
tag_trigger.object
totalEnrolled and inProgress counts.string
ISO 8601 timestamp.
Errors
| Status | When | Body |
|---|---|---|
401 | Missing or invalid API key | { "error": "Unauthorized" } |