POST /v1/sandboxes/{sandbox_id}/egress
Replaces the sandbox's `egress` policy (mode and allow list) while it runs or is paused. New outbound connections and DNS answers follow the new policy at once, and open connections it does not allow (SOCKS5, HTTP CONNECT and transparently redirected TCP alike) are closed: under `allowlist`, a connection stays open only if the host name it was opened for is on the new list (one opened by address alone is closed); under `deny`, every connection closes. Private, loopback, tailnet and metadata addresses stay refused in every mode. A sandbox cannot change its own policy (its in-VM API gets `403 forbidden`, `reason: self`, whatever its grant); call from outside it. Code in a sandbox may only narrow another sandbox's policy, to one within both that sandbox's current policy and its own (otherwise `403 forbidden`, `reason: egress_escalation`). A change cuts the streams code in other sandboxes holds open into this sandbox, and those code in this sandbox holds into others, once their target is no longer within the caller's reach (`sandboxesCreateSandbox`); the processes and files such code placed stay.

Authentication

Bearer Token (b3os_sk_ API key or b3os_pat_ token) API Key (cookie: __Host-b3os_session)

Path Parameters

sandbox_id string required path
The sandbox ID (`sbx_…`).
Example: "sbx_01m5t68q1b590rj801nbzsqzkk"

Request Body required

application/json
mode string
Enum: public, allowlist, deny
allow string[]
Array of: string

Responses

