curl --request POST \
--url https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-workspace-id: <x-workspace-id>' \
--data '
{
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": [
"Pregunta por el presupuesto disponible",
"Valida el uso actual de soluciones"
],
"order": 2,
"triggers": [
{
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing"
}
],
"metadata": {
"author": "playbook@agents.studio"
}
}
'import requests
url = "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages"
payload = {
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": ["Pregunta por el presupuesto disponible", "Valida el uso actual de soluciones"],
"order": 2,
"triggers": [
{
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing"
}
],
"metadata": { "author": "playbook@agents.studio" }
}
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-workspace-id': '<x-workspace-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'qualification',
title: 'Calificación',
goalPrompt: 'Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.',
promptInstructions: ['Pregunta por el presupuesto disponible', 'Valida el uso actual de soluciones'],
order: 2,
triggers: [
{
condition: {type: 'expression', value: 'lead.qualified == true'},
nextStageName: 'closing'
}
],
metadata: {author: 'playbook@agents.studio'}
})
};
fetch('https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'qualification',
'title' => 'Calificación',
'goalPrompt' => 'Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.',
'promptInstructions' => [
'Pregunta por el presupuesto disponible',
'Valida el uso actual de soluciones'
],
'order' => 2,
'triggers' => [
[
'condition' => [
'type' => 'expression',
'value' => 'lead.qualified == true'
],
'nextStageName' => 'closing'
]
],
'metadata' => [
'author' => 'playbook@agents.studio'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-workspace-id: <x-workspace-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages"
payload := strings.NewReader("{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "b0d32725-47cc-43b3-b415-1304ca4f9e24",
"agentId": "38f62697-0f4b-49bc-8a0c-67256f5af6ff",
"blueprintId": "c09f3fa9-5082-4b0e-96b8-7426e672d88a",
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": [
"Pregunta por el presupuesto disponible",
"Valida el uso actual de soluciones"
],
"order": 2,
"triggers": [
{
"id": "a02a4142-8279-42b3-98a2-71ef712d9c25",
"stageId": "b0d32725-47cc-43b3-b415-1304ca4f9e24",
"blueprintId": "c09f3fa9-5082-4b0e-96b8-7426e672d88a",
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing",
"createdAt": "2025-10-05T19:47:55.000Z",
"updatedAt": "2025-10-05T19:47:55.000Z"
}
],
"metadata": {
"author": "playbook@agents.studio"
},
"createdAt": "2025-10-05T19:47:55.000Z",
"updatedAt": "2025-10-05T19:47:55.000Z"
}{
"code": "INVALID_STAGE",
"message": "El nombre debe ser único dentro del blueprint"
}{
"code": "BLUEPRINT_NOT_FOUND",
"message": "No se encontró un blueprint editable para el agente"
}{
"code": "BLUEPRINT_LOCKED",
"message": "El blueprint publicado no admite nuevas modificaciones"
}Crear un stage dentro del blueprint del agente
Persiste un nuevo stage en el blueprint indicado. Antes de guardar se
ejecuta la validación completa del grafo; en caso de error se responde 400 INVALID_GRAPH. Una vez confirmada la creación se emite un evento
BlueprintStageCreated que desencadena el job interno StagesSyncJob para reflejar
los cambios en el proveedor (p.ej. Retell) de forma asincrónica.
curl --request POST \
--url https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-workspace-id: <x-workspace-id>' \
--data '
{
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": [
"Pregunta por el presupuesto disponible",
"Valida el uso actual de soluciones"
],
"order": 2,
"triggers": [
{
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing"
}
],
"metadata": {
"author": "playbook@agents.studio"
}
}
'import requests
url = "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages"
payload = {
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": ["Pregunta por el presupuesto disponible", "Valida el uso actual de soluciones"],
"order": 2,
"triggers": [
{
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing"
}
],
"metadata": { "author": "playbook@agents.studio" }
}
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-workspace-id': '<x-workspace-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'qualification',
title: 'Calificación',
goalPrompt: 'Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.',
promptInstructions: ['Pregunta por el presupuesto disponible', 'Valida el uso actual de soluciones'],
order: 2,
triggers: [
{
condition: {type: 'expression', value: 'lead.qualified == true'},
nextStageName: 'closing'
}
],
metadata: {author: 'playbook@agents.studio'}
})
};
fetch('https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'qualification',
'title' => 'Calificación',
'goalPrompt' => 'Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.',
'promptInstructions' => [
'Pregunta por el presupuesto disponible',
'Valida el uso actual de soluciones'
],
'order' => 2,
'triggers' => [
[
'condition' => [
'type' => 'expression',
'value' => 'lead.qualified == true'
],
'nextStageName' => 'closing'
]
],
'metadata' => [
'author' => 'playbook@agents.studio'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-workspace-id: <x-workspace-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages"
payload := strings.NewReader("{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-prod.studio.getsupervisor.ai/v1/agents/{agentId}/blueprints/{blueprintId}/stages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"qualification\",\n \"title\": \"Calificación\",\n \"goalPrompt\": \"Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.\",\n \"promptInstructions\": [\n \"Pregunta por el presupuesto disponible\",\n \"Valida el uso actual de soluciones\"\n ],\n \"order\": 2,\n \"triggers\": [\n {\n \"condition\": {\n \"type\": \"expression\",\n \"value\": \"lead.qualified == true\"\n },\n \"nextStageName\": \"closing\"\n }\n ],\n \"metadata\": {\n \"author\": \"playbook@agents.studio\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "b0d32725-47cc-43b3-b415-1304ca4f9e24",
"agentId": "38f62697-0f4b-49bc-8a0c-67256f5af6ff",
"blueprintId": "c09f3fa9-5082-4b0e-96b8-7426e672d88a",
"name": "qualification",
"title": "Calificación",
"goalPrompt": "Haz preguntas abiertas para entender el contexto y valida si el lead cumple criterios.",
"promptInstructions": [
"Pregunta por el presupuesto disponible",
"Valida el uso actual de soluciones"
],
"order": 2,
"triggers": [
{
"id": "a02a4142-8279-42b3-98a2-71ef712d9c25",
"stageId": "b0d32725-47cc-43b3-b415-1304ca4f9e24",
"blueprintId": "c09f3fa9-5082-4b0e-96b8-7426e672d88a",
"condition": {
"type": "expression",
"value": "lead.qualified == true"
},
"nextStageName": "closing",
"createdAt": "2025-10-05T19:47:55.000Z",
"updatedAt": "2025-10-05T19:47:55.000Z"
}
],
"metadata": {
"author": "playbook@agents.studio"
},
"createdAt": "2025-10-05T19:47:55.000Z",
"updatedAt": "2025-10-05T19:47:55.000Z"
}{
"code": "INVALID_STAGE",
"message": "El nombre debe ser único dentro del blueprint"
}{
"code": "BLUEPRINT_NOT_FOUND",
"message": "No se encontró un blueprint editable para el agente"
}{
"code": "BLUEPRINT_LOCKED",
"message": "El blueprint publicado no admite nuevas modificaciones"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Identificador del workspace multi-tenant.
Path Parameters
Identificador del agente
Identificador del blueprint del agente (se obtiene de GET /v1/agents/{agentId}/blueprints)
Body
Nombre slug utilizado para referenciar el stage desde otros triggers.
1^[a-zA-Z0-9_-]+$1x >= 0Triggers opcionales que se crearán junto con el stage.
Show child attributes
Show child attributes
Response
Stage creado correctamente
Nombre estable del stage (slug amigable para referencias entre triggers).
1Título legible que se muestra en el editor.
Objetivo del stage expresado como prompt de alto nivel.
1Lista ordenada de instrucciones que contextualizan el goal prompt.
Posición del stage dentro del blueprint.
Triggers asociados al stage.
Show child attributes
Show child attributes
Campos adicionales definidos por el workspace.
Variables detectadas en el goal prompt e instrucciones del stage.
