# E2B compatibility

Set `E2B_DOMAIN=rent.dev` and the E2B SDK talks to rent.dev. The API host serves E2B's own paths, without a `/v1` prefix, for 39 of the 126 routes in E2B's spec.

`POST https://api.rent.dev/sandboxes`

## Point the SDK at rent.dev

```sh
export E2B_DOMAIN=rent.dev
export E2B_API_KEY=e2b_<the 64 hex characters of your rent.dev key>
```

```ts
import { Sandbox } from "e2b";

const sandbox = await Sandbox.create("base");
const result = await sandbox.commands.run("echo hello");
console.log(result.stdout);
await sandbox.kill();
```

A rent.dev key works in either spelling: `rent_sk_` plus 64 hex characters, or `e2b_` plus the same 64. The second is there for tools that check the prefix. Get a key with `POST /v1/accounts`; see [the agent quickstart](/docs/agents).

Sandbox ports are served at `https://{port}-{sandboxID}.rent.dev`, which is where `sandbox.getHost(port)` points.

## What it costs

A sandbox created through the SDK is a rent.dev sandbox: it draws on the prepaid balance by the second, at [rent.dev's own price](/docs/pricing). Creating one takes a hold first, so a short balance answers 402 before anything starts.

Errors keep E2B's shape, `{code, message}`, so the SDK reads them as it reads E2B's own. A refusal from rent.dev adds its Problem code as `error_code`, and a 402 keeps `balance_required_micros` and the `topup` links:

```json
{
  "code": 402,
  "message": "Insufficient balance",
  "error_code": "insufficient_balance",
  "balance_required_micros": 9075,
  "topup": {
    "checkout_url": "https://api.rent.dev/pay/<token>",
    "x402_url": "https://api.rent.dev/v1/credits/x402?amount_usd=0.009075"
  }
}
```

## rent.dev options through metadata

Two metadata keys on create carry what the E2B API has no field for:

| Metadata key | Value |
| --- | --- |
| `rent.dev/profile` | The workload profile: `agent-loop`, `interactive` or `workspace`. Used for placement when the account has no history. |
| `rent.dev/allow` | Comma-separated endpoint ids a create may also use, such as `byok-e2b`, each with a [stored credential](/docs/byok) for its vendor. This path has no `deny`: rent.dev's own supply is used while it can take the sandbox, and your own key only when own supply is down or full. To place on your own key every time, create through `/v1` with `routing.deny`: see [placing on your own key](/docs/byok#sandboxes). An id that names no endpoint answers 400. The key is never sent upstream. A sandbox on your own E2B key has been tested against a stand-in for E2B's API, and has not yet been run against a live E2B account. |

Keys starting `rentdev_` are reserved for rent.dev's own labels and are dropped from a request.

## Known gaps

- Template builds work from an image or another template with command steps. A `copy()` step needs a file upload, and uploads are closed.
- `volumeMounts`, `iam`, `mcp` and an egress proxy are refused on create with 400 `unsupported_parameter`.
- A pause always keeps memory. Asking for a filesystem-only pause is refused.
- `cpuCount` must match the template's; a sandbox cannot be resized on create or resume.
- `getMetrics` is not supported.
- These paths reach a sandbox that runs on E2B's API: rent.dev's own, or one on your own E2B key. A sandbox placed on your own Vercel token answers 404 here. Manage it through `/v1`, where it cannot be paused or resumed and has no log stream; [the table](/docs/byok#verbs) lists what each vendor can do.
- Team, node, admin, volume, secret, API-key and webhook routes are not served. They answer 404.

> Measured 2026-11-11 18:49 UTC with `npm:e2b@2.46.1 and 2.63.0`, `npm:@e2b/code-interpreter@2.9.1`, `pypi:e2b@2.46.0 and 2.63.0`, `pypi:e2b-code-interpreter@2.11.9`.

## Sandbox routes

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| `GET /health` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /sandboxes` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `POST /sandboxes` | Partial | Pass | `volumeMounts`, `iam`, `mcp`, `network.egressProxy` and `autoPauseMemory: false` answer 400 `unsupported_parameter`. `cpuCount` must be the template's. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0. |
| `POST /v2/sandboxes` | Partial | Pass | `volumeMounts`, `iam`, `mcp`, `network.egressProxy` and `autoPauseMemory: false` answer 400 `unsupported_parameter`. `cpuCount` must be the template's. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.63.0. |
| `GET /v2/sandboxes` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /sandboxes/{sandboxID}/logs` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /v2/sandboxes/{sandboxID}/logs` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /sandboxes/{sandboxID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `DELETE /sandboxes/{sandboxID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /sandboxes/{sandboxID}/metrics` | Not supported | Pass | Sandbox metrics are not supported: `getMetrics` answers an empty list. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/pause` | Partial | Pass | `memory: false` (a filesystem-only pause) and `requireHealthyGuest: true` answer 400 `unsupported_parameter`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/resume` | Partial | Pass | `memory: false` answers 400 `unsupported_parameter`. `cpuCount` must be the sandbox's. Measured with npm e2b 2.46.1 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/fork` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/connect` | Partial | Pass | `memory: false` answers 400 `unsupported_parameter`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0. |
| `POST /v2/sandboxes/{sandboxID}/connect` | Partial | Pass | `memory: false` answers 400 `unsupported_parameter`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.63.0. |
| `POST /sandboxes/{sandboxID}/timeout` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `PUT /sandboxes/{sandboxID}/network` | Partial | Pass | `egressProxy` answers 400 `unsupported_parameter`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/refreshes` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `POST /sandboxes/{sandboxID}/snapshots` | Partial | Pass | Own sandboxes only. A sandbox on your own E2B key is snapshotted with E2B's API. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /snapshots` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |

## Template routes

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| `POST /v3/templates` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /v2/templates` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/files/{hash}` | Not supported | Pass | Answers 501: template file uploads are closed, so builds work without `copy()` steps. Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `POST /templates/tags` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `DELETE /templates/tags` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /templates/aliases/{alias}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /templates/{templateID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `DELETE /templates/{templateID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `PATCH /templates/{templateID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `POST /v2/templates/{templateID}/builds/{buildID}` | Partial | Pass | A step with a `filesHash` (a `copy()` step) answers 400 `unsupported_parameter`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `PATCH /v2/templates/{templateID}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/builds/{buildID}/status` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /templates/{templateID}/builds/{buildID}/logs` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/tags` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `GET /templates/{templateID}/tags/groups` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/tags/count` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/tags/exists` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |
| `GET /templates/{templateID}/tags/{tag}/assignments` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0. |

## Request parameters

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| `volumeMounts` on create | Not supported | Pass | Volumes are not available: the parameter answers 400 and `/volumes` is not served. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `iam` on create | Not supported | Pass | Workload identity is not available. Measured with npm e2b 2.46.1 and 2.63.0. |
| `mcp` on create | Not supported | Pass | The MCP gateway is not available. Measured with npm e2b 2.46.1 and 2.63.0. |
| `network.egressProxy` on create and on a network update | Not supported | Pass | An egress proxy is not available. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `autoPauseMemory: false` on create, `memory: false` on pause, resume and connect | Not supported | Pass | A pause always keeps memory: a filesystem-only pause cannot be requested. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `requireHealthyGuest` on pause | Not supported | Pass | The guest check cannot be requested. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.63.0. |
| `cpuCount` on create and resume | Partial | Pass | Accepted only when it equals the template's vCPU count. Measured with npm e2b 2.46.1 and 2.63.0. |
| Metadata `rent.dev/profile` | Supported | Pass | A rent.dev key: declares the workload profile, `agent-loop`, `interactive` or `workspace`. Measured with npm e2b 2.46.1 and 2.63.0. |
| Metadata `rent.dev/allow` | Supported | Pass | A rent.dev key: comma-separated endpoint ids to place on besides own supply. Never sent upstream. Measured with npm e2b 2.46.1 and 2.63.0. |
| Metadata keys starting `rentdev_` | Partial | Pass | Reserved: client keys with this prefix are dropped, and rent.dev's own are not shown. Measured with npm e2b 2.46.1 and 2.63.0. |

## SDK calls

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| `Sandbox.create()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Sandbox.connect()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Sandbox.list()` | Supported | Pass | Lists your own sandboxes. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.getInfo()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.setTimeout()` | Supported | Pass | Takes the added hold first. A session lasts at most 24 hours. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.kill()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.betaPause()` and `sandbox.pause()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.fork()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.createSnapshot()` and `Sandbox.listSnapshots()` | Supported | Pass | Own sandboxes only. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.commands.run()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.pty` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.files.read()`, `write()`, `list()` and `watchDir()` | Partial | Pass | The edge refuses request bodies over 100 MB. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.getHost(port)` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `sandbox.getMetrics()` | Not supported | Pass | Sandbox metrics are not supported: `getMetrics` answers an empty list. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Template.build()` from an image or another template, with `runCmd()` steps | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Template.build()` with `copy()` steps | Not supported | Pass | Template file uploads are closed. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Volume` | Not supported | Pass | Volumes are not available. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `@e2b/code-interpreter`: `sandbox.runCode()` on `code-interpreter-v1` | Supported | Pass | Measured with npm @e2b/code-interpreter 2.9.1; PyPI e2b-code-interpreter 2.11.9. |

## Measured behaviour

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| A `rent_sk_` key as `E2B_API_KEY` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| The same key written `e2b_` plus the same 64 hex characters | Supported | Pass | For tools that check the prefix. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Sandbox.list()` pages with `limit` and `nextToken` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `Sandbox.list()` filtered by metadata | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Run a command: exit code, stdout and stderr | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Background commands, listed while they run | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Stdin to a running command | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Kill a running command | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Write and read files, text and bytes | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| List a directory | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Watch a directory | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Signed `uploadUrl()` and `downloadUrl()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Upload a 99 MB body | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Upload a body over 100 MB | Not supported | Pass | The edge refuses request bodies over 100 MB: write a larger file in parts. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Download a 101 MiB file | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| A sandbox port over HTTP at `https://{port}-{sandboxID}.{domain}` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| A sandbox port over WebSocket | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Pause and resume keep memory and disk | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `lifecycle.onTimeout: 'pause'` (`autoPause`) | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| `lifecycle.autoResume`: traffic resumes a paused sandbox | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Network `allowOut` and `denyOut`, on create and with `updateNetwork()` | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Template names are your own: namespaced per account upstream and mapped back | Supported | Pass | Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |
| Errors in E2B's shape, raised as the SDK's own error classes | Supported | Pass | A refusal from rent.dev adds its Problem code as `error_code`. Measured with npm e2b 2.46.1 and 2.63.0; PyPI e2b 2.46.0 and 2.63.0. |

## Routes not served

| Feature | Support | Result | Note |
| --- | --- | --- | --- |
| `/teams*` (3 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/unstable/*` (44 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/sandboxes/metrics` (1 route of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/default-templates` (1 route of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/nodes*` (4 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/admin/*` (7 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/api-keys*` (4 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/volumes*` (4 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/secrets*` (5 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/clusters*` (5 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |
| `/events/*` (9 routes of the spec) | Not supported | Pass | Answers 404 without being forwarded. Measured with npm e2b 2.46.1 and 2.63.0. |

## The spec this is measured against

The route rows come from `e2b-dev/runtime` at commit `f3eee1ae84e2b1d893bc7806280a9a33f2e9001e`, whose spec lists 126 routes.
