# TypeScript SDK (/docs/sdk)



The `@crownest/sdk` package is the official TypeScript client for CrowNest.
It wraps the REST API with typed resource clients for sandboxes, commands,
Workspace Runs, files, artifacts, previews, and projects, and returns a
`SandboxHandle` that binds helpers to a specific sandbox.

## Install [#install]

Add the package to your project with your package manager of choice.

```bash title="Terminal"
pnpm add @crownest/sdk
# or
npm install @crownest/sdk
# or
yarn add @crownest/sdk
```

## Create a client [#create-a-client]

Call `createCrowNestClient` to construct a client. All options are
optional.

```ts
import { createCrowNestClient } from "@crownest/sdk";

const client = createCrowNestClient({
  credential: "cn_live_...", // or an agent token; falls back to env
  baseUrl: "https://api.crownest.dev", // default
});
```

| Option       | Type           | Default                    | Description                                                                       |
| ------------ | -------------- | -------------------------- | --------------------------------------------------------------------------------- |
| `credential` | `string`       | env var                    | Bearer token. Accepts an API key (`cn_live_...`) or agent token (`cn_agent_...`). |
| `apiKey`     | `string`       | env var                    | API key. Alias for `credential`.                                                  |
| `baseUrl`    | `string`       | `https://api.crownest.dev` | API base URL.                                                                     |
| `fetch`      | `typeof fetch` | global `fetch`             | Custom fetch implementation.                                                      |

When no credential is passed, the client reads `CROWNEST_BEARER_TOKEN`, then
falls back to `CROWNEST_API_KEY`. It throws if neither is set.

Create API keys in the dashboard; the raw key value is shown once at
creation.

## SandboxHandle [#sandboxhandle]

`client.sandboxes.create()` and `client.sandboxes.get()` return a
`SandboxHandle`: the full `Sandbox` object (`id`, `status`, `expiresAt`,
`metadata`, and so on) plus helpers bound to that sandbox, so you don't
pass the sandbox ID on every call.

```ts
const sandbox = await client.sandboxes.create({ template: "python-node" });

const result = await sandbox.commands.run("python3 -c 'print(40 + 2)'");
console.log(result.exitCode, result.stdout);

await sandbox.files.write("notes.txt", "hello from crownest");
const artifact = await sandbox.artifacts.create({ path: "notes.txt" });

await sandbox.kill();
```

The handle exposes:

* `sandbox.commands.run`, `sandbox.commands.cancel`, `sandbox.commands.wait`
* `sandbox.commands.get`, `sandbox.commands.logs`, `sandbox.commands.streamLogs`
* `sandbox.files.read`, `write`, `delete`, `list`, `stat`, `mkdir`, `move`,
  `downloadUrl`
* `sandbox.artifacts.create`, `list`, `get`, `delete`, `download`, `downloadUrl`
* `sandbox.previews.create`, `list`, `get`, `revoke`
* `sandbox.setTtl()` — resets the TTL countdown from the current time
* `sandbox.kill()` — destroys the sandbox and returns an updated handle
* `sandbox.waitUntilReady()` — polls until the sandbox can accept work

Top-level clients expose the same helpers when you already have a resource ID
and do not need a sandbox-bound handle.

## Projects [#projects]

List the projects your API key can access.

```ts
const projects = await client.projects.list();
// { data: [{ id: "prj_...", orgId, name, createdAt }, ...], hasMore: false }

const project = await client.projects.create({ name: "Agent Workspace" });
```

`list()` returns the REST page envelope. `create()` requires an org-wide key
with `project:create`.

## API keys [#api-keys]

Read and revoke API keys from trusted automation.

```ts
const keys = await client.apiKeys.list();
const key = keys.data[0] ?? (await client.apiKeys.get("key_..."));
await client.apiKeys.revoke(key.id);
```

`apiKeys` exposes list, get, and revoke only. API key creation stays in the
dashboard.

## Exported types [#exported-types]

The package exports `CrowNestClientOptions`, `RunCommandOptions`,
`SandboxHandle`, and the `CrowNestApiError` class, plus the resource types
(`Sandbox`, `Command`, `Artifact`, `Preview`, `Project`, and friends) from
the contracts package.

## Resource clients [#resource-clients]

Each resource client has its own reference page:

* [Sandboxes](/docs/sdk/sandboxes) — `client.sandboxes`: create, get, list,
  kill.
* [Commands](/docs/sdk/commands) — `client.commands`: run, start, get,
  cancel, logs, streamLogs.
* [Workspace Runs](/docs/sdk/workspace-runs) — `client.workspaceRuns`:
  create, upload archives, start, stream events, cancel, evidence.
* [Files](/docs/sdk/files) — `client.files`: read, write, delete, list,
  stat, mkdir, move, downloadUrl.
* [Artifacts](/docs/sdk/artifacts) — `client.artifacts`: create, list, get,
  download, downloadUrl, delete.
* [Code](/docs/sdk/code) — `client.code`: run, runStream, createContext,
  getContext, listContexts, deleteContext.
* [Previews](/docs/sdk/previews) — `client.previews`: create, list, get,
  revoke.
* [Errors](/docs/sdk/errors) — `CrowNestApiError`, error codes, and retry
  guidance.

## Next steps [#next-steps]

* [Sandboxes](/docs/sdk/sandboxes) — create your first sandbox.
* [Errors](/docs/sdk/errors) — handle failures and retries.
* [Sandboxes concept](/docs/concepts/sandboxes) — lifecycle, TTL, and
  templates.
