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

# Ports and preview links

> Share a server running inside a sandbox: signed links, public ports, or the traffic token.

Every port of a sandbox has a URL: `https://<port>-<sandbox id>.sbx.compute.anonalabs.com`. The SDK builds it for you with `get_host`. Who can open it depends on how you share it:

| Way | Who gets in | Good for |
| - | - | - |
| **Preview link** | Anyone with the link, for one port, until it expires (1 minute to 24 hours) | Showing a dev server or app to a person |
| **Public port** | Anyone, on that port, until you make it private again | Webhook receivers, demos |
| **Traffic token** | Requests carrying the `e2b-traffic-access-token` header | Your own backend or proxy |
| **Public sandbox** (`allow_public_traffic`) | Anyone, on every port | Throwaway previews |

Port 49983 (`envd`, which runs commands and files) is never shared: it always needs the sandbox's own access token, which the SDK holds.

## Preview links

```bash preview.sh theme={null}
anona-compute preview "$SANDBOX_ID" 3000              # prints a link, valid 1 hour
anona-compute preview "$SANDBOX_ID" 3000 --ttl 15m
anona-compute preview "$SANDBOX_ID" --revoke          # ends every link (and live-view token) of the sandbox
```

```python preview_link.py theme={null}
import os
import httpx

api = httpx.Client(base_url="https://api.compute.anonalabs.com", headers={"X-API-Key": os.environ["E2B_API_KEY"]})
sid = os.environ["SANDBOX_ID"]

link = api.post(f"/v1/sandboxes/{sid}/preview-links", json={"port": 3000, "ttlSeconds": 900}).json()
print(link["url"].split("?")[0], "expires", link["expiresAt"])

api.post(f"/v1/sandboxes/{sid}/preview-links:revoke-all").raise_for_status()
```

The link looks like `https://3000-<id>.sbx.compute.anonalabs.com/?anona_sig=…&anona_exp=…`. On the first visit the sandbox edge exchanges it for a cookie that is scoped to that one port's host (`Secure`, `HttpOnly`, `SameSite=Lax`) and redirects to the same URL without the signature, so the app inside never sees it. Other ports and other sandboxes stay private.

Revoking ends every link and every live-view token of the sandbox within a second. The dashboard's sandbox page has **Share preview**, and agents get links from the MCP tool `get_preview_url`.

## Public ports

```bash public_port.sh theme={null}
anona-compute preview "$SANDBOX_ID" 8080 --public     # anyone can open port 8080, no link needed
curl -sS "https://api.compute.anonalabs.com/v1/sandboxes/$SANDBOX_ID/access" -H "X-API-Key: $E2B_API_KEY" | jq -c .
anona-compute preview "$SANDBOX_ID" 8080 --private
```

Up to 64 public ports per sandbox. `PUT /v1/sandboxes/{id}/ports/{port}` with `{"public": true}` does the same over the API.

## Traffic token

For your own services, keep the port private and send the sandbox's traffic token:

```python private_port.py theme={null}
import httpx
from anona import Sandbox

with Sandbox.create("python", network={"allow_public_traffic": False}) as sbx:
    sbx.commands.run("cd /tmp && python3 -m http.server 8000", background=True)
    sbx.commands.run("for i in $(seq 50); do curl -s localhost:8000 >/dev/null && break; sleep 0.1; done")
    url = "https://" + sbx.get_host(8000)
    print(httpx.get(url).status_code)  # refused without the token
    print(httpx.get(url, headers={"e2b-traffic-access-token": sbx.traffic_access_token}).status_code)
```

A request to a paused sandbox's URL gets `409`; resume it with `Sandbox.connect` first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.