intentic
Download the app
Download the app
Agents

One agent

Run a turn in one conversation, then attach to it, answer it, steer it or stop it

On this page(15 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.

15 calls. Pick one to open it, or use the list on the right.

POST/agentSay something to an agent

Answers at once with what became of the message: it starts a turn when the conversation is free, is said into the running turn where that turn takes words mid-way, and otherwise waits in the conversation's queue for the next turn, where every window sees it. 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. Give the message an id, and sending it again after a lost answer is met with what became of it the first time rather than a second delivery.

What you send

FieldTypeWhere
promptrequiredWhat to say to the agentstringbody
errandWhat the words are for, when…"land-conflict" | "verify-nudge" | "land-breakage" | "land-fix" … (10)body
messageIdYour id for this messagestringbody
titleA title for a conversation this…stringbody
attachmentsFiles to hand the agent along…string[]body
mentionsWorkspace paths the prompt mentions with…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
startInWhich folder the conversation opens in,…stringbody
placementWhere this conversation runs: this sandbox…objectbody
when kind is "local"shapebody
when kind is "runner"shapebody
idrequiredstringbody
worktreeBasePin a new private copy to…object[]body
reporequiredstringbody
baserequiredstringbody
autoLandWhether this turn's work merges into…booleanbody
runRoleWhat started this turn, when it…"commit-message" | "session-title" | "safety-judge" | "loop-verdict" … (13)body
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 is watching this turn: a…booleanbody
outsideWakeContent from outside caused this turn,…stringbody
permissionModeHow tool calls are gated: ask…"default" | "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
autoPickedWhether this turn's model was chosen…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
sendAtHold this message until then (epoch…integerbody
sendAfterHold this message until the conversation…stringbody
conversationAutoLandWhether this conversation's finished work merges…booleanbody
continuesCarry the conversation on from where…truebody

What comes back

FieldType
deliveredWhat became of the message: it…"started" | "steered" | "queued"
runThe run the message is in:…string
duplicateThe sandbox had already taken a…true
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.","errand":"land-conflict","messageId":"a1b2c3d4","title":"Update the changelog","attachments":["…","…"],"mentions":["…","…"],"agent":"…","harness":"native","account":"work","actsAs":"…","sessionId":"a1b2c3d4","conversationId":"nightly-changelog","isolated":true,"startIn":"…","placement":{"kind":"local"},"worktreeBase":[{"repo":"root","base":"…"},{"repo":"site","base":"…"}],"autoLand":true,"runRole":"commit-message","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,"autoPicked":true,"editorContext":{"file":"…","startLine":1,"endLine":1,"selection":"…"},"sendAt":1,"sendAfter":"…","conversationAutoLand":true,"continues":true}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.run({
  "prompt": "Update the changelog for the last five commits.",
  "errand": "land-conflict",
  "messageId": "a1b2c3d4",
  "title": "Update the changelog",
  "attachments": [
    "…",
    "…"
  ],
  "mentions": [
    "…",
    "…"
  ],
  "agent": "…",
  "harness": "native",
  "account": "work",
  "actsAs": "…",
  "sessionId": "a1b2c3d4",
  "conversationId": "nightly-changelog",
  "isolated": true,
  "startIn": "…",
  "placement": {
    "kind": "local"
  },
  "worktreeBase": [
    {
      "repo": "root",
      "base": "…"
    },
    {
      "repo": "site",
      "base": "…"
    }
  ],
  "autoLand": true,
  "runRole": "commit-message",
  "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,
  "autoPicked": true,
  "editorContext": {
    "file": "…",
    "startLine": 1,
    "endLine": 1,
    "selection": "…"
  },
  "sendAt": 1,
  "sendAfter": "…",
  "conversationAutoLand": true,
  "continues": true
});
POST/agent/attachWatch a turn happenstream

Streams everything the agent does: its words, the tools it reaches for, and the answers it gets. It opens with the turn's transcript whole as it stands, then sends every change as it lands, so a reload or a dropped connection loses nothing: attaching again hands over the whole transcript again. 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

What comes back

FieldType
when event is "message"shape
dataobject
when kind is "attached"shape
runThe run's idstring
startedAtWhen it started, in milliseconds, so…number
seqHow many frames the run has…number
rowsThe turn's rows as they stand:…object[]
when kind is "patch"shape
seqIts position in the run, counting…number
patchobject
when kind is "fact"shape
seqIts position in the run, counting…number
factobject
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"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.attach({
  "conversationId": "nightly-changelog",
  "run": "run_8c2f41d9"
});
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
attachmentsFiles that go with your own-words…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" | "everything" | "deny"body
feedbackWhy not, which goes back to…stringbody
childFor a request to start a…objectbody
providerrequiredWhich provider serves itstringbody
modelrequiredWhich of that provider's modelsstringbody
harnessWhich agentic loop runs it"native" | "claude-code"body
accountWhich of that provider's connected accounts…stringbody
effortHow hard it thinks, where the…stringbody
thinkingWhether it reasons before it answers,…booleanbody
fastWhether it asks for the faster…booleanbody
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 "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
when kind is "credential_offer"shapebody
requestIdrequiredWhich card you are answeringstringbody
approverequiredYes releases it, as far as…booleanbody

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. Give the message an id, and sending it again after a lost answer is met with what became of it the first time rather than saying it twice.

