# Sandboxes (/docs/sdk/sandboxes)



`client.sandboxes` manages sandbox lifecycle. Its methods return
[`SandboxHandle`](/docs/sdk) values — sandbox records with bound Command, file,
preview, artifact, TTL, and lifecycle helpers.

## create [#create]

Create a sandbox from a template. The call resolves once the sandbox
record exists; check `status` and `expiresAt` on the returned handle.

```ts
create(input?: CreateSandboxInput): Promise<SandboxHandle>
```

| Field               | Type                     | Default        | Description                                                                                                                                                          |
| ------------------- | ------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `template`          | `string`                 | server default | Template slug. `python-node` is the broad default; `node` is the lean JavaScript and TypeScript environment.                                                         |
| `templateVersionId` | `` `tplv_${string}` ``   | —              | Pin an immutable TemplateVersion instead of a slug.                                                                                                                  |
| `ttlMs`             | `number`                 | `3600000`      | Requested lifetime in milliseconds. Positive integer, capped at 3600000 ms (1 hour) at creation. Use `setTtl` to reset the countdown, up to a 24-hour total session. |
| `metadata`          | `Record<string, string>` | —              | Labels for correlation and filtering. Max 16 keys, key up to 64 chars, value up to 512 chars, 4 KB total.                                                            |
| `projectId`         | `` `prj_${string}` ``    | server default | Project to create the sandbox in.                                                                                                                                    |
| `idempotencyKey`    | `string`                 | SDK-generated  | Idempotency key with a 24-hour retry window.                                                                                                                         |

```ts
const sandbox = await client.sandboxes.create({
  template: "python-node",
  ttlMs: 10 * 60 * 1000,
  metadata: { run: "nightly-eval" },
});

console.log(sandbox.id, sandbox.status, sandbox.expiresAt);
```

Error codes: `invalid_request`, `forbidden`, `not_found`,
`quota_exceeded`, `sandbox_ttl_exceeded` (requested `ttlMs` exceeds your
plan limit).

## get [#get]

Fetch a sandbox by ID and get a handle bound to it.

```ts
get(sandboxId: `sbx_${string}`): Promise<SandboxHandle>
```

```ts
const sandbox = await client.sandboxes.get("sbx_abc123");
console.log(sandbox.status);
```

Error codes: `not_found`, `forbidden`.

## setTtl [#setttl]

Set a live sandbox's TTL, reset its expiration countdown from the time of the
request, and get a refreshed handle.

```ts
setTtl(
  sandboxId: `sbx_${string}`,
  input: { ttlMs: number; idempotencyKey?: string },
): Promise<SandboxHandle>
```

| Field            | Type     | Default       | Description                                                           |
| ---------------- | -------- | ------------- | --------------------------------------------------------------------- |
| `ttlMs`          | `number` | —             | New lifetime in milliseconds from now, up to a 24-hour total session. |
| `idempotencyKey` | `string` | SDK-generated | Idempotency key with a 24-hour retry window.                          |

```ts
const updated = await client.sandboxes.setTtl(sandbox.id, {
  ttlMs: 60 * 60 * 1000,
});

console.log(updated.expiresAt);
```

You can also call `sandbox.setTtl({ ttlMs })` on a handle.

Error codes: `invalid_request`, `not_found`, `forbidden`,
`sandbox_destroyed`, `sandbox_ttl_exceeded`.

## list [#list]

List sandboxes visible to your API key. Live sandboxes are returned;
destroyed and failed records are excluded by default.

```ts
list(input?: ListSandboxesInput): Promise<ListSandboxHandlesResponse>
```

```ts
const sandboxes = await client.sandboxes.list();
for (const sandbox of sandboxes.data) {
  await sandbox.commands.run("python --version");
}
```

## kill [#kill]

Destroy a sandbox. The operation is idempotent by state: killing an
already destroyed sandbox returns the destroyed record. The returned
sandbox has status `destroyed` and `destroyedReason` `user_killed`.

```ts
kill(sandboxId: `sbx_${string}`): Promise<SandboxHandle>
```

```ts
const destroyed = await client.sandboxes.kill(sandbox.id);
console.log(destroyed.status, destroyed.destroyedReason);
```

You can also call `sandbox.kill()` on a handle. Both forms return an updated
`SandboxHandle`.

<Callout type="warn" title="Important">
  Killing a sandbox discards the workspace filesystem. Export anything you need to keep
  with [artifacts](/docs/sdk/artifacts) first.
</Callout>

Error codes: `not_found`, `forbidden`.

## Sandbox object [#sandbox-object]

The `Sandbox` type includes `id` (`sbx_` prefix), `orgId`, `projectId`,
`status` (`creating`, `starting`, `ready`, `running`, `idle`, `expiring`,
`destroyed`, `failed`), `templateId`, `templateSlug`, `templateVersion`,
`templateVersionId`, `ttlMs`, `expiresAt` (ISO 8601), `metadata`, and —
once destroyed — `destroyedAt` and `destroyedReason`.

## Next steps [#next-steps]

* [Commands](/docs/sdk/commands) — run processes inside the sandbox.
* [Files](/docs/sdk/files) — manage the workspace filesystem.
* [Sandboxes concept](/docs/concepts/sandboxes) — lifecycle, TTL, and
  templates in depth.
