How to expose a port from a sandbox at an HTTPS URL
Start the server with spawn, then call sbx.previews.create(port); the address needs a token unless you pass visibility: "public".
On Runtime a shared port is private by default, lives on its own domain,
runtimehost.com, and wakes a paused sandbox when someone visits it. So a
preview can sit idle for days at paused-storage prices, $0.08 per decimal GB
of saved state a month, instead of a running machine's $0.03125 an hour for 2
vCPU and 4 GiB (rates checked 25 September 2026, pricing).
Runtime adds no badge or banner to the pages a preview serves.
Share a port and call it
TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create();await sbx.spawn("python3 -m http.server 3000");const preview = await sbx.previews.create(3000);const page = await fetch(preview.url, { headers: { "x-runtime-preview-token": preview.token! },});console.log(page.status); // 200Pythonimport urllib.requestfrom withruntime import Sandboxwith Sandbox.create() as sbx: sbx.spawn("python3 -m http.server 3000") preview = sbx.previews.create(3000) request = urllib.request.Request(preview["url"], headers={"x-runtime-preview-token": preview["token"]}) print(urllib.request.urlopen(request).status) # 200Terminalruntime sandbox preview "${id}" 3000 # private, with a tokenruntime sandbox preview "${id}" 3000 --public # anyone with the addressruntime sandbox previews "${id}"runtime sandbox unshare "${id}" 3000An agent on MCP uses runtime_sandbox_previews_create, _list and _delete.
Who can open it
| How you share it | Who gets in | Send |
|---|---|---|
| Private, from code | A client that sends the token | x-runtime-preview-token: <token> |
| Private, in a browser | Whoever opens the one-time link | preview.urlWithToken |
| Public | Anyone with the address | preview.url |
Making a port public or private is written to the account's audit log, with who did it and from where.
Manage the tokens
- Revoke every token at once with
previews.rotate(port). Every token issued before it is refused; use it when a link went somewhere it should not. - Stop sharing with
previews.delete(port). - List what is shared with
runtime sandbox previews <id>.
A private preview's token expires, so a link sent today does not work forever (network access).
What the server must do
- Run under
spawn, notexec. Everything anexecstarts,nohup … &included, ends when its command does.spawnkeeps the server running after your call returns. - Listen on
0.0.0.0orlocalhostinside the sandbox. - WebSockets work, so dev servers keep their live reload.
A paused sandbox wakes on a visit
A visit to a shared port wakes a paused sandbox that has automatic wake on.
An API client's request waits up to 30 seconds for it, and a browser sees a
short "Waking up" page that reloads itself. The wake is an ordinary wake,
billed from the moment it runs. Pair a preview with idlePauseSeconds, which
counts preview requests as use, and the sandbox runs only while people use it
(pause and resume).
Preview, port-forward, SSH or a domain?
| You need | Use |
|---|---|
| A URL for a person or a webhook | A preview |
| The port on your own machine, just for you | runtime sandbox port-forward <id> 3000 |
| A shell or an editor in the sandbox | runtime sandbox ssh <id> (editors) |
| Your own hostname, paid accounts | runtime domain add app.example.com <id> 3000 |
| A raw TCP port, such as Postgres, paid accounts | runtime port open <id> 5432 |
Port-forward and SSH go through Runtime's API with your key, so the sandbox opens nothing to the internet (networking).
Mistakes to avoid
- Putting the token in a shared URL by hand. Send it as the header from
code, or give a browser
urlWithToken, which carries it once. - Making a preview public to skip the token. A public address is open to anyone who finds it. Keep it private unless it is meant as a demo.
- Serving from
exec. The server ends when the command returns, and nothing is left listening behind the preview. - Expecting
previews_unavailableto clear. That 503 means previews are switched off there on purpose; retrying will not help. - Treating the address as your site. Preview addresses sit under
runtimehost.com, never underwithruntime.com, so a sandbox's pages never share an origin with your account.
For a full product built on previews, see preview apps an AI agent builds; for browser automation against a preview, see Playwright.
Facts on this page were checked on 25 September 2026.