What you send

FieldTypeWhere
conversationIdrequiredWhich running conversation to interruptstringbody
textrequiredWhat to say to itstringbody
messageIdYour id for this messagestringbody
attachmentsFiles to send with it, as…string[]body
mentionsWorkspace paths the message mentions with…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
deliveredWhat became of the message: it…"started" | "steered" | "queued"
runThe run the message is in:…string
duplicateThe sandbox had already taken a…true
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","messageId":"a1b2c3d4","attachments":["…","…"],"mentions":["…","…"],"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",
  "messageId": "a1b2c3d4",
  "attachments": [
    "…",
    "…"
  ],
  "mentions": [
    "…",
    "…"
  ],
  "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, and whatever waits in the conversation's queue is held there, for everyone, until somebody resumes it. Name the run you mean: a stop that arrives after that run has ended cancels nothing, rather than whatever turn started next.

What you send

FieldTypeWhere
conversationIdrequiredWhich conversation's running turn to cancelstringbody
runrequiredThe run you mean to cancel,…stringbody

What comes back

FieldType
stoppedWhether a turn was cancelledboolean
runningThe run that is live instead…string
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","run":"run_8c2f41d9"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.stop({
  "conversationId": "nightly-changelog",
  "run": "run_8c2f41d9"
});
POST/agent/queue/editReword a waiting message

Changes what a message waiting in the conversation's queue says, keeping its place. Name the revision you read it at: if somebody changed it since, on this device or another, nothing is changed and you are told so.

What you send

FieldTypeWhere
conversationIdrequiredWhose queuestringbody
idrequiredWhich waiting messagestringbody
revisionrequiredThe message's revision as you read…integerbody
textrequiredWhat the message should say insteadstringbody

What comes back

FieldType
itemsWhat waits, in the order it…object[]
idThe message's id: what its sender…string
textThe words, as they will go…string
attachmentsFiles that go with it, as…string[]
voiceWho it is from: a person,…"person" | "sandbox" | "agent"
queuedAtWhen it joined the queue, in…number
revisionThe queue's revision when this message…integer
revisionMoves with every change to the…integer
pausedWhy nothing goes out by itself:…"stopped" | "refused" | "scheduled"
untilWhen scheduled messages go out by…number
afterThe conversation whose finished work must…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/queue/edit" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","id":"a1b2c3d4","revision":0,"text":"export const start = () => listen(PORT);\n"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.queueEdit({
  "conversationId": "nightly-changelog",
  "id": "a1b2c3d4",
  "revision": 0,
  "text": "export const start = () => listen(PORT);\n"
});
POST/agent/queue/removeTake back a waiting message

Removes a message from the conversation's queue before the agent gets it. Name the revision you read it at: a message somebody reworded since is left alone, so you never take back words you have not seen.

