---
title: "System · intentic sandbox API"
description: "The daemon itself: its identity, its event stream, its terminals, its browsers, its helpers. Every route in the system group of the intentic sandbox API, with its input, its answer and a playground."
url: "https://intentic.dev/api/system/"
---

The sandbox itself

# System

The daemon itself: its identity, its event stream, its terminals, its browsers, its helpers

**On this page (14 sections)**

- [What this sandbox is](#system-info)
- [Settings files the sandbox could not read](#system-manifestProblems)
- [Trade a sign-in for a session](#system-session)
- [The live event stream](#system-events)
- [Say what you are looking at](#system-presence)
- [What has been spent](#system-usage)
- [Open terminals](#system-terminals)
- [Close a terminal](#system-killTerminal)
- [A terminal's history as plain text](#system-terminalScrollback)
- [Browsers the agent has open](#system-browsers)
- [Shut a browser down](#system-closeBrowser)
- [Helpers the agents have started](#system-subagents)
- [A helper agent's record](#system-subagentTranscript)
- [Drive a sandbox on one of your own computers](#system-manageMachineSandbox)

The group with the widest job. The identity read is what the daemon says it is, including the routes it implements, which is the one call that tells a newer client what this sandbox can do. The event stream is the sandbox-wide live feed. The rest is the machinery an agent leaves running: terminals and their history, browsers, and the records of helpers it delegated to.

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

**GET`/info` What this sandbox is**

The sandbox's own identity and state: which workspace it holds, which image it runs, what it is called, and the list of calls it actually implements. Start here, because a browser is routinely newer than the sandbox it is talking to and this is how it finds out what is there.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `name` What this sandbox is called | string |
| `image` The image it is running | string |
| `version` The version of that image | string |
| `latest` The newest published version on its… | string |
| `updateAvailable` Whether those two differ | boolean |
| `runtimes` Which agent runtimes can serve a… | object |
| `channel` Which release channel this sandbox follows | string |
| `previousImage` The image the last update replaced,… | string |
| `updateNotes` What is in the update, in… | string[] |
| `moreUpdateNotes` How many further notes there are… | number |
| `breakingNotes` What the update takes away, uncapped,… | string[] |
| `staged` An update already downloaded and built… | object |
| `version` What the downloaded build says it… | string |
| `channel` Which channel it was taken from | string |
| `at` When the download finished, in milliseconds,… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/info" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.info();
```

**GET`/system/manifest-problems` Settings files the sandbox could not read**

Anything the daemon tripped over in its own configuration on disk: a file it had to fall back from, a key it did not recognise, an entry it skipped. Separate from the identity call because it goes stale for a different reason, namely a file changing.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `path` The file, as a workspace path | string |
| `problems` Everything currently wrong with it | object[] |
| `kind` What to do about it | "unreadable" | "unknownKey" | "invalidEntry" |
| `detail` What exactly was wrong | string |
| `suggestion` The name it was probably meant… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/manifest-problems" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.manifestProblems();
```

**POST`/system/session` Trade a sign-in for a session**

Exchanges a verified sign-in, or a session that has not expired yet, for a fresh session the daemon minted. That session is the credential every other call carries, and calling this again with a live one renews it.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `token` The credential every other call carries | string |
| `expiresAt` When it stops working, in milliseconds,… | number |
| `email` Who the sandbox verified you as | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/system/session" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.session();
```

**GET`/events` The live event stream stream**

A stream held open for as long as you want it, carrying heartbeats so a caller notices the sandbox dying at once, batches of file changes so a tree or an editor can refresh itself, and the roster of who else is looking. Give it an id for this connection to appear in that roster; leave it out and you watch without being seen.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `clientId` | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `when event is "message"` | shape |
| `data` | object |
| `when kind is "hello"` | shape |
| `workspaceId` | string |
| `routes` | string[] |
| `shapes` | object |
| `build` | string |
| `boot` | object |
| `when kind is "heartbeat"` | shape |
| `when kind is "boot"` | shape |
| `ready` | boolean |
| `startedAt` | number |
| `steps` | object[] |
| `when kind is "workspaceChanged"` | shape |
| `paths` | string[] |
| `when kind is "reposChanged"` | shape |
| `repos` | string[] |
| `when kind is "refsChanged"` | shape |
| `repos` | string[] |
| `when kind is "runtimeChanged"` | shape |
| `domains` | string[] |
| `when kind is "presence"` | shape |
| `users` | object[] |
| `when kind is "agents"` | shape |
| `agents` | object[] |
| `rev` | number |
| `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 |

Try it answered in this tab

curl

```bash
curl -N "$SANDBOX/events" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.events();
```

**POST`/system/presence` Say what you are looking at**

Reports which view, conversation or file this connection is on, or that it has gone idle. The daemon fans it back out on the event stream so everyone else's roster updates.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `clientId` required This connection's own id, the same… | string | body |
| `idle` required Whether the person has stopped doing… | boolean | body |
| `view` Which view they are on | string | body |
| `sessionId` Which conversation they have open | string | body |
| `path` Which file they are looking at | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/system/presence" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"clientId":"a1b2c3d4","idle":true,"view":"…","sessionId":"a1b2c3d4","path":"src/app.ts"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.presence({
 "clientId": "a1b2c3d4",
 "idle": true,
 "view": "…",
 "sessionId": "a1b2c3d4",
 "path": "src/app.ts"
});
```

**GET`/system/usage` What has been spent**

Token and cost totals per account, added up from the record of every finished turn.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `accounts` | object[] |
| `provider` | string |
| `account` | string |
| `turns` | number |
| `inputTokens` | number |
| `outputTokens` | number |
| `cacheReadTokens` | number |
| `cacheCreationTokens` | number |
| `costUsd` | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/usage" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.usage();
```

**GET`/system/terminals` Open terminals**

The terminal sessions this sandbox is holding, which is what a terminal panel rebuilds its tabs from after a reload. The live typing and output run over a separate socket; this is the list.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `sessions` Every live surface the sandbox is… | object[] |
| `name` Its id, and what the close… | string |
| `label` What to call it on screen | string |
| `kind` What sort of thing it is:… | "shell" | "panel" | "agent" | "job" … (5) |
| `running` Whether it is alive | boolean |
| `activityAt` When it last produced output, in… | number |
| `exitCode` How the last thing in it… | number |
| `command` What is running in it right… | string |
| `extensionId` Which extension declared this process, when… | string |
| `processName` Which of that extension's processes it… | string |
| `help` The agent has stopped at something… | object |
| `requestId` What to send back when you… | string |
| `message` What the agent needs, in its… | string |
| `requestedAt` When it asked, in milliseconds | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/terminals" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.terminals();
```

**DELETE`/system/terminals/{name}` Close a terminal**

Destroys one terminal session and whatever was running inside it.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `name` required Which terminal | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X DELETE "$SANDBOX/system/terminals/nightly%20changelog" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.killTerminal({
 "name": "nightly changelog"
});
```

**GET`/system/terminals/{name}/scrollback` A terminal's history as plain text**

What has scrolled past in one terminal, as text you can select and copy. The live view is a picture of a screen on the far side of a socket, with nothing in the page to select, so scrolling back and copying is this call rather than a gesture.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `name` required Which terminal | string | address |
| `lines` How far back to ask for | number | query |

### What comes back

| Field | Type |
| --- | --- |
| `name` Which terminal this is from | string |
| `text` The history, oldest line first, with… | string |
| `lines` How many lines you got | number |
| `truncated` It stopped because you asked for… | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/terminals/nightly%20changelog/scrollback" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.terminalScrollback({
 "name": "nightly changelog"
});
```

**GET`/system/browsers` Browsers the agent has open**

Every browser a conversation currently has running and the pages inside each one. The picture of what they are showing comes over a separate socket; this is the roster.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `sessions` Every browser the agents have running,… | object[] |
| `name` Its id, and what the close… | string |
| `label` What to call it on screen:… | string |
| `server` Which browser drives it: the credential-free… | string |
| `running` Whether it is still open | boolean |
| `activityAt` When it last did anything, in… | number |
| `finishedAt` When it closed, in milliseconds | number |
| `help` The agent has hit something only… | object |
| `requestId` What to send back when you… | string |
| `message` What the agent needs, in its… | string |
| `requestedAt` When it asked, in milliseconds | number |
| `pages` Every page it has open | object[] |
| `id` Stable for the life of the… | string |
| `title` The page's title | string |
| `url` Where it is | string |
| `active` The one the agent last touched,… | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/browsers" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.browsers();
```

**DELETE`/system/browsers/{name}` Shut a browser down**

Closes one of the agent's browsers. Its next attempt to use that browser then fails as though it had crashed, which is the honest account of somebody pulling the plug.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `name` required Which browser | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X DELETE "$SANDBOX/system/browsers/nightly%20changelog" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.closeBrowser({
 "name": "nightly changelog"
});
```

**GET`/system/subagents` Helpers the agents have started**

Every helper agent this sandbox's conversations have delegated work to, whichever tool started it, with what each one is doing.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `sessions` Every helper this sandbox's conversations have… | object[] |
| `id` The id of the tool call… | string |
| `kind` What sort of helper: one the… | "subagent" | "codex" | "grok" |
| `conversationId` The conversation whose turn started it,… | string |
| `agentType` What kind of helper it is | string |
| `description` What it was asked to do,… | string |
| `model` Which model it runs on | string |
| `spawnDepth` How deep in the chain it… | number |
| `background` The parent carried on working instead… | boolean |
| `status` How it is going | "pending" | "running" | "blocked" | "completed" … (7) |
| `startedAt` When it started, in milliseconds | number |
| `endedAt` When it finished, in milliseconds | number |
| `activityAt` When it last did anything, in… | number |
| `tokens` What it has spent | number |
| `toolUses` How many tools it has used | number |
| `lastTool` The last one it reached for | string |
| `summary` Its report: what it concluded, without… | string |
| `error` Why it failed, when it did | string |
| `terminal` The terminal its command runs in,… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/subagents" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.subagents();
```

**GET`/system/subagents/{id}/transcript` A helper agent's record**

The full record of one delegated helper, in the same shape as any other conversation. It comes live from the parent turn while the helper works, and from stored history once it has finished.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `messages` The conversation, in order | object[] |
| `role` Who said it | "user" | "assistant" | "notice" |
| `text` The words | string |
| `sentAt` When it was sent, in milliseconds | number |
| `attachments` Files attached to this message, as… | string[] |
| `checkpointId` The saved point this message can… | string |
| `thinking` What the agent was reasoning about | string |
| `tools` The tool calls this part of… | object[] |
| `id` The call's id | string |
| `name` Which tool | string |
| `category` What kind of thing it does:… | "read" | "edit" | "delete" | "move" … (9) |
| `status` How it went | "pending" | "in_progress" | "completed" | "failed" |
| `target` What it acted on, in one… | string |
| `locations` The files it touched | object[] |
| `path` The file, as a workspace path,… | string |
| `line` Which line, counting from one | number |
| `content` What it produced: text, a change… | object[] |
| `type` Plain output | "text" |
| `text` What the tool said | string |
| `children` Calls a delegated helper made, nested… | object[] |
| `id` The call's id | string |
| `name` Which tool | string |
| `category` What kind of thing it does:… | "read" | "edit" | "delete" | "move" … (9) |
| `status` How it went | "pending" | "in_progress" | "completed" | "failed" |
| `target` What it acted on, in one… | string |
| `locations` The files it touched | object[] |
| `content` What it produced: text, a change… | object[] |
| `children` Calls a delegated helper made, nested… | object[] |
| `thinking` What the agent was reasoning about… | string |
| `thinking` What the agent was reasoning about… | string |
| `notes` What the sandbox added to this… | object[] |
| `title` The one line a reader sees,… | string |
| `text` The note itself, which is also… | string |
| `placed` A person wrote this in the… | boolean |
| `noticeAction` A one-press follow-up this recorded notice… | "tierHold" |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/system/subagents/a1b2c3d4/transcript" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.subagentTranscript({
 "id": "a1b2c3d4"
});
```

**POST`/system/computers/{id}/sandboxes/{slug}` Drive a sandbox on one of your own computers stream**

Start, stop, restart, update, rebuild, roll back or remove a sandbox running on a machine you own, relayed over the connection that machine holds open. The answer is a stream because the slowest of these takes minutes, and it is the same stream whichever you ask for. The daemon adds no opinion: the machine enforces its own permissions and a refusal arrives as the last line, in the machine's words, naming the switch to flip.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required | string | address |
| `slug` required | string | address |
| `op` required | "start" | "stop" | "restart" | "prepare" … (9) | body |
| `hash` | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `when event is "message"` | shape |
| `data` | object |
| `when kind is "line"` | shape |
| `text` | string |
| `when kind is "result"` | shape |
| `message` | string |
| `when kind is "error"` | shape |
| `message` | string |
| `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 |

Try it answered in this tab

curl

```bash
curl -N -X POST "$SANDBOX/system/computers/a1b2c3d4/sandboxes/nightly-changelog" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"op":"start","hash":"…"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.system.manageMachineSandbox({
 "id": "a1b2c3d4",
 "slug": "nightly-changelog",
 "op": "start",
 "hash": "…"
});
```

More in The sandbox itself

[Next Activity →](https://intentic.dev/api/activity/)