200 The sandbox with its new `egress`.
application/json
id string REQUIRED
object string REQUIRED
Enum: sandbox
status string REQUIRED
`running` → `paused` ↔ `running` → `stopped`. `failed` means the microVM crashed; its usage is final.
Enum: running, paused, stopped, failed
host_id string REQUIRED
The ID in host-safe form, used in port URLs.
template object REQUIRED
id string REQUIRED
name string REQUIRED
snapshot string | null REQUIRED
The snapshot the sandbox was restored from.
vcpu integer REQUIRED
memory_mib integer REQUIRED
disk_gib integer REQUIRED
timeout_s integer REQUIRED
on_idle string REQUIRED
Enum: stop, pause
expires_at string (date-time) REQUIRED
env object REQUIRED
secret_names string[] REQUIRED
Names of the variables set from `secrets` (values are never returned).
Array of: string
ports object[] REQUIRED
Array of:
port integer REQUIRED
public boolean REQUIRED
url string (uri) | null REQUIRED
Public ports: the long-lived preview URL, token included. Private ports: `null`; mint a URL with `POST /v1/sandboxes/{sandbox_id}/ports/{port}/url`. Also `null` when code in another sandbox reads this sandbox and this sandbox is not within that sandbox's reach (`sandboxesCreateSandbox`).
api object REQUIRED
scopes string[] REQUIRED
Array of: string
spend_cap_usd number | null REQUIRED
The grant's own cap, or `null` when the creating principal's cap applies.
connections string[] REQUIRED
Array of: string
egress object REQUIRED
mode string REQUIRED
Enum: public, allowlist, deny
allow string[] REQUIRED
Array of: string
forkable boolean REQUIRED
created_at string (date-time) REQUIRED
started_at string (date-time) REQUIRED
paused_at string (date-time) | null REQUIRED
stopped_at string (date-time) | null REQUIRED
stop_reason string | null REQUIRED
Why the sandbox stopped: `deleted`, `timeout` (it reached `expires_at`), `failed` (the microVM crashed), `budget` (while it ran, its organization was suspended or ran out of credits, or the creating key or the sandbox's own `api.spend_cap_usd` reached its cap; the node checks every 10 s) or `revoked` (the key that created it was revoked).
Enum: deleted, timeout, failed, budget, revoked, null
usage object REQUIRED
vcpu_ms integer REQUIRED
gib_ms integer REQUIRED
readiness object | null
The readiness probe and what it found; `null` when the sandbox has none.
status string REQUIRED
`failed`: the probe did not pass within its `timeout_s`, or the sandbox stopped first.
Enum: pending, ready, failed
probe object REQUIRED
When the sandbox counts as ready: a TCP port inside it accepting connections (`port`), or a command that exits 0 (`cmd`, run as `user` with a 5 s limit per try). Set exactly one. The node tries it every `interval_ms` from the moment it is set until it passes or `timeout_s` runs out; the sandbox's `readiness` reports the result and `POST /v1/sandboxes/{sandbox_id}/ready` waits for it. Probing goes on across a restart of the node's daemon, within the same `timeout_s`; `attempts` counts the tries since the daemon last recorded a change of `status`, so it can start again from a lower number after such a restart.
port integer
cmd string | string[]
A shell command line (run with `/bin/sh -c`) or an argv array.
One of:
Option 1string
Option 2
Array of: string
interval_ms integer
timeout_s integer
attempts integer REQUIRED
ready_at string (date-time) | null REQUIRED
time_to_ready_ms integer | null REQUIRED
From the create's start (or from when the probe was set) to the first passing try.
last_error string | null REQUIRED
Why the last failing try failed.
timing object
Server-side phase durations in milliseconds with microsecond resolution: the same phases as the `Server-Timing` header, keyed `<phase>_ms`. `total_ms` is always present. Phase names are product-specific and documented per operation. Example values in this reference are illustrative, not measurements.
total_ms number REQUIRED
metadata object REQUIRED
Up to 16 string key-value pairs you attach to an object for your own use. Keys are 1 to 40 characters of `A-Z a-z 0-9 _ . : -`; values are at most 500 characters. B3OS never interprets them.
400 The request failed validation (`invalid_request`, `invalid_url`).
401 Missing, malformed, expired or revoked credentials (`unauthorized`).
403 Authenticated but not allowed (`forbidden`, `egress_denied`).
404 No such sandbox in this project (`sandbox_not_found`).
409 The sandbox is paused or stopped (`sandbox_not_running`).
413 The request body exceeds this operation's limit.
415 The Content-Type is not accepted by this operation.
429 A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).
500 Something failed inside B3OS (`internal`). Retry with backoff.
503 The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).
curl -X POST 'https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/egress' \  -H 'Authorization: Bearer YOUR_API_TOKEN' \  -H 'Content-Type: application/json' \  -d '{  "mode": "public",  "allow": [    "string"  ]}'
const response = await fetch('https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/egress', {  method: 'POST',  headers: {      "Authorization": "Bearer YOUR_API_TOKEN",      "Content-Type": "application/json"  },  body: JSON.stringify({    "mode": "public",    "allow": [      "string"    ]  })});const data = await response.json();console.log(data);
import requestsheaders = {    'Authorization': 'Bearer YOUR_API_TOKEN'}response = requests.post('https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/egress', headers=headers, json={  "mode": "public",  "allow": [    "string"  ]})print(response.json())
200 Response
{  "id": "sbx_01m5t68q1b590rj801nbzsqzkk",  "object": "sandbox",  "status": "running",  "host_id": "sbx-01m5t68q1b590rj801nbzsqzkk",  "template": {    "id": "tpl_01m5t59b2ps0djyzdf082s18bz",    "name": "base"  },  "snapshot": null,  "vcpu": 1,  "memory_mib": 512,  "disk_gib": 4,  "timeout_s": 900,  "on_idle": "stop",  "expires_at": "2026-10-25T19:15:00.004Z",  "env": {},  "secret_names": [],  "ports": [],  "api": {    "scopes": [],    "spend_cap_usd": null,    "connections": []  },  "egress": {    "mode": "allowlist",    "allow": [      "github.com",      "*.githubusercontent.com",      "pypi.org",      "files.pythonhosted.org"    ]  },  "forkable": false,  "created_at": "2026-10-25T19:00:00.000Z",  "started_at": "2026-10-25T19:00:00.004Z",  "paused_at": null,  "stopped_at": null,  "stop_reason": null,  "usage": {    "vcpu_ms": 2100,    "gib_ms": 300000  },  "metadata": {}}
Ask a question... ⌘I