What you send

FieldTypeWhere
conversationIdrequiredWhose queuestringbody
idrequiredWhich waiting messagestringbody
revisionrequiredThe message's revision as you read…integerbody

What comes back

FieldType
itemsWhat waits, in the order it…object[]
idThe message's id: what its sender…string
textThe words, as they will go…string
attachmentsFiles that go with it, as…string[]
voiceWho it is from: a person,…"person" | "sandbox" | "agent"
queuedAtWhen it joined the queue, in…number
revisionThe queue's revision when this message…integer
revisionMoves with every change to the…integer
pausedWhy nothing goes out by itself:…"stopped" | "refused" | "scheduled"
untilWhen scheduled messages go out by…number
afterThe conversation whose finished work must…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/queue/remove" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","id":"a1b2c3d4","revision":0}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.queueRemove({
  "conversationId": "nightly-changelog",
  "id": "a1b2c3d4",
  "revision": 0
});
POST/agent/queue/resumeLet waiting messages go

Releases a queue held after a stop or a refusal: what waits goes out now as one turn when nothing is running, or after the running turn otherwise. Name who serves that turn when the conversation has been re-pointed since the messages were queued.

What you send

FieldTypeWhere
conversationIdrequiredWhose queue to let gostringbody
routingWho serves the turn the waiting…objectbody
agentrequiredWhich provider serves the re-runstringbody
harnessrequiredWhich agentic loop runs it"native" | "claude-code"body
accountWhich of that provider's accounts pays…stringbody
modelWhich modelstringbody
carryWhen the account changes, keep the…booleanbody

What comes back

FieldType
runThe turn the waiting messages startedstring
queueThe queue the release left: what…object
itemsWhat waits, in the order it…object[]
idThe message's id: what its sender…string
textThe words, as they will go…string
attachmentsFiles that go with it, as…string[]
voiceWho it is from: a person,…"person" | "sandbox" | "agent"
queuedAtWhen it joined the queue, in…number
revisionThe queue's revision when this message…integer
revisionMoves with every change to the…integer
pausedWhy nothing goes out by itself:…"stopped" | "refused" | "scheduled"
untilWhen scheduled messages go out by…number
afterThe conversation whose finished work must…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/queue/resume" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","routing":{"agent":"…","harness":"native","account":"work","model":"claude-sonnet-4-6","carry":true}}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.queueResume({
  "conversationId": "nightly-changelog",
  "routing": {
    "agent": "…",
    "harness": "native",
    "account": "work",
    "model": "claude-sonnet-4-6",
    "carry": true
  }
});
POST/agent/queue/scheduleReschedule waiting messages

Books what waits in the conversation's queue to go out by itself at another instant, or once another conversation has finished and its work has landed, holding it until then. Works on a queue that is held for any reason, or on messages waiting behind a running turn. A time already past, or a conversation with nothing left to land, lets them go now.

What you send

FieldTypeWhere
conversationIdrequiredWhose queuestringbody
sendAtSend what waits at this instant…integerbody
sendAfterSend what waits once that conversation…stringbody

What comes back

FieldType
itemsWhat waits, in the order it…object[]
idThe message's id: what its sender…string
textThe words, as they will go…string
attachmentsFiles that go with it, as…string[]
voiceWho it is from: a person,…"person" | "sandbox" | "agent"
queuedAtWhen it joined the queue, in…number
revisionThe queue's revision when this message…integer
revisionMoves with every change to the…integer
pausedWhy nothing goes out by itself:…"stopped" | "refused" | "scheduled"
untilWhen scheduled messages go out by…number
afterThe conversation whose finished work must…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/queue/schedule" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","sendAt":1,"sendAfter":"…"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.queueSchedule({
  "conversationId": "nightly-changelog",
  "sendAt": 1,
  "sendAfter": "…"
});
POST/agent/resumeRun a refused turn again

Sends the same turn again when the model provider's allowance refused it, with everything it originally carried except who serves it: the caller may name a different provider, harness or account, which is the usual answer to a spent allowance. It repeats the request rather than adding a new message to the conversation, so pressing it twice costs nothing and the agent is never told to continue work it has not started.

