# Code (/docs/sdk/code)



`client.code` runs Python, JavaScript, or TypeScript snippets inside a live
Sandbox. A [`SandboxHandle`](/docs/sdk) exposes the same helpers as
`sandbox.code.*`, so most code can stay sandbox-scoped instead of passing
the Sandbox id repeatedly.

Use [Commands](/docs/sdk/commands) for top-level process records and shell
commands. Use Code Runs for notebook-style snippets, stateful interpreter
work, rich outputs, and streamed execution events. Code Runs are not
durable resources; export files or promote outputs to
[Artifacts](/docs/sdk/artifacts) when you need persistence.

<Callout type="info" title="Default language">
  The TypeScript SDK defaults Code Contexts and Code Runs to `python` when you omit
  `language`. Pass `javascript` or `typescript` when you want those interpreters.
</Callout>

## run [#run]

Run a snippet and wait for the result.

```ts
run(
  sandboxId: `sbx_${string}`,
  input: RunCodeInput,
): Promise<RunCodeResult>
```

`RunCodeInput`:

| Field            | Type                                       | Default       | Description                                                             |
| ---------------- | ------------------------------------------ | ------------- | ----------------------------------------------------------------------- |
| `code`           | `string`                                   | required      | Source to execute, capped at 256 KB.                                    |
| `language`       | `"python" \| "javascript" \| "typescript"` | `"python"`    | Interpreter language.                                                   |
| `contextId`      | `` `cctx_${string}` ``                     | SDK-created   | Existing Code Context to reuse.                                         |
| `cwd`            | `string`                                   | `/workspace`  | Working directory inside the Workspace.                                 |
| `timeoutMs`      | `number`                                   | `60000`       | Code Run timeout in milliseconds, maximum 600000.                       |
| `artifactPolicy` | `"inline_only" \| "promote"`               | `inline_only` | Whether artifact-capable rich outputs should be promoted to Artifacts.  |
| `idempotencyKey` | `string`                                   | SDK-generated | Idempotency key with a 24-hour retry window for the completed Code Run. |

```ts title="main.ts"
const result = await sandbox.code.run({
  code: `
total = sum([10, 20, 12])
print(f"total={total}")
total
`,
});

process.stdout.write(result.stdout);
console.log(result.outputs);
```

`RunCodeResult` includes `sandboxId`, `contextId`, `language`,
`executionCount`, `stdout`, `stderr`, `outputs`, optional truncation flags,
optional `error`, and `durationMs`.

## Code Contexts [#code-contexts]

A Code Context keeps language state inside one Sandbox. Use it when values,
imports, or loaded data should persist across runs.

```ts
createContext(
  sandboxId: `sbx_${string}`,
  input?: CreateCodeContextInput,
): Promise<CodeContextRef>

listContexts(sandboxId: `sbx_${string}`): Promise<ListCodeContextsResponse>

getContext(
  sandboxId: `sbx_${string}`,
  contextId: `cctx_${string}`,
): Promise<CodeContextRef>
```

```ts title="stateful.ts"
const context = await sandbox.code.createContext({ language: "python" });
const contexts = await sandbox.code.listContexts();
console.log(contexts.data.map((item) => item.id));
const sameContext = await sandbox.code.getContext(context.id);

await sandbox.code.run({
  contextId: context.id,
  code: "import math\nradius = 4",
});

const result = await sandbox.code.run({
  contextId: context.id,
  code: "print(math.pi * radius ** 2)",
});

console.log(result.stdout);

await sandbox.code.deleteContext(context.id);
```

`CreateCodeContextInput` accepts `language`, `cwd`, `timeoutMs`, and
`idempotencyKey`. Context creation defaults to `/workspace` and a 30000 ms
context timeout, with a maximum of 600000 ms. Deleting a context is
best-effort against the provider, but CrowNest metadata is authoritative.

If you omit `contextId` from `run`, CrowNest lazily creates or reuses one
default Code Context for the Sandbox and language. The result always returns
the `contextId` that was used.

## Rich outputs [#rich-outputs]

Code Runs return `outputs` rather than forcing everything through stdout.
Each output is one of:

| Kind       | Description                                                                  |
| ---------- | ---------------------------------------------------------------------------- |
| `inline`   | Small text, markdown, JSON, data, chart, or LaTeX value in the response.     |
| `artifact` | Promoted output stored as an Artifact, with `artifactId` and content type.   |
| `rejected` | Output CrowNest could not inline or promote, with a stable rejection reason. |

Use `artifactPolicy: "promote"` when code may produce images, HTML, SVG,
or larger structured results that should survive after the Sandbox is gone.
Promotion requires the `artifact:create` scope.

```ts title="plot.ts"
import { writeFile } from "node:fs/promises";

const result = await sandbox.code.run({
  artifactPolicy: "promote",
  code: `
import matplotlib.pyplot as plt

plt.figure()
plt.plot([1, 2, 3], [2, 5, 4])
plt.title("Weekly score")
plt.show()
`,
});

const image = result.outputs.find(
  (output) => output.kind === "artifact" && output.format === "png",
);

if (image?.kind === "artifact") {
  const bytes = await client.artifacts.download(image.artifactId);
  await writeFile("weekly-score.png", bytes);
}
```

Each inline output is capped, and total inline output is capped per Code
Run. Large or unsafe outputs may be rejected with reasons such as
`output_too_large`, `requires_artifact_promotion`, or
`unsafe_active_content`.

## runStream [#runstream]

Stream interpreter events as the Code Run executes.

```ts
runStream(
  sandboxId: `sbx_${string}`,
  input: RunCodeInput,
): AsyncIterable<CodeRunEvent>
```

`CodeRunEvent`:

| Event      | Shape                                         |
| ---------- | --------------------------------------------- |
| `stdout`   | `{ type: "stdout", data: string }`            |
| `stderr`   | `{ type: "stderr", data: string }`            |
| `output`   | `{ type: "output", data: CodeOutput }`        |
| `error`    | `{ type: "error", data: CodeExecutionError }` |
| `complete` | `{ type: "complete", data: RunCodeResult }`   |

```ts title="stream.ts"
let finalResult;

for await (const event of sandbox.code.runStream({
  code: `
import time
for idx in range(3):
    print(f"step {idx}")
    time.sleep(0.2)
`,
})) {
  if (event.type === "stdout") process.stdout.write(event.data);
  if (event.type === "stderr") process.stderr.write(event.data);
  if (event.type === "error") {
    console.error(event.data.message);
  }
  if (event.type === "complete") {
    finalResult = event.data;
  }
}

console.log(finalResult?.executionCount);
```

Stream replay is result-only in v1. Reusing a completed idempotency key
emits a single `complete` event with the stored result.

## Execution errors [#execution-errors]

Interpreter failures are part of the Code Run result, not SDK transport
errors. A Python exception resolves normally with `result.error`, and may
also appear as a streaming `error` event.

```ts
const result = await sandbox.code.run({ code: "1 / 0" });

if (result.error) {
  console.error(result.error.name);
  console.error(result.error.message);
  console.error(result.error.traceback?.join("\n"));
}
```

API-level failures still throw `CrowNestApiError`, for example
`forbidden`, `not_found`, `sandbox_destroyed`, `code_source_too_large`,
`unsupported_code_language`, or `quota_exceeded`.

## JavaScript and TypeScript [#javascript-and-typescript]

Pass `language` when you don't want Python.

```ts
const js = await sandbox.code.run({
  language: "javascript",
  code: "console.log(JSON.stringify({ ok: true }))",
});

const ts = await sandbox.code.run({
  language: "typescript",
  code: "const answer: number = 42; console.log(answer)",
});
```

Code Contexts are language-specific. Keep separate contexts if you switch
between Python, JavaScript, and TypeScript in the same Sandbox.

## Next steps [#next-steps]

* [Code concept](/docs/concepts/code) - how Code Contexts and Code Runs
  fit the resource model.
* [Commands](/docs/sdk/commands) - run top-level processes and stream logs.
* [Artifacts](/docs/sdk/artifacts) - persist rich outputs.
* [Code API reference](/docs/api/code)
