> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a sandbox (E2B)

E2B's `POST /v2/sandboxes`. Claims a warm microVM of the template (`base`, `code-interpreter`, `agent` or `browser`; E2B's default `base`), with `envVars`, `metadata` and `timeout` (seconds, default 300, at most the plan's limit). `autoPause: true` pauses the sandbox at its timeout instead of stopping it. Egress: `allow_internet_access: false` or `network.denyOut: ["0.0.0.0/0"]` alone denies all; that `denyOut` with `network.allowOut` hosts allows only those hosts (ports 80 and 443 unless named). The key needs `sandboxes:run` as well as `sandboxes:write` (`403` without it), since the answer's `envdAccessToken` grants `sandboxes:run` on the new sandbox.
`Idempotency-Key` (the SDKs send one): a repeat with the same key and body from the same key returns the same sandbox with a new envd access token (the earlier one stays valid 60 seconds), for 24 hours; the token itself is never stored. Bills `sandboxes.vcpu_ms` and `sandboxes.gib_ms` while the sandbox runs. 

` POST /compat/e2b/v2/sandboxes `

Create a sandbox (E2B)

E2B's `POST /v2/sandboxes`. Claims a warm microVM of the template (`base`, `code-interpreter`, `agent` or
`browser`; E2B's default `base`), with `envVars`, `metadata` and `timeout` (seconds, default 300, at most
the plan's limit). `autoPause: true` pauses the sandbox at its timeout instead of stopping it. Egress:
`allow_internet_access: false` or `network.denyOut: ["0.0.0.0/0"]` alone denies all; that `denyOut` with
`network.allowOut` hosts allows only those hosts (ports 80 and 443 unless named). The key needs
`sandboxes:run` as well as `sandboxes:write` (`403` without it), since the answer's `envdAccessToken`
grants `sandboxes:run` on the new sandbox.

`Idempotency-Key` (the SDKs send one): a repeat with the same key and body from the same key returns the
same sandbox with a new envd access token (the earlier one stays valid 60 seconds), for 24 hours; the
token itself is never stored. Bills `sandboxes.vcpu_ms` and `sandboxes.gib_ms` while the sandbox runs.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Authentication

The operation accepts these alternatives. Schemes within one alternative are required together.

### Alternative 1

- ` apiKey `: ` http `

  - HTTP scheme: ` bearer ` (b3os_sk_ API key or b3os_pat_ token)

  - `Authorization: Bearer <credential>`. Two credential kinds are accepted:

- **API keys** `b3os_sk_<32 base32>_<crc32>`, created in the dashboard or with `POST /v1/keys`. A key belongs to
  one project, has scopes, an optional spend cap and expiry, and is shown only once.
- **CLI tokens** `b3os_pat_<32 base32>_<crc32>`, issued by the device login (`b3os login`). They act for one
  user in the organization and project chosen at approval.

Keys are stored as SHA-256 hashes. The edge exchanges them for a 60-second node token before forwarding
a request to a node, so nodes never see your key.


## Parameters

### ` Idempotency-Key ` (header, optional)

A value the SDKs send to make the create safe to retry. A repeat with the same key and body from the same key returns the same sandbox, with a new envd access token, for 24 hours; another body with the same key is refused with `409`. The token is never stored.

- ` value `: type ` string `

  - minLength: ` 1 `

  - maxLength: ` 255 `

## Request body (required)

Content type: ` application/json `

- ` value `: type ` object ` — E2B's create body. Unknown fields are ignored; the fields below that B3OS cannot honor are refused.

  - ` templateID `: type ` string ` — `base` (default), `code-interpreter`, `agent` or `browser`, or a template's `tpl_` id.

  - ` timeout `: type ` integer ` — Seconds until the sandbox ends (default 300).

    - minimum: ` 1 `

  - ` metadata `: type ` object `

  - ` envVars `: type ` object `

  - ` autoPause `: type ` boolean ` — Pause instead of stopping at the timeout.

  - ` autoPauseMemory `: type ` boolean ` — `false` (a filesystem-only pause) is refused.

  - ` autoResume `: type ` object ` — Refused when `enabled` is true.

  - ` allow_internet_access `: type ` boolean `

  - ` network `: type ` object ` — `allowOut` hosts, and `denyOut: ["0.0.0.0/0"]`; other fields are refused.

  - ` mcp `: type ` object ` — Refused.

  - ` volumeMounts `: type ` array ` — Refused.

    - ` array item `: type ` object `

  - ` iam `: type ` object ` — Refused.

Example:

```json
{
  "templateID": "base",
  "timeout": 300,
  "metadata": {
    "run": "demo"
  },
  "envVars": {
    "GREETING": "hello"
  }
}
```

## Responses

### ` 201 ` — The sandbox, running, with its envd access token.

Content type: ` application/json `

- ` value `: type ` object ` — A created or connected sandbox.

  - Required fields: ` sandboxID `, ` templateID `, ` clientID `, ` envdVersion `, ` envdAccessToken `

  - ` sandboxID `: type ` string `

  - ` templateID `: type ` string `

  - ` clientID `: type ` string `

  - ` envdVersion `: type ` string ` — The envd protocol version the SDKs check features against.

  - ` envdAccessToken `: type ` string ` — The envd access token (`b3os_et_…`): valid at most 1 hour, while the sandbox is running or paused and the key that minted it is not revoked. Returned only here and by connect.

  - ` domain `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "sandboxID": "sbx-01m5t68q1b590rj801nbzsqzkk",
  "templateID": "base",
  "clientID": "b3os",
  "envdVersion": "0.5.7",
  "envdAccessToken": "b3os_et_BeHVb2oQkV3ZzHdpPJ2b0rlwxn6jQe7fT1sfJk0Uf2c",
  "domain": null
}
```

### ` 400 ` — A malformed value, or an option B3OS cannot honor named in the message (`invalid_request`, `unsupported_option`).

Content type: ` application/json `

- ` value `: type ` object ` — E2B's error body.

  - Required fields: ` code `, ` message `

  - ` code `: type ` integer ` — The HTTP status.

  - ` message `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "code": 400,
  "message": "mcp is not supported by B3OS: run your MCP server as a process in the sandbox"
}
```

