intentic
Create your workspace
Agents

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

FieldTypeWhere
promptrequiredWhat to say to the agentstringbody
titleA title for a conversation this…stringbody
attachmentsFiles to hand the agent along…string[]body
agentWhich model provider serves this turnstringbody
harnessWhich agentic loop runs the turn"native" | "claude-code"body
accountWhich of that provider's connected accounts…stringbody
actsAsWhich persona the turn speaks as…stringbody
sessionIdResume this provider session instead of…stringbody
conversationIdThe conversation this turn belongs tostringbody
isolatedWork in this conversation's own private…booleanbody
worktreeBasePin a new private copy to…object[]body
reporequiredstringbody
baserequiredstringbody
autoLandWhether this turn's work merges into…booleanbody
originSet by the sandbox alone: this…objectbody
automationIdrequiredstringbody
providerrequiredstringbody
channelIdstringbody
authorstringbody
forkOfWhere this conversation was cut from,…objectbody
conversationIdrequiredThe conversation this one was cut…stringbody
keeprequiredHow many of that conversation's messages…integerbody
filesrequiredWhich files the fork opens on:…"then" | "now"body
modelWhich model to usestringbody
unattendedNobody chose a model for this…booleanbody
outsideWakeContent from outside caused this turn,…stringbody
permissionModeHow tool calls are gated: ask…"default" | "acceptEdits" | "plan" | "bypassPermissions"body
allowedToolsNarrow the turn to these toolsstring[]body
effortHow hard the model should think,…stringbody
thinkingWhether to show the model's reasoning…booleanbody
fastAsk for the same work at…booleanbody
tierHoldRun exactly the model that was…booleanbody
editorContextWhat the user has open in…objectbody
filerequiredThe file open in the editor,…stringbody
startLineFirst line of the selection, counting…integerbody
endLineLast line of the selection, counting…integerbody
selectionThe selected text itselfstringbody

What comes back

FieldType
runThe id of the run that…string
Try itanswered in this tab
curl
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":"…"}}'
TypeScript
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

FieldTypeWhere
conversationIdrequiredWhich conversation to watchstringbody
runThe run you were watchingstringbody
afterThe last frame you already haveintegerbody

What comes back

FieldType
when event is "message"shape
dataobject
when kind is "attached"shape
runThe run's idstring
promptWhat was said to start it,…string
startedAtWhen it started, in milliseconds, so…number
seqHow many frames already existnumber
when kind is "frame"shape
seqIts position in the run, counting…number
when kind is "end"shape
idstring
retrynumber
when event is "done"shape
dataunknown
idstring
retrynumber
when event is "error"shape
dataunknown
idstring
retrynumber
Try itanswered in this tab
curl
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}'
TypeScript
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

FieldTypeWhere
when kind is "plan"shapebody
requestIdrequiredWhich card you are answering, from…stringbody
approverequiredWhether to go aheadbooleanbody
feedbackWhy not, which goes back to…stringbody
when kind is "question"shapebody
requestIdrequiredWhich card you are answeringstringbody
answersWhat you chose, keyed by the…objectbody
cancelledDismissing it instead, which tells the…booleanbody
when kind is "permission"shapebody
requestIdrequiredWhich card you are answeringstringbody
decisionrequiredOnce allows this call alone; always…"once" | "always" | "deny"body
feedbackWhy not, which goes back to…stringbody
when kind is "browser_help"shapebody
requestIdrequiredWhich card you are answeringstringbody
helpedrequiredWhether you cleared itbooleanbody
noteAnything the agent should know, which…stringbody
when kind is "terminal_help"shapebody
requestIdrequiredWhich card you are answeringstringbody
helpedrequiredWhether you did itbooleanbody
noteAnything the agent should know, which…stringbody
when kind is "service_offer"shapebody
requestIdrequiredWhich card you are answeringstringbody
approverequiredYes releases exactly one runbooleanbody
when kind is "capability_offer"shapebody
requestIdrequiredWhich card you are answeringstringbody
connectrequiredYes keeps the agent waiting while…booleanbody
when kind is "payment_offer"shapebody
requestIdrequiredWhich card you are answeringstringbody
approverequiredYes releases exactly one paymentbooleanbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
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":"…"}'
TypeScript
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

FieldTypeWhere
conversationIdrequiredWhich running conversation to interruptstringbody
textrequiredWhat to say to itstringbody
attachmentsFiles to send with it, as…string[]body
editorContextWhat you have open, folded in…objectbody
filerequiredThe file open in the editor,…stringbody
startLineFirst line of the selection, counting…integerbody
endLineLast line of the selection, counting…integerbody
selectionThe selected text itselfstringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
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":"…"}}'
TypeScript
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

FieldTypeWhere
conversationIdrequiredWhich conversation's running turn to cancelstringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/stop" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog"}'
TypeScript
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

FieldTypeWhere
conversationIdrequiredWhich conversation to rewindstringbody
indexrequiredWhich message to go back to,…integerbody

What comes back

FieldType
snapshotThe saved point the files were…string
droppedHow many messages were removedinteger
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/rewind" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","index":0}'
TypeScript
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

FieldTypeWhere
agentWhose commands to readstringquery

What comes back

FieldType
commandsThe shortcut commands, as the provider…object[]
nameWhat to type, without the leading…string
descriptionWhat it doesstring
hintWhat its argument should look like,…string
Try itanswered in this tab
curl
curl "$SANDBOX/agent/commands" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
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

FieldType
refusalsThe most recent refusal per providerobject
Try itanswered in this tab
curl
curl "$SANDBOX/agent/refusals" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.refusals();
More in Agents

Type to search every page, in the docs and the API reference.