Agenti e workflow

Crea e gestisci agenti, e pianifica, esegui e monitora i task di workflow tramite l'API REST.

9 min di lettura · Aggiornato il 28 settembre 2026

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

  • :id accetta sia l’ID numerico sia lo slug. 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 sempre null); tutti gli altri campi sono in snake_case.
  • Gli elenchi paginati accettano page (predefinito 1) e size (predefinito 10), restituiscono un semplice array JSON e riportano i totali negli header di risposta X-Total-Count, X-Page e X-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, "...": "..." }]
}
CampoTipoNote
user_iduintIl proprietario.
namestringFino a 500 caratteri.
slugstringGenerato dal server, utilizzabile come :id.
tagstringL’@handle: ^[a-z0-9][a-z0-9-_]*$, da 1 a 50 caratteri.
iconstringPer esempio cpu, rocket, folder, database, headset. Predefinito: cpu.
colorstringUn colore esadecimale della palette, per esempio #F59E0B (il predefinito).
descriptionstring o nullMostrata sulla scheda dell’agente.
system_promptstringPotrebbe essere stato oscurato dai guardrail del tuo workspace.
ai_model_id, ai_modeluint, oggettoIl modello. In GET /agents l’oggetto ai_model non viene caricato e restituisce valori zero: lì leggi ai_model_id.
toolsarray o null{"name", "use"}. Nomi: web_search, image_generation, video_generation, speech_generation, music_generation, remote_mcp.
knowledge_base_limit_node_idsuint[] o nullLimita il recupero a questi nodi della knowledge base.
world_knowledgeboolIndica se l’agente può andare oltre le proprie knowledge base.
mcp_servers, knowledge_bases, filesarrayOmessi quando sono vuoti; non vengono caricati nell’endpoint di elenco.
is_sharedboolSolo in GET /agents e GET /agents/:id: true quando l’agente appartiene a qualcun altro che lo ha condiviso con te.

POST /agents

POST /api/v1/agents
Autorizzazione agents_manage

Crea un agente.

Corpo
name string obbligatorio
Non può essere vuoto.
ai_model_id uint 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.
tag string facoltativo
L’@handle. Se lo ometti, viene ricavato da name (in minuscolo, con gli altri caratteri sostituiti da -, al massimo 50, con agent come ripiego).
icon string facoltativo predefinito cpu
Il nome dell’icona.
color string facoltativo predefinito #F59E0B
Il colore esadecimale.
description string facoltativo
Una descrizione di una riga.
system_prompt string facoltativo
La descrizione del compito. Passa attraverso il filtro sui dati sensibili del tuo workspace.
tools array facoltativo
[{"name", "use"}].
mcp_server_ids uint[] facoltativo
I server MCP remoti da collegare. Vengono collegati solo i server di tua proprietà; gli altri vengono ignorati senza alcun avviso.
knowledge_base_ids uint[] facoltativo
Le knowledge base da collegare. Vengono collegate solo quelle a cui hai accesso; le altre vengono scartate senza alcun avviso.
file_ids uint[] facoltativo
I file da collegare. Vengono collegati solo i file di tua proprietà; gli altri vengono ignorati senza alcun avviso.
knowledge_base_limit_node_ids uint[] facoltativo
Limita il recupero a questi nodi.
world_knowledge bool facoltativo predefinito false
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

GET /api/v1/agents
Autorizzazione agents_get Strumento MCP list_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.

Parametri di query
search string in query facoltativo
Corrispondenza parziale su name, senza distinzione tra maiuscole e minuscole.
shared string in query facoltativo
false: solo gli agenti di tua proprietà. true: solo gli agenti di altri utenti condivisi con te. Se omesso: entrambi.
usage_sort string in query facoltativo
Con true ordina in base al numero di messaggi inviati con l’agente, in ordine decrescente. Altrimenti nessun ordinamento esplicito.
page integer in query facoltativo predefinito 1
Numero di pagina.
size integer in query facoltativo predefinito 10
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

GET /api/v1/agents/:id
Autorizzazione agents_get Strumento MCP get_agent

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.

Parametri di percorso
id string 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

PATCH /api/v1/agents/:id
Autorizzazione agents_manage

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.

