One agent
Run a turn in one conversation, then attach to it, answer it, steer it or stop it
On this page(8 sections)
The surface most callers are here for. Starting a turn answers with a run id and nothing else: the work happens inside the sandbox whether or not anybody stays connected, and attaching is how you watch it, from the beginning or from wherever you had got to. The rest is the things a person does to a turn in flight — answer a question it asked, redirect it, stop it, or put the whole conversation back to an earlier point. Everything here addresses one conversation by id.
8 calls. Pick one to open it, or use the list on the right.
POST/agentSay something to an agent
Starts a turn and answers immediately with its id; the work runs inside the sandbox whether or not anybody stays connected. Watch it by attaching. Naming a conversation that does not exist yet opens it.
What you send
| Field | Type | Where |
|---|---|---|
promptrequiredWhat to say to the agent | string | body |
titleA title for a conversation this… | string | body |
attachmentsFiles to hand the agent along… | string[] | body |
agentWhich model provider serves this turn | string | body |
harnessWhich agentic loop runs the turn | "native" | "claude-code" | body |
accountWhich of that provider's connected accounts… | string | body |
actsAsWhich persona the turn speaks as… | string | body |
sessionIdResume this provider session instead of… | string | body |
conversationIdThe conversation this turn belongs to | string | body |
isolatedWork in this conversation's own private… | boolean | body |
worktreeBasePin a new private copy to… | object[] | body |
reporequired | string | body |
baserequired | string | body |
autoLandWhether this turn's work merges into… | boolean | body |
originSet by the sandbox alone: this… | object | body |
automationIdrequired | string | body |
providerrequired | string | body |
channelId | string | body |
author | string | body |
forkOfWhere this conversation was cut from,… | object | body |
conversationIdrequiredThe conversation this one was cut… | string | body |
keeprequiredHow many of that conversation's messages… | integer | body |
filesrequiredWhich files the fork opens on:… | "then" | "now" | body |
modelWhich model to use | string | body |
unattendedNobody chose a model for this… | boolean | body |
outsideWakeContent from outside caused this turn,… | string | body |
permissionModeHow tool calls are gated: ask… | "default" | "acceptEdits" | "plan" | "bypassPermissions" | body |
allowedToolsNarrow the turn to these tools | string[] | body |
effortHow hard the model should think,… | string | body |
thinkingWhether to show the model's reasoning… | boolean | body |
fastAsk for the same work at… | boolean | body |
tierHoldRun exactly the model that was… | boolean | body |
editorContextWhat the user has open in… | object | body |
filerequiredThe file open in the editor,… | string | body |
startLineFirst line of the selection, counting… | integer | body |
endLineLast line of the selection, counting… | integer | body |
selectionThe selected text itself | string | body |
What comes back
| Field | Type |
|---|---|
runThe id of the run that… | string |
curl -X POST "$SANDBOX/agent" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"prompt":"Update the changelog for the last five commits.","title":"Update the changelog","attachments":["…","…"],"agent":"…","harness":"native","account":"work","actsAs":"…","sessionId":"a1b2c3d4","conversationId":"nightly-changelog","isolated":true,"worktreeBase":[{"repo":"root","base":"…"},{"repo":"site","base":"…"}],"autoLand":true,"origin":{"automationId":"a1b2c3d4","provider":"claude","channelId":"a1b2c3d4","author":"Ada Lovelace"},"forkOf":{"conversationId":"nightly-changelog","keep":0,"files":"then"},"model":"claude-sonnet-4-6","unattended":true,"outsideWake":"…","permissionMode":"default","allowedTools":["…","…"],"effort":"…","thinking":true,"fast":true,"tierHold":true,"editorContext":{"file":"…","startLine":1,"endLine":1,"selection":"…"}}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.run({
"prompt": "Update the changelog for the last five commits.",
"title": "Update the changelog",
"attachments": [
"…",
"…"
],
"agent": "…",
"harness": "native",
"account": "work",
"actsAs": "…",
"sessionId": "a1b2c3d4",
"conversationId": "nightly-changelog",
"isolated": true,
"worktreeBase": [
{
"repo": "root",
"base": "…"
},
{
"repo": "site",
"base": "…"
}
],
"autoLand": true,
"origin": {
"automationId": "a1b2c3d4",
"provider": "claude",
"channelId": "a1b2c3d4",
"author": "Ada Lovelace"
},
"forkOf": {
"conversationId": "nightly-changelog",
"keep": 0,
"files": "then"
},
"model": "claude-sonnet-4-6",
"unattended": true,
"outsideWake": "…",
"permissionMode": "default",
"allowedTools": [
"…",
"…"
],
"effort": "…",
"thinking": true,
"fast": true,
"tierHold": true,
"editorContext": {
"file": "…",
"startLine": 1,
"endLine": 1,
"selection": "…"
}
});POST/agent/attachWatch a turn happenstream
Streams everything the agent does: its words, the tools it reaches for, and the answers it gets. Give it the point you have already seen and it replays from there before going live, so a reload loses nothing. The window that started the turn holds no special claim, and any number of watchers on any number of devices see the same thing.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation to watch | string | body |
runThe run you were watching | string | body |
afterThe last frame you already have | integer | body |
What comes back
| Field | Type |
|---|---|
when event is "message" | shape |
data | object |
when kind is "attached" | shape |
runThe run's id | string |
promptWhat was said to start it,… | string |
startedAtWhen it started, in milliseconds, so… | number |
seqHow many frames already exist | number |
when kind is "frame" | shape |
seqIts position in the run, counting… | number |
when kind is "end" | shape |
id | string |
retry | number |
when event is "done" | shape |
data | unknown |
id | string |
retry | number |
when event is "error" | shape |
data | unknown |
id | string |
retry | number |
curl -N -X POST "$SANDBOX/agent/attach" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","run":"run_8c2f41d9","after":0}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.attach({
"conversationId": "nightly-changelog",
"run": "run_8c2f41d9",
"after": 0
});POST/agent/replyAnswer a question the agent asked
Un-parks a turn that is waiting on you: approving a plan, choosing between options, or permitting a tool. The turn picks up where it stopped.
What you send
| Field | Type | Where |
|---|---|---|
when kind is "plan" | shape | body |
requestIdrequiredWhich card you are answering, from… | string | body |
approverequiredWhether to go ahead | boolean | body |
feedbackWhy not, which goes back to… | string | body |
when kind is "question" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
answersWhat you chose, keyed by the… | object | body |
cancelledDismissing it instead, which tells the… | boolean | body |
when kind is "permission" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
decisionrequiredOnce allows this call alone; always… | "once" | "always" | "deny" | body |
feedbackWhy not, which goes back to… | string | body |
when kind is "browser_help" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
helpedrequiredWhether you cleared it | boolean | body |
noteAnything the agent should know, which… | string | body |
when kind is "terminal_help" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
helpedrequiredWhether you did it | boolean | body |
noteAnything the agent should know, which… | string | body |
when kind is "service_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
approverequiredYes releases exactly one run | boolean | body |
when kind is "capability_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
connectrequiredYes keeps the agent waiting while… | boolean | body |
when kind is "payment_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
approverequiredYes releases exactly one payment | boolean | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/agent/reply" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"kind":"plan","requestId":"a1b2c3d4","approve":true,"feedback":"…"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.reply({
"kind": "plan",
"requestId": "a1b2c3d4",
"approve": true,
"feedback": "…"
});POST/agent/steerInterrupt a running turn
Slips a message into a turn already under way, without stopping it. This is how you redirect an agent mid-thought rather than waiting for it to finish being wrong.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich running conversation to interrupt | string | body |
textrequiredWhat to say to it | string | body |
attachmentsFiles to send with it, as… | string[] | body |
editorContextWhat you have open, folded in… | object | body |
filerequiredThe file open in the editor,… | string | body |
startLineFirst line of the selection, counting… | integer | body |
endLineLast line of the selection, counting… | integer | body |
selectionThe selected text itself | string | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/agent/steer" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","text":"export const start = () => listen(PORT);\n","attachments":["…","…"],"editorContext":{"file":"…","startLine":1,"endLine":1,"selection":"…"}}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.steer({
"conversationId": "nightly-changelog",
"text": "export const start = () => listen(PORT);\n",
"attachments": [
"…",
"…"
],
"editorContext": {
"file": "…",
"startLine": 1,
"endLine": 1,
"selection": "…"
}
});POST/agent/stopStop a turn now
Cancels the running turn inside the sandbox. Whatever it had already written to disk stays written.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation's running turn to cancel | string | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/agent/stop" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.stop({
"conversationId": "nightly-changelog"
});POST/agent/rewindGo back to an earlier message
Puts the files back as they stood at that point, drops every message after it, and forgets what the model remembered, so the next thing you say starts from there cleanly. Refused while a turn is running, because a restore cannot overwrite files an agent is editing, and refused for a message with no saved state to return to.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation to rewind | string | body |
indexrequiredWhich message to go back to,… | integer | body |
What comes back
| Field | Type |
|---|---|
snapshotThe saved point the files were… | string |
droppedHow many messages were removed | integer |
curl -X POST "$SANDBOX/agent/rewind" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","index":0}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.rewind({
"conversationId": "nightly-changelog",
"index": 0
});GET/agent/commandsShortcut commands the agent knows
The commands a provider published the last time one of its turns ran, so a composer can offer them before this conversation has run anything. A running turn's own list wins over this one.
What you send
| Field | Type | Where |
|---|---|---|
agentWhose commands to read | string | query |
What comes back
| Field | Type |
|---|---|
commandsThe shortcut commands, as the provider… | object[] |
nameWhat to type, without the leading… | string |
descriptionWhat it does | string |
hintWhat its argument should look like,… | string |
curl "$SANDBOX/agent/commands" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.commands();GET/agent/refusalsThe last time each provider said no
What each model provider most recently refused and why. Read this alongside an account's usage: the usage says how full it was when last checked, this says whether it has since started turning work away.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
refusalsThe most recent refusal per provider | object |
curl "$SANDBOX/agent/refusals" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.refusals();