What you send

FieldTypeWhere
conversationIdrequiredWhich conversation's held turn to run…stringbody
routingWho serves the re-run, when the…objectbody
agentrequiredWhich provider serves the re-runstringbody
harnessrequiredWhich agentic loop runs it"native" | "claude-code"body
accountWhich of that provider's accounts pays…stringbody
modelWhich modelstringbody
carryWhen the account changes, keep the…booleanbody

What comes back

FieldType
runThe id of the run that…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/resume" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","routing":{"agent":"…","harness":"native","account":"work","model":"claude-sonnet-4-6","carry":true}}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.resume({
  "conversationId": "nightly-changelog",
  "routing": {
    "agent": "…",
    "harness": "native",
    "account": "work",
    "model": "claude-sonnet-4-6",
    "carry": true
  }
});
POST/agent/accountMove a conversation to another account

Points the conversation at another connected account of the provider it runs on, for every turn from now on. It starts nothing by itself: with `run`, a turn held by a spent allowance or a stop runs again at once on that account, which is how a refused turn continues elsewhere. Without `carry` the next turn opens a fresh session seeded from the record.

What you send

FieldTypeWhere
conversationIdrequiredWhich conversation to movestringbody
accountrequiredWhich of the conversation's provider's connected…stringbody
carryKeep the provider session across the…booleanbody
runAlso run a turn that a…booleanbody

What comes back

FieldType
runThe run that re-ran a held…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/account" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"conversationId":"nightly-changelog","account":"work","carry":true,"run":true}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.switchAccount({
  "conversationId": "nightly-changelog",
  "account": "work",
  "carry": true,
  "run": true
});
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; refused for a message with no saved state to return to; and refused when that position no longer holds the message you named, because the conversation moved since you read it.

What you send

FieldTypeWhere
conversationIdrequiredWhich conversation to rewindstringbody
indexrequiredWhich message to go back to,…integerbody
messageIdrequiredThe id of the message at…stringbody

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,"messageId":"a1b2c3d4"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.rewind({
  "conversationId": "nightly-changelog",
  "index": 0,
  "messageId": "a1b2c3d4"
});
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();
POST/agent/route-chatChoose what a new chat opens on

Reads a new chat's opening message once and answers whichever of two questions it still has: the model, effort and account that conversation should run on, from what is connected and still has allowance left, and which of this sandbox's personas should handle it. `model` and `persona` on the ask say which halves to answer, and only those are put to the model. Asked once per chat, on the message actually sent, and never again: every turn after it runs on what the chat is wearing, which you are free to change. Answers with nothing, and a reason, whenever it cannot choose — a chat is never held up by this.

What you send

FieldTypeWhere
promptrequiredThe message a new chat is…stringbody
pathsWorkspace paths the message names: uploads,…string[]body
folderThe workspace folder the chat was…stringbody
editorContextWhether the message carries a file…booleanbody
planModeWhether the chat opens in plan…booleanbody
modelrequiredWhether to choose the model, effort…booleanbody
personarequiredWhether to choose the persona: true…booleanbody

What comes back

FieldType
personaThe persona half's answer, present only…object
idThe persona this message belongs to,…string
reasonWhy, in the one clause a…string
modelThe model half's answer, present only…object
pickWhat the conversation should run on,…object
providerWhich provider serves the conversationstring
modelWhich of its modelsstring
effortHow hard it should think, where…string
accountWhich connected account pays, by its…string
reasonWhy, in the one clause a…string
judgeWhich model answered, as `provider:model`, so…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/agent/route-chat" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"prompt":"Update the changelog for the last five commits.","paths":["src/app.ts","README.md"],"folder":"…","editorContext":true,"planMode":true,"model":true,"persona":true}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.agent.routeChat({
  "prompt": "Update the changelog for the last five commits.",
  "paths": [
    "src/app.ts",
    "README.md"
  ],
  "folder": "…",
  "editorContext": true,
  "planMode": true,
  "model": true,
  "persona": true
});
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.