Parametri di percorso
id string in path obbligatorio
ID o slug dell’agente.
Corpo
name string facoltativo
Il nuovo nome. Non può essere vuoto.
system_prompt string facoltativo
Il nuovo prompt di sistema.
ai_model_id uint facoltativo
Il nuovo modello.
mcp_server_ids uint[] facoltativo
Se omesso: resta invariato. Qualsiasi array, compreso [], sostituisce l’intero insieme.
knowledge_base_ids uint[] facoltativo
Se omesso: resta invariato. Qualsiasi array, compreso [], sostituisce l’intero insieme.
file_ids uint[] facoltativo
Se omesso: resta invariato. Qualsiasi array, compreso [], sostituisce l’intero insieme.
tag string facoltativo
Come alla creazione.
icon string facoltativo
Come alla creazione.
color string facoltativo
Come alla creazione.
description string facoltativo
Come alla creazione.
tools array facoltativo
Come alla creazione.
knowledge_base_limit_node_ids uint[] facoltativo
Come alla creazione.
world_knowledge bool 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

DELETE /api/v1/agents/:id
Autorizzazione agents_delete

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.

Parametri di percorso
id string 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 invia instructions come 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 come error con "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"
    }
  ]
}
CampoNote
instructionsIl prompt inviato a ogni esecuzione, dopo l’oscuramento dei dati sensibili.
enabledI trigger cron di un task disattivato non scattano.
triggersOmesso 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_countSolo in GET /workflow-tasks/:id: il numero totale di esecuzioni mai registrate.
success_rateSolo 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

POST /api/v1/workflow-tasks

Crea un task di workflow.

Corpo
name string obbligatorio
Non può essere vuoto.
ai_model_id uint obbligatorio
Deve esistere (400 "AI model not found") e superare la verifica della policy di residenza dei dati per i workflow.
instructions string obbligatorio
Non può essere vuoto. Passa attraverso il filtro sui dati sensibili.
description string facoltativo
Testo libero.
enabled bool facoltativo predefinito true
Indica se i trigger del task scattano.
triggers array facoltativo
Le richieste di trigger, vedi sotto.
Richiesta di trigger
type string obbligatorio
Deve essere cron. Qualsiasi altro valore restituisce 400 "unsupported trigger type: <x>".
cron_expression string 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: ...".
enabled bool facoltativo predefinito false
Il valore predefinito è false. Un trigger inviato senza "enabled": true viene salvato disattivato e non scatta mai.
timezone string facoltativo predefinito UTC
Un fuso orario IANA, per esempio Europe/Budapest. Un valore non valido restituisce 400 "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

GET /api/v1/workflow-tasks
Autorizzazione workflow_tasks_get Strumento MCP list_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.

Parametri di query
search string in query facoltativo
Corrispondenza parziale su name, senza distinzione tra maiuscole e minuscole.
page integer in query facoltativo predefinito 1
Numero di pagina.
size integer in query facoltativo predefinito 10
Elementi per pagina.

Risposta. 200 con un array di oggetti Workflow task.

GET /workflow-tasks/:id

GET /api/v1/workflow-tasks/:id
Autorizzazione workflow_tasks_get Strumento MCP get_workflow_task

Restituisce uno dei tuoi task di workflow con ai_model, triggers, total_run_count e success_rate.

Parametri di percorso
id string 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

PATCH /api/v1/workflow-tasks/:id

Aggiorna uno dei tuoi task di workflow. Tutti i campi sono facoltativi; quelli omessi restano invariati.

Parametri di percorso
id string in path obbligatorio
ID o slug del task di workflow.
Corpo
name string facoltativo
Non può essere vuoto.
description string facoltativo
Testo libero.
ai_model_id uint facoltativo
Il nuovo modello.
instructions string facoltativo
Non può essere vuoto.
enabled bool facoltativo
Il passaggio da false a true ricalcola il next_trigger_at di ogni trigger attivo a partire da questo momento.
triggers array 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

DELETE /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.

Parametri di percorso
id string in path obbligatorio
ID o slug del task di workflow.

Risposta. 204 No Content.

POST /workflow-tasks/:id/manual-run

POST /api/v1/workflow-tasks/:id/manual-run
Autorizzazione workflow_tasks_manage Strumento MCP run_workflow_task

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.

Parametri di percorso
id string 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"])
        break
const 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

GET /api/v1/workflow-tasks/:id/executions
Autorizzazione workflow_tasks_get

Restituisce la cronologia delle esecuzioni di un task, dalla più recente. Solo per il proprietario.

Parametri di percorso
id string in path obbligatorio
ID o slug del task di workflow.
Parametri di query
page integer in query facoltativo predefinito 1
Numero di pagina.
size integer in query facoltativo predefinito 10
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
  }
]