Agenti e workflow
Crea e gestisci agenti, e pianifica, esegui e monitora i task di workflow tramite l'API REST.
Un agente è un assistente salvato: un prompt di sistema, un modello, gli strumenti integrati che può usare, server MCP remoti, knowledge base e file. Un task di workflow è un’esecuzione dell’IA senza supervisione: istruzioni fisse inviate a un modello secondo una pianificazione cron o su richiesta, con ogni avvio registrato come esecuzione. Sono il lato API delle funzionalità Agenti e Workflow dell’app.
Tutti i percorsi sono relativi a https://api.stickyprompts.com/api/v1. Ogni richiesta viene eseguita come l’utente proprietario della chiave API.
Convenzioni
:idaccetta sia l’IDnumerico sia loslug. Un valore composto solo da cifre viene sempre trattato come ID.- Gli oggetti serializzano i campi di base con l’iniziale maiuscola (
ID,CreatedAt,UpdatedAt,DeletedAt, che sulle righe attive vale semprenull); tutti gli altri campi sono in snake_case. - Gli elenchi paginati accettano
page(predefinito1) esize(predefinito10), restituiscono un semplice array JSON e riportano i totali negli header di rispostaX-Total-Count,X-PageeX-Page-Size. - Gli errori hanno la forma
{"error": "<message>"}. I rifiuti dovuti ai guardrail e alla residenza dei dati aggiungono un codice leggibile dalle macchine:{"error": "...", "code": "..."}.
Agenti
L’API gestisce la configurazione di un agente. Per chattare con un agente, passa il suo agent_id quando avvii una conversazione, oppure menziona il suo tag con @mention: vedi Conversazioni e messaggi.
L’oggetto Agent
{
"ID": 412,
"CreatedAt": "2026-09-28T09:14:03.512Z",
"UpdatedAt": "2026-09-28T09:14:03.512Z",
"DeletedAt": null,
"user_id": 88,
"name": "Support Triage",
"slug": "k7Xq2bd",
"tag": "support-triage",
"icon": "headset",
"color": "#3B82F6",
"description": "Classifies Northwind support tickets and drafts replies",
"system_prompt": "You are the first-line support agent for Northwind Analytics...",
"ai_model_id": 31,
"ai_model": { "ID": 31, "name": "...", "...": "..." },
"tools": [{ "name": "web_search", "use": true }],
"knowledge_base_limit_node_ids": null,
"world_knowledge": false,
"knowledge_bases": [{ "ID": 7, "...": "..." }]
}
| Campo | Tipo | Note |
|---|---|---|
user_id | uint | Il proprietario. |
name | string | Fino a 500 caratteri. |
slug | string | Generato dal server, utilizzabile come :id. |
tag | string | L’@handle: ^[a-z0-9][a-z0-9-_]*$, da 1 a 50 caratteri. |
icon | string | Per esempio cpu, rocket, folder, database, headset. Predefinito: cpu. |
color | string | Un colore esadecimale della palette, per esempio #F59E0B (il predefinito). |
description | string o null | Mostrata sulla scheda dell’agente. |
system_prompt | string | Potrebbe essere stato oscurato dai guardrail del tuo workspace. |
ai_model_id, ai_model | uint, oggetto | Il modello. In GET /agents l’oggetto ai_model non viene caricato e restituisce valori zero: lì leggi ai_model_id. |
tools | array o null | {"name", "use"}. Nomi: web_search, image_generation, video_generation, speech_generation, music_generation, remote_mcp. |
knowledge_base_limit_node_ids | uint[] o null | Limita il recupero a questi nodi della knowledge base. |
world_knowledge | bool | Indica se l’agente può andare oltre le proprie knowledge base. |
mcp_servers, knowledge_bases, files | array | Omessi quando sono vuoti; non vengono caricati nell’endpoint di elenco. |
is_shared | bool | Solo in GET /agents e GET /agents/:id: true quando l’agente appartiene a qualcun altro che lo ha condiviso con te. |
POST /agents
/api/v1/agents Crea un agente.
-
namestring obbligatorio - Non può essere vuoto.
-
ai_model_iduint obbligatorio - In pratica è obbligatorio. Viene verificato rispetto alla policy di residenza dei dati del tuo workspace per gli agenti. Qui non viene verificato esplicitamente che il modello esista.
-
tagstring facoltativo - L’
@handle. Se lo ometti, viene ricavato daname(in minuscolo, con gli altri caratteri sostituiti da-, al massimo 50, conagentcome ripiego). -
iconstring facoltativo predefinitocpu - Il nome dell’icona.
-
colorstring facoltativo predefinito#F59E0B - Il colore esadecimale.
-
descriptionstring facoltativo - Una descrizione di una riga.
-
system_promptstring facoltativo - La descrizione del compito. Passa attraverso il filtro sui dati sensibili del tuo workspace.
-
toolsarray facoltativo [{"name", "use"}].-
mcp_server_idsuint[] facoltativo - I server MCP remoti da collegare. Vengono collegati solo i server di tua proprietà; gli altri vengono ignorati senza alcun avviso.
-
knowledge_base_idsuint[] facoltativo - Le knowledge base da collegare. Vengono collegate solo quelle a cui hai accesso; le altre vengono scartate senza alcun avviso.
-
file_idsuint[] facoltativo - I file da collegare. Vengono collegati solo i file di tua proprietà; gli altri vengono ignorati senza alcun avviso.
-
knowledge_base_limit_node_idsuint[] facoltativo - Limita il recupero a questi nodi.
-
world_knowledgebool facoltativo predefinitofalse - Consente conoscenze che vanno oltre le knowledge base.
curl -X POST https://api.stickyprompts.com/api/v1/agents \
-H "Authorization: Bearer $STICKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Triage",
"tag": "support-triage",
"icon": "headset",
"description": "Classifies Northwind support tickets and drafts replies",
"system_prompt": "You are the first-line support agent for Northwind Analytics. Classify each ticket, rate urgency 1-3 and draft a reply.",
"ai_model_id": 31,
"tools": [{ "name": "web_search", "use": false }],
"knowledge_base_ids": [7]
}'import os, requests
r = requests.post(
"https://api.stickyprompts.com/api/v1/agents",
headers={"Authorization": f"Bearer {os.environ['STICKY_API_KEY']}"},
json={
"name": "Support Triage",
"tag": "support-triage",
"icon": "headset",
"description": "Classifies Northwind support tickets and drafts replies",
"system_prompt": "You are the first-line support agent for Northwind Analytics. "
"Classify each ticket, rate urgency 1-3 and draft a reply.",
"ai_model_id": 31,
"tools": [{"name": "web_search", "use": False}],
"knowledge_base_ids": [7],
},
)
r.raise_for_status()
agent = r.json()
print(agent["ID"], agent["tag"])const agent = await fetch("https://api.stickyprompts.com/api/v1/agents", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.STICKY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Support Triage",
tag: "support-triage",
icon: "headset",
description: "Classifies Northwind support tickets and drafts replies",
system_prompt:
"You are the first-line support agent for Northwind Analytics. Classify each ticket, rate urgency 1-3 and draft a reply.",
ai_model_id: 31,
tools: [{ name: "web_search", use: false }],
knowledge_base_ids: [7],
}),
}).then((r) => r.json());
console.log(agent.ID, agent.tag);Risposta. 201 Created con l’oggetto Agent (senza is_shared).
Errori. 400 per un corpo non JSON, "Agent name is required", un tag non valido, una violazione della residenza dei dati ({"error": "...", "code": "NO_ENDPOINT_AVAILABLE"}, "NO_PROVIDER_ASSIGNED" e simili) o una violazione delle regole sui dati sensibili in system_prompt ({"error", "code"}). 500 "Failed to create agent".
GET /agents
/api/v1/agents Elenca gli agenti di tua proprietà e quelli condivisi con te (direttamente, tramite uno dei tuoi team o con l’intero workspace). Lo strumento MCP list_agents restituisce solo i tuoi agenti.
-
searchstring in query facoltativo - Corrispondenza parziale su
name, senza distinzione tra maiuscole e minuscole. -
sharedstring in query facoltativo false: solo gli agenti di tua proprietà.true: solo gli agenti di altri utenti condivisi con te. Se omesso: entrambi.-
usage_sortstring in query facoltativo - Con
trueordina in base al numero di messaggi inviati con l’agente, in ordine decrescente. Altrimenti nessun ordinamento esplicito. -
pageinteger in query facoltativo predefinito1 - Numero di pagina.
-
sizeinteger in query facoltativo predefinito10 - Elementi per pagina.
Risposta. 200 con un array di oggetti Agent, ciascuno con is_shared. In questa route ai_model, mcp_servers, knowledge_bases e files non vengono caricati.
GET /agents/:id
/api/v1/agents/:id Restituisce un agente di tua proprietà o condiviso con te, con tutti i dati caricati: ai_model, mcp_servers, knowledge_bases, files e is_shared.
-
idstring in path obbligatorio - ID o slug dell’agente.
Errori. 404 "Agent not found", 403 "You don't have access to this agent".
PATCH /agents/:id
/api/v1/agents/:id Aggiorna un agente. Solo il proprietario può aggiornarlo; la condivisione non concede diritti di modifica. Il corpo accetta gli stessi campi della creazione, tutti facoltativi: i campi omessi o null restano invariati. name non può essere vuoto; system_prompt passa attraverso il filtro sui dati sensibili e ai_model_id attraverso la verifica della residenza dei dati.
-
idstring in path obbligatorio - ID o slug dell’agente.
-
namestring facoltativo - Il nuovo nome. Non può essere vuoto.
-
system_promptstring facoltativo - Il nuovo prompt di sistema.
-
ai_model_iduint facoltativo - Il nuovo modello.
-
mcp_server_idsuint[] facoltativo - Se omesso: resta invariato. Qualsiasi array, compreso
[], sostituisce l’intero insieme. -
knowledge_base_idsuint[] facoltativo - Se omesso: resta invariato. Qualsiasi array, compreso
[], sostituisce l’intero insieme. -
file_idsuint[] facoltativo - Se omesso: resta invariato. Qualsiasi array, compreso
[], sostituisce l’intero insieme. -
tagstring facoltativo - Come alla creazione.
-
iconstring facoltativo - Come alla creazione.
-
colorstring facoltativo - Come alla creazione.
-
descriptionstring facoltativo - Come alla creazione.
-
toolsarray facoltativo - Come alla creazione.
-
knowledge_base_limit_node_idsuint[] facoltativo - Come alla creazione.
-
world_knowledgebool facoltativo - Come alla creazione.
Risposta. 200 con l’oggetto Agent completo di tutti i dati (senza is_shared).
Errori. 400, 403 "You are not authorized to update this agent", 404 "Agent not found", 500.
DELETE /agents/:id
/api/v1/agents/:id Esegue un’eliminazione logica (soft delete) di un agente di tua proprietà. I suoi collegamenti a server MCP, knowledge base e file vengono rimossi; i file e le knowledge base in sé non vengono eliminati.
-
idstring in path obbligatorio - ID o slug dell’agente.
Risposta. 204 No Content. Errori. 403 "You are not authorized to delete this agent".
Task di workflow
Un task di workflow invia le sue instructions a un modello, senza supervisione. Ecco come funziona un’esecuzione:
- Viene creata subito un’esecuzione con
status: "running"; il lavoro si svolge in background. - L’esecuzione verifica prima la quota del proprietario (in caso di errore,
error_text: "quota exceeded: <reason>"), poi crea una conversazione nascosta e non interattiva con il modello del task e inviainstructionscome messaggio. - Vengono attivati tutti gli strumenti integrati (
web_search,image_generation,video_generation,speech_generation,music_generation) e tutti i server MCP remoti configurati dal proprietario. Il modello ignora gli strumenti che non supporta. - Un’esecuzione ha un timeout rigido di 45 minuti (
error_text: "The run took too long to complete"). - In caso di successo, la risposta finale viene salvata in
result_text. Le esecuzioni interrotte da un riavvio del server vengono contrassegnate comeerrorcon"The run was interrupted before it could finish"e non vengono riprese.
Trigger. L’unico tipo di trigger è cron. Non esistono trigger basati su webhook, eventi o chiamate API: un’esecuzione parte da un trigger cron oppure da POST /workflow-tasks/:id/manual-run. Non esistono nemmeno webhook in uscita, quindi per sapere quando un’esecuzione è terminata devi usare il polling.
Stati delle esecuzioni. running (in corso), success (terminata, con result_text valorizzato) ed error (terminata, con error_text valorizzato). success ed error sono stati finali. Il valore pending esiste, ma il codice di esecuzione attuale non lo imposta.
L’oggetto Workflow task
{
"ID": 57,
"CreatedAt": "2026-09-28T09:20:11Z",
"UpdatedAt": "2026-09-28T09:20:11Z",
"DeletedAt": null,
"user_id": 88,
"name": "Monday pipeline digest",
"slug": "Tq9mZr4b",
"description": null,
"ai_model_id": 31,
"ai_model": { "ID": 31, "...": "..." },
"instructions": "Summarise last week's new deals in our CRM and email the summary to the Northwind sales team.",
"enabled": true,
"triggers": [
{
"ID": 90,
"workflow_task_id": 57,
"type": "cron",
"enabled": true,
"cron_expression": "0 8 * * 1",
"timezone": "Europe/Budapest",
"last_triggered_at": null,
"next_trigger_at": "2026-09-28T08:00:00+02:00"
}
]
}
| Campo | Note |
|---|---|
instructions | Il prompt inviato a ogni esecuzione, dopo l’oscuramento dei dati sensibili. |
enabled | I trigger cron di un task disattivato non scattano. |
triggers | Omesso quando è vuoto. Ogni trigger ha type (cron), enabled, cron_expression, timezone (IANA, predefinito UTC), last_triggered_at e next_trigger_at (null finché il trigger è disattivato). |
total_run_count | Solo in GET /workflow-tasks/:id: il numero totale di esecuzioni mai registrate. |
success_rate | Solo in GET /workflow-tasks/:id: la quota di success tra le 30 esecuzioni più recenti, da 0 a 1 (0 quando non ce ne sono). |
POST /workflow-tasks
/api/v1/workflow-tasks Crea un task di workflow.
-
namestring obbligatorio - Non può essere vuoto.
-
ai_model_iduint obbligatorio - Deve esistere (
400 "AI model not found") e superare la verifica della policy di residenza dei dati per i workflow. -
instructionsstring obbligatorio - Non può essere vuoto. Passa attraverso il filtro sui dati sensibili.
-
descriptionstring facoltativo - Testo libero.
-
enabledbool facoltativo predefinitotrue - Indica se i trigger del task scattano.
-
triggersarray facoltativo - Le richieste di trigger, vedi sotto.
-
typestring obbligatorio - Deve essere
cron. Qualsiasi altro valore restituisce400 "unsupported trigger type: <x>". -
cron_expressionstring obbligatorio - Espressione cron standard a 5 campi: minuto, ora, giorno del mese, mese, giorno della settimana. Un valore non valido restituisce
400 "invalid cron_expression: ...". -
enabledbool facoltativo predefinitofalse - Il valore predefinito è false. Un trigger inviato senza
"enabled": trueviene salvato disattivato e non scatta mai. -
timezonestring facoltativo predefinitoUTC - Un fuso orario IANA, per esempio
Europe/Budapest. Un valore non valido restituisce400 "invalid timezone: ...".
curl -X POST https://api.stickyprompts.com/api/v1/workflow-tasks \
-H "Authorization: Bearer $STICKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Monday pipeline digest",
"ai_model_id": 31,
"instructions": "Summarise last week'"'"'s new deals in our CRM and email the summary to the Northwind sales team.",
"triggers": [
{ "type": "cron", "enabled": true, "cron_expression": "0 8 * * 1", "timezone": "Europe/Budapest" }
]
}'import os, requests
r = requests.post(
"https://api.stickyprompts.com/api/v1/workflow-tasks",
headers={"Authorization": f"Bearer {os.environ['STICKY_API_KEY']}"},
json={
"name": "Monday pipeline digest",
"ai_model_id": 31,
"instructions": "Summarise last week's new deals in our CRM and email "
"the summary to the Northwind sales team.",
"triggers": [{"type": "cron", "enabled": True,
"cron_expression": "0 8 * * 1", "timezone": "Europe/Budapest"}],
},
)
r.raise_for_status()
print(r.json()["triggers"][0]["next_trigger_at"])const task = await fetch("https://api.stickyprompts.com/api/v1/workflow-tasks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.STICKY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Monday pipeline digest",
ai_model_id: 31,
instructions:
"Summarise last week's new deals in our CRM and email the summary to the Northwind sales team.",
triggers: [{ type: "cron", enabled: true, cron_expression: "0 8 * * 1", timezone: "Europe/Budapest" }],
}),
}).then((r) => r.json());
console.log(task.ID, task.triggers[0].next_trigger_at);Risposta. 201 con il task di workflow (senza le statistiche delle esecuzioni).
Errori. 400 (convalida, errori dei trigger, residenza dei dati {"error", "code"}, dati sensibili {"error", "code"}), 500.
GET /workflow-tasks
/api/v1/workflow-tasks Elenca i tuoi task di workflow (non possono essere condivisi), dal più recente. Ogni elemento include ai_model e triggers, ma non total_run_count né success_rate.
-
searchstring in query facoltativo - Corrispondenza parziale su
name, senza distinzione tra maiuscole e minuscole. -
pageinteger in query facoltativo predefinito1 - Numero di pagina.
-
sizeinteger in query facoltativo predefinito10 - Elementi per pagina.
Risposta. 200 con un array di oggetti Workflow task.
GET /workflow-tasks/:id
/api/v1/workflow-tasks/:id Restituisce uno dei tuoi task di workflow con ai_model, triggers, total_run_count e success_rate.
-
idstring in path obbligatorio - ID o slug del task di workflow.
Errori. 404 "Workflow task not found", 403 "You don't have access to this workflow task".
PATCH /workflow-tasks/:id
/api/v1/workflow-tasks/:id Aggiorna uno dei tuoi task di workflow. Tutti i campi sono facoltativi; quelli omessi restano invariati.
-
idstring in path obbligatorio - ID o slug del task di workflow.
-
namestring facoltativo - Non può essere vuoto.
-
descriptionstring facoltativo - Testo libero.
-
ai_model_iduint facoltativo - Il nuovo modello.
-
instructionsstring facoltativo - Non può essere vuoto.
-
enabledbool facoltativo - Il passaggio da
falseatruericalcola ilnext_trigger_atdi ogni trigger attivo a partire da questo momento. -
triggersarray facoltativo - Se presente, sostituisce l’intero insieme di trigger: i vecchi trigger vengono eliminati e tolti dalla pianificazione.
[]rimuove tutti i trigger.
curl -X PATCH https://api.stickyprompts.com/api/v1/workflow-tasks/57 \
-H "Authorization: Bearer $STICKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'
Risposta. 200 con il task di workflow (con ai_model e triggers, senza le statistiche delle esecuzioni).
Errori. 400, 403 "You are not authorized to update this workflow task", 404, 500.
DELETE /workflow-tasks/:id
/api/v1/workflow-tasks/:id Toglie i trigger dalla pianificazione e li elimina, poi esegue un’eliminazione logica (soft delete) del task e delle sue esecuzioni. Solo per il proprietario.
-
idstring in path obbligatorio - ID o slug del task di workflow.
Risposta. 204 No Content.
POST /workflow-tasks/:id/manual-run
/api/v1/workflow-tasks/:id/manual-run Avvia subito un’esecuzione, indipendentemente dal fatto che il task o i suoi trigger siano attivi. Solo per il proprietario. Nessun corpo. Restituisce 202 Accepted con la nuova esecuzione, mentre il lavoro prosegue in background. Non esiste un callback: interroga GET /workflow-tasks/:id/executions finché lo status dell’esecuzione non vale success o error.
-
idstring in path obbligatorio - ID o slug del task di workflow.
curl -X POST https://api.stickyprompts.com/api/v1/workflow-tasks/57/manual-run \
-H "Authorization: Bearer $STICKY_API_KEY"
# Then poll the run history until the execution is success or error
curl "https://api.stickyprompts.com/api/v1/workflow-tasks/57/executions?page=1&size=5" \
-H "Authorization: Bearer $STICKY_API_KEY"import os, time, requests
BASE = "https://api.stickyprompts.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['STICKY_API_KEY']}"}
run = requests.post(f"{BASE}/workflow-tasks/57/manual-run", headers=H).json()
while True:
time.sleep(10)
executions = requests.get(f"{BASE}/workflow-tasks/57/executions",
headers=H, params={"page": 1, "size": 10}).json()
ex = next((e for e in executions if e["ID"] == run["ID"]), None)
if ex and ex["status"] in ("success", "error"):
print(ex["status"], ex["result_text"] or ex["error_text"])
breakconst BASE = "https://api.stickyprompts.com/api/v1";
const headers = { Authorization: `Bearer ${process.env.STICKY_API_KEY}` };
const run = await fetch(`${BASE}/workflow-tasks/57/manual-run`, { method: "POST", headers }).then((r) => r.json());
for (;;) {
await new Promise((r) => setTimeout(r, 10_000));
const executions = await fetch(`${BASE}/workflow-tasks/57/executions?page=1&size=10`, { headers }).then((r) => r.json());
const ex = executions.find((e) => e.ID === run.ID);
if (ex && (ex.status === "success" || ex.status === "error")) {
console.log(ex.status, ex.result_text ?? ex.error_text);
break;
}
}Risposta. 202 Accepted:
{
"ID": 1203,
"CreatedAt": "2026-09-28T09:31:00Z",
"UpdatedAt": "2026-09-28T09:31:00Z",
"DeletedAt": null,
"workflow_task_id": 57,
"trigger_type": null,
"conversation_context_id": null,
"status": "running",
"started_at": "2026-09-28T09:31:00Z",
"finished_at": null,
"result_text": null,
"error_text": null
}
Qui conversation_context_id vale null perché la conversazione nascosta viene collegata un attimo dopo.
Errori. 404, 403 "You are not authorized to run this workflow task", 500 "Failed to start workflow run". Gli errori di quota e del modello non fanno fallire la chiamata HTTP: compaiono in seguito come status: "error" sull’esecuzione.
GET /workflow-tasks/:id/executions
/api/v1/workflow-tasks/:id/executions Restituisce la cronologia delle esecuzioni di un task, dalla più recente. Solo per il proprietario.
-
idstring in path obbligatorio - ID o slug del task di workflow.
-
pageinteger in query facoltativo predefinito1 - Numero di pagina.
-
sizeinteger in query facoltativo predefinito10 - Elementi per pagina.
Risposta. 200 con un array di esecuzioni. trigger_type vale null per un’esecuzione manuale e "cron" per una pianificata. result_text viene restituito come HTML renderizzato.
[
{
"ID": 1203,
"workflow_task_id": 57,
"trigger_type": null,
"conversation_context_id": 88123,
"status": "success",
"started_at": "2026-09-28T09:31:00Z",
"finished_at": "2026-09-28T09:32:14Z",
"result_text": "<p>Last week 4 new deals were created...</p>",
"error_text": null
}
]
Pagine correlate
- Conversazioni e messaggi - chatta con un agente tramite
agent_ido un@tag. - Integrazioni - le connessioni a CRM, email e database che un workflow può usare.
- Riferimento degli strumenti -
list_agents,get_agent,list_workflow_tasks,get_workflow_task,run_workflow_task.