### ` 401 ` — Missing or invalid B3OS key in `X-API-KEY` (`unauthorized`).

Content type: ` application/json `

- ` value `: type ` object ` — E2B's error body.

  - Required fields: ` code `, ` message `

  - ` code `: type ` integer ` — The HTTP status.

  - ` message `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "code": 401,
  "message": "unknown key"
}
```

### ` 403 ` — The key lacks a scope the operation needs (`forbidden`).

Content type: ` application/json `

- ` value `: type ` object ` — E2B's error body.

  - Required fields: ` code `, ` message `

  - ` code `: type ` integer ` — The HTTP status.

  - ` message `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "code": 403,
  "message": "this credential lacks the scope sandboxes:run"
}
```

### ` 404 ` — No such live sandbox, template or file (`sandbox_not_found`, `template_not_found`, `file_not_found`).

Content type: ` application/json `

- ` value `: type ` object ` — E2B's error body.

  - Required fields: ` code `, ` message `

  - ` code `: type ` integer ` — The HTTP status.

  - ` message `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "code": 404,
  "message": "No sandbox sbx_01m5t68q1b590rj801nbzsqzkk in this project"
}
```

### ` 429 ` — Over a limit of the organization (`limit_exceeded`, `rate_limited`); `Retry-After` says when.

Content type: ` application/json `

- ` value `: type ` object ` — E2B's error body.

  - Required fields: ` code `, ` message `

  - ` code `: type ` integer ` — The HTTP status.

  - ` message `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "code": 429,
  "message": "The organization has 10 running or paused sandboxes, its limit"
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/compat/e2b/v2/sandboxes' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "templateID": "base",
  "timeout": 300,
  "metadata": {
    "run": "demo"
  },
  "envVars": {
    "GREETING": "hello"
  }
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/compat/e2b/v2/sandboxes', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "templateID": "base",
    "timeout": 300,
    "metadata": {
      "run": "demo"
    },
    "envVars": {
      "GREETING": "hello"
    }
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/compat/e2b/v2/sandboxes', headers=headers, json={
  "templateID": "base",
  "timeout": 300,
  "metadata": {
    "run": "demo"
  },
  "envVars": {
    "GREETING": "hello"
  }
})
print(response.json())
```