Automations
Work the sandbox starts on its own, and the approvals it parks waiting for you
On this page(9 sections)
Scheduled and triggered work: what can trigger one here, what is configured, and switching one on or off, deleting it or firing it by hand. The other half is the approval queue — an automation set to ask first lands there each time it would have run.
9 calls. Pick one to open it, or use the list on the right.
GET/automationsThings that wake an agent on their own
Every automation with its recent runs and when it fires next.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
automations | object[] |
idThe automation's id | string |
triggerWhat sets it off: a schedule,… | object |
when kind is "schedule" | shape |
cronWhen, in cron notation | string |
when kind is "event" | shape |
tokenThe credential a caller presents | string |
when kind is "listener" | shape |
providerWhich service to listen to | string |
channelIdNarrow it to one channel or… | string |
eventTypeNarrow it to one kind of… | string |
mentionedOnly when the agent is actually… | boolean |
branchNarrow it to one branch, for… | string |
allowedOriginsWhich websites may reach the chat… | string[] |
when kind is "workspace" | shape |
eventWhich happening | "turn.settled" | "agent.landed" | "deps.broken" | "deps.fixed" |
repoNarrow it to one repository | string |
guardA command run before the wake… | string |
promptWhat the woken agent is told | string |
webchatSettings for the public chat widget,… | object |
accessWho may write to it | "public" | "google" |
requireNameAsk a visitor for a name… | boolean |
antiBotHow to keep bots out: a… | "turnstile" | "pow" |
turnstileSiteKeyThe public half of those keys,… | string |
turnstileSecretThe private half, which the sandbox… | string |
googleClientIdThe site's own sign-in client id | string |
title | string |
greeting | string |
accent | string |
position | "top-right" | "top-left" | "bottom-right" | "bottom-left" |
dailyMessageMax | integer |
conversationMessageMax | integer |
sessionTtlMinutes | integer |
allowedToolsNarrow the woken turn to these… | string[] |
agentWhich provider serves the wake | string |
accountWhich account pays for it | string |
actsAsWhich persona it speaks as | string |
harnessWhich agentic loop runs it | "native" | "claude-code" |
modelWhich model runs it | string |
requireApprovalHold every fire for a person… | boolean |
holdForSecondsHold each fire this long before… | number |
choreThis automation is a maintenance job,… | boolean |
enabledWhether it fires at all | boolean |
runs | object[] |
at | number |
outcome | "completed" | "skipped" | "error" | "interrupted" |
detail | string |
conversationId | string |
nextRun | number |
curl "$SANDBOX/automations" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.list();POST/automationsCreate or edit an automation
Writes an automation by id. Nothing needs provisioning: the scheduler picks it up on its next sweep.
What you send
| Field | Type | Where |
|---|---|---|
idrequiredThe automation's id | string | body |
triggerrequiredWhat sets it off: a schedule,… | object | body |
when kind is "schedule" | shape | body |
cronrequiredWhen, in cron notation | string | body |
when kind is "event" | shape | body |
tokenThe credential a caller presents | string | body |
when kind is "listener" | shape | body |
providerrequiredWhich service to listen to | string | body |
channelIdNarrow it to one channel or… | string | body |
eventTypeNarrow it to one kind of… | string | body |
mentionedOnly when the agent is actually… | boolean | body |
branchNarrow it to one branch, for… | string | body |
allowedOriginsWhich websites may reach the chat… | string[] | body |
when kind is "workspace" | shape | body |
eventrequiredWhich happening | "turn.settled" | "agent.landed" | "deps.broken" | "deps.fixed" | body |
repoNarrow it to one repository | string | body |
guardA command run before the wake… | string | body |
promptrequiredWhat the woken agent is told | string | body |
webchatSettings for the public chat widget,… | object | body |
accessWho may write to it | "public" | "google" | body |
requireNameAsk a visitor for a name… | boolean | body |
antiBotHow to keep bots out: a… | "turnstile" | "pow" | body |
turnstileSiteKeyThe public half of those keys,… | string | body |
turnstileSecretThe private half, which the sandbox… | string | body |
googleClientIdThe site's own sign-in client id | string | body |
title | string | body |
greeting | string | body |
accent | string | body |
position | "top-right" | "top-left" | "bottom-right" | "bottom-left" | body |
dailyMessageMax | integer | body |
conversationMessageMax | integer | body |
sessionTtlMinutes | integer | body |
allowedToolsNarrow the woken turn to these… | string[] | body |
agentWhich provider serves the wake | string | body |
accountWhich account pays for it | string | body |
actsAsWhich persona it speaks as | string | body |
harnessWhich agentic loop runs it | "native" | "claude-code" | body |
modelWhich model runs it | string | body |
requireApprovalHold every fire for a person… | boolean | body |
holdForSecondsHold each fire this long before… | number | body |
choreThis automation is a maintenance job,… | boolean | body |
enabledrequiredWhether it fires at all | boolean | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/automations" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"id":"a1b2c3d4","trigger":{"kind":"schedule","cron":"…"},"guard":"…","prompt":"Update the changelog for the last five commits.","webchat":{"access":"public","requireName":true,"antiBot":"turnstile","turnstileSiteKey":"…","turnstileSecret":"…","googleClientId":"a1b2c3d4","title":"Update the changelog","greeting":"…","accent":"…","position":"top-right","dailyMessageMax":1,"conversationMessageMax":1,"sessionTtlMinutes":1},"allowedTools":["…","…"],"agent":"…","account":"work","actsAs":"…","harness":"native","model":"claude-sonnet-4-6","requireApproval":true,"holdForSeconds":1,"chore":true,"enabled":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.upsert({
"id": "a1b2c3d4",
"trigger": {
"kind": "schedule",
"cron": "…"
},
"guard": "…",
"prompt": "Update the changelog for the last five commits.",
"webchat": {
"access": "public",
"requireName": true,
"antiBot": "turnstile",
"turnstileSiteKey": "…",
"turnstileSecret": "…",
"googleClientId": "a1b2c3d4",
"title": "Update the changelog",
"greeting": "…",
"accent": "…",
"position": "top-right",
"dailyMessageMax": 1,
"conversationMessageMax": 1,
"sessionTtlMinutes": 1
},
"allowedTools": [
"…",
"…"
],
"agent": "…",
"account": "work",
"actsAs": "…",
"harness": "native",
"model": "claude-sonnet-4-6",
"requireApproval": true,
"holdForSeconds": 1,
"chore": true,
"enabled": true
});GET/automations/catalogWhat can trigger an automation here
Every trigger this sandbox understands and every template worth starting from, the daemon's own merged with each installed extension's. Writing an automation is checked against this same list, so a screen and the daemon can never disagree about what is allowed.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
sources | object[] |
provider | string |
label | string |
logo | string |
icon | string |
events | object[] |
value | string |
label | string |
channel | object |
label | string |
placeholder | string |
hint | string |
branchField | object |
label | string |
placeholder | string |
hint | string |
mentionLabel | string |
starterPrompt | string |
requires | string[] |
enabled | boolean |
templates | object[] |
id | string |
title | string |
logo | string |
icon | string |
requires | string[] |
trigger | object |
when kind is "schedule" | shape |
cronWhen, in cron notation | string |
when kind is "event" | shape |
tokenThe credential a caller presents | string |
when kind is "listener" | shape |
providerWhich service to listen to | string |
channelIdNarrow it to one channel or… | string |
eventTypeNarrow it to one kind of… | string |
mentionedOnly when the agent is actually… | boolean |
branchNarrow it to one branch, for… | string |
allowedOriginsWhich websites may reach the chat… | string[] |
when kind is "workspace" | shape |
eventWhich happening | "turn.settled" | "agent.landed" | "deps.broken" | "deps.fixed" |
repoNarrow it to one repository | string |
guard | string |
holdForSeconds | integer |
prompt | string |
note | string |
setup | string |
description | string |
offer | "create" | "configure" |
chore | boolean |
curl "$SANDBOX/automations/catalog" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.catalog();POST/automations/{id}/enabledTurn an automation on or off
Flips only the switch, so a row in a list can be toggled without rebuilding the whole record.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
enabledrequired | boolean | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/automations/a1b2c3d4/enabled" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"enabled":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.setEnabled({
"id": "a1b2c3d4",
"enabled": true
});DELETE/automations/{id}Delete an automation
Removes it, so nothing fires from it again.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X DELETE "$SANDBOX/automations/a1b2c3d4" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.remove({
"id": "a1b2c3d4"
});POST/automations/{id}/runFire an automation by hand
The answer to writing something that runs at three in the morning and having no way to try it. It takes exactly the path the real trigger takes, including the check that decides whether there was anything to do, since skipped by the guard is the most useful thing this can tell you. A switched-off automation fires too, because trying it before switching it on is the main reason to press this. Not available for the trigger that listens for incoming messages, where a hand-fire would produce an agent asked to handle events and handed none; send the bot a message instead. Answers straight away and runs detached.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/automations/a1b2c3d4/run" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.run({
"id": "a1b2c3d4"
});GET/automations/pendingAutomations waiting for a yes
The queue an automation set to ask first lands in each time it would have fired.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
approvalsEverything waiting for a yes | object[] |
idThis waiting item's own id, which… | string |
automationIdWhich automation it came from | string |
payloadWhat set it off, kept whole… | string |
originWhere the message came from, kept… | object |
automationId | string |
provider | string |
channelId | string |
author | string |
titleWhat the conversation would be called | string |
conversationIdThe thread this belongs to, when… | string |
sessionIdThe provider session that thread last… | string |
createdAtWhen it started waiting, in milliseconds | number |
autoRunAtWhen it goes ahead on its… | number |
curl "$SANDBOX/automations/pending" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.pendingList();POST/automations/pending/{id}/approveLet a held automation run
Releases one waiting automation and runs the wake it was holding. Answers straight away and runs detached.
What you send
| Field | Type | Where |
|---|---|---|
idrequiredWhich waiting item | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/automations/pending/a1b2c3d4/approve" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.approve({
"id": "a1b2c3d4"
});POST/automations/pending/{id}/rejectDrop a held automation
Throws one waiting fire away. The automation stays on, and the next trigger queues as usual.
What you send
| Field | Type | Where |
|---|---|---|
idrequiredWhich waiting item | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/automations/pending/a1b2c3d4/reject" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.automations.reject({
"id": "a1b2c3d4"
});