Workflows
A workflow is a reusable agent configuration. These endpoints let you list, create, and retrieve workflows scoped to the API key's account.
The workflow object#
idstringoptionalnamestringoptionaldescriptionstring | nulloptionalstatusstringoptionalactive or paused. Runs cannot be triggered on a paused workflow.modelstringoptionalclaude-sonnet-4-6 or gpt-5.4. Any catalog model from any provider; see Models.crewAgent[]optionalrole, systemPrompt, and an optional model.memory_enabledbooleanoptionalfalse.created_atstringoptionalupdated_atstringoptionalList workflows#
/v1/workflowsReturns every workflow owned by the authenticated account, most recently updated first. Takes no parameters.
Request
curl https://loopllama.ai/api/v1/workflows \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY"Response
{
"data": [
{
"id": "ckv9...",
"name": "Brief writer",
"description": null,
"status": "active",
"model": "claude-sonnet-4-6",
"crew": [
{ "role": "planner", "systemPrompt": "You are a planning agent..." },
{ "role": "writer", "systemPrompt": "You are a writing agent..." }
],
"created_at": "2026-05-20T17:00:00.000Z",
"updated_at": "2026-05-20T17:00:00.000Z"
}
]
}Create a workflow#
/v1/workflowsCreates a new workflow. If crew is omitted, the default planner→writer crew is used. Responds with 201 Created.
Body parameters
namestringrequireddescriptionstringoptionalmodelstringoptionalopenai/gpt-5.4). Unroutable ids return 400. Defaults to the server's configured model (claude-sonnet-4-6).crewAgent[]optionalrole (1–60 chars) and systemPrompt (1–8000 chars), with an optional model.memory_enabledbooleanoptionalfalse.Request
curl -X POST https://loopllama.ai/api/v1/workflows \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Spec reviewer",
"description": "Summarize specs and surface risks",
"crew": [
{ "role": "researcher", "systemPrompt": "Extract key claims and open questions." },
{ "role": "writer", "systemPrompt": "Draft a one-page summary with a Risks section." }
]
}'Response
{
"data": {
"id": "ckva...",
"name": "Spec reviewer",
"description": "Summarize specs and surface risks",
"status": "active",
"model": "claude-sonnet-4-6",
"crew": [
{ "role": "researcher", "systemPrompt": "Extract key claims and open questions." },
{ "role": "writer", "systemPrompt": "Draft a one-page summary with a Risks section." }
],
"created_at": "2026-05-20T17:05:00.000Z"
}
}Retrieve a workflow#
/v1/workflows/{id}Fetches a single workflow by id. Returns 404 Not found if the workflow doesn't exist or belongs to a different account.
Path parameters
idstringrequiredRequest
curl https://loopllama.ai/api/v1/workflows/ckva... \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY"Response
{
"data": {
"id": "ckva...",
"name": "Spec reviewer",
"description": "Summarize specs and surface risks",
"status": "active",
"model": "claude-sonnet-4-6",
"crew": [ { "role": "researcher", "systemPrompt": "..." } ],
"created_at": "2026-05-20T17:05:00.000Z",
"updated_at": "2026-05-20T17:05:00.000Z"
}
}Triggers#
A trigger starts runs of a workflow when something happens, so the agents in it react on their own. Four types: webhook (an inbound POST to a private URL), gmail and outlook (one run per new email in the connected mailbox), and slack (one run per new human message in a channel). Runs started this way have trigger: "event". See how triggers work.
The trigger object
idstringoptionaltypestringoptionalwebhook, gmail, outlook or slack.namestring | nulloptionalenabledbooleanoptionalconfigobjectoptionalinstructions (prepended to every run input); query (gmail search); folder (outlook, default inbox); channel and mentionOnly (slack).urlstring | nulloptionalfireCountintegeroptionallastFiredAtstring | nulloptionallastRunIdstring | nulloptionallastErrorstring | nulloptionalautoPauseAfterintegeroptionaldisabledReasonstring | nulloptionalmanual or auto_paused_failures.List triggers
/v1/workflows/{id}/triggersCreate a trigger
/v1/workflows/{id}/triggerstypestringrequirednamestringoptionalconfigobjectoptionalchannel.enabledbooleanoptionaltrue.autoPauseAfterintegeroptionalcurl -X POST https://loopllama.ai/api/v1/workflows/ckva.../triggers \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "gmail",
"name": "Deals inbox",
"config": {
"query": "to:deals@yourco.com -category:promotions",
"instructions": "A new email arrived in the deals inbox. Triage it, look the sender up in the CRM, and draft a reply for approval."
}
}'For a webhook trigger the response includes url. POST any JSON, form or text body (up to 256 KB) to it and a run is queued; the response is 202 with run_id. Polling triggers check the mailbox or channel about once a minute and only react to messages that arrive after they were created — nothing is backfilled.
Update, pause or resume a trigger
/v1/workflows/{id}/triggers/{triggerId}Any of name, enabled, config, autoPauseAfter, or rotateSecret: true to issue a webhook a new URL. Changing a polling trigger's config restarts it from "now".
Delete a trigger
/v1/workflows/{id}/triggers/{triggerId}Run history is kept.
Follow-up tasks#
Work an agent has scheduled for itself (schedule_followup) or that you hand it. When dueAt arrives a run starts with the task as input; see how tasks work.
The task object
idstringoptionalrolestringoptionalagentIdstring | nulloptionaltitlestringoptionaldetailsstring | nulloptionalstatusstringoptionalopen, running, done, cancelled or failed.dueAtstringoptionalsourcestringoptionalagent or operator.createdByRunIdstring | nulloptionalrunIdstring | nulloptionalattemptsintegeroptionalList tasks
/v1/workflows/{id}/tasks/v1/agents/{id}/tasksAssign a task
/v1/workflows/{id}/taskstitlestringrequireddetailsstringoptionaldueAtstringoptionaldueInMinutes.dueInMinutesintegeroptionalrolestringoptionalcurl -X POST https://loopllama.ai/api/v1/workflows/ckva.../tasks \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "account-manager",
"title": "Check whether Acme signed the proposal",
"details": "If not signed, send a friendly nudge to Dana Reyes and cc the AE.",
"dueAt": "2026-10-09T14:00:00Z"
}'Update a task
/v1/workflows/{id}/tasks/{taskId}title, details, dueAt, or status (open to reopen or run sooner, done, cancelled). A running task returns 409.
Delete a task
/v1/workflows/{id}/tasks/{taskId}Agent memory#
When a workflow has memory_enabled, each agent (by crew role) keeps notes it chooses to remember and a system-written journal of its past runs. These endpoints let you read that memory, brief an agent before its next run, pin the notes it must always see, and delete anything wrong. See how memory works.
The memory object
idstringoptionalrolestringoptionalkindstringoptionalnote (a durable fact) or journal (what the agent did on one run).contentstringoptionalpinnedbooleanoptionalsourcestringoptionalagent (the agent wrote it), operator (written via dashboard or API), or system (journal).runIdstring | nulloptionalcreatedAtstringoptionalList memory
/v1/workflows/{id}/memoryPinned notes first, then newest first, up to 200 entries. Filter to one agent with ?role=.
curl "https://loopllama.ai/api/v1/workflows/ckva.../memory?role=account-manager" \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY"Add a note
/v1/workflows/{id}/memoryrolestringrequiredcontentstringrequiredpinnedbooleanoptionalfalse.curl -X POST https://loopllama.ai/api/v1/workflows/ckva.../memory \
-H "Authorization: Bearer $LOOPLLAMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "account-manager",
"content": "Acme Corp: main contact is Dana Reyes. They prefer a call before any pricing email.",
"pinned": true
}'Update a note
/v1/workflows/{id}/memory/{memoryId}Change content and/or pinned. Journal entries are read-only and return 400.
Delete a memory
/v1/workflows/{id}/memory/{memoryId}Removes a note or journal entry. The agent will not see it again.