Preview URLs
Give a server running inside a sandbox a public https address, so the person who asked for it can just click a link.
A sandbox has no inbound network. A server started in one listens on its own
localhost, the same as on a laptop, and until now nothing outside could reach it. That
ruled out the most common thing people build with sandboxes: an agent writes a web app, and whoever
asked for it wants to look at it.
Open one
POST https://sandbox-as-a-service.com/v1/sandboxes/{id}/ports
curl -sS -X POST -H "$AUTH" -H "$JSON" \\
-d '{"port":3000}' \\
$API/sandboxes/$SBX/portspreview = requests.post(
f"{API}/sandboxes/{sandbox_id}/ports",
headers=headers, json={"port": 3000},
).json()
print(preview["url"]) # https://preview.sandbox-as-a-service.com/<token>/
The response is the address, and it works as soon as something is listening:
{
"object": "port",
"sandbox_id": "sbx_...",
"port": 3000,
"url": "https://preview.sandbox-as-a-service.com/8f2c...b41a/",
"created_at": "2026-08-22T20:14:03.221Z"
}
Asking again for the same port returns the same URL rather than minting a second one, so it is safe to call on every run.
A complete round trip
Write an app, start it, and hand back a link:
curl -sS -X PUT -H "$AUTH" -H "$JSON" \\
-d '{"path":"app.py","content":"from http.server import *\\nHTTPServer((\\"127.0.0.1\\",3000), SimpleHTTPRequestHandler).serve_forever()"}' \\
$API/sandboxes/$SBX/files
curl -sS -X POST -H "$AUTH" -H "$JSON" \\
-d '{"command":"nohup python3 app.py > server.log 2>&1 & sleep 1; echo started"}' \\
$API/sandboxes/$SBX/exec
curl -sS -X POST -H "$AUTH" -H "$JSON" -d '{"port":3000}' \\
$API/sandboxes/$SBX/ports
Note the &: exec waits
for the command to finish, so a server has to be started in the background or it will hold the request
open until the timeout.
How it reaches your server
The request arrives at our edge, and is carried into the sandbox over the same connection we use to run your commands. Your machine's firewall is not touched, no port is opened to the internet, and the sandbox's inbound surface stays exactly what it was: nothing.
Preview URLs live on their own hostname, deliberately separated from the site you sign in to, so a page served from a sandbox can never read your session. They do share that hostname with each other: two previews are the same origin, and only the token in the path tells them apart. Since a token is 160 random bits, one preview cannot find another — but it is worth knowing that the separation between previews is the secrecy of the URL rather than the browser's origin boundary.
That is a deliberate trade. The obvious implementation — a public port and a firewall rule per sandbox — would put every half-finished dev server directly on the internet, reachable by anyone who found the address, and would rewrite the firewall on every create. This way the only thing that can reach your server is a process that already holds the host key.
Closing one
DELETE https://sandbox-as-a-service.com/v1/sandboxes/{id}/ports/{port}
The URL stops resolving immediately. The server inside the sandbox keeps running — closing a preview is about who can reach it, not about what is running.
Everything is closed when the sandbox goes away, so cleaning up is optional.
Limits worth knowing
| Ports per sandbox | No fixed limit; one live URL per port. |
| Port 22 | Refused — it would publish an SSH endpoint. |
| Lifetime | Tied to the sandbox, so at most 24 hours. |
| Protocols | HTTP and WebSocket. Not raw TCP. |
| Who can reach it | Anyone with the link. Treat the URL as a secret. |
| Isolation | Separate origin from the main site; previews share an origin with each other. |
Does my server need to bind 0.0.0.0?
No — and it should not. Listening on localhost is enough, exactly as it would be on your own machine. The request is carried into the sandbox over the connection we already hold, so nothing about the machine's own network is changed and no inbound port is opened.
Who can open the URL?
Anyone who has it. That is the point — you share it with the person who asked the agent for the thing. The token in the hostname is 160 bits from a CSPRNG, so it is not something anyone finds by guessing, but treat it as a capability: whoever holds the link reaches the server.
How long does it last?
As long as the sandbox does. When the sandbox is destroyed or expires the URL stops resolving, and so does every other preview on it — up to the 24 hours ceiling. You can also close one explicitly without touching the sandbox.
Do WebSockets work?
Yes. Upgrades are passed through, so a dev server with live reload behaves the way it does locally.
Can I expose the SSH port?
No. Port 22 is refused, because publishing it would hand an SSH endpoint to anyone holding the URL.