Runtime

How to rotate a preview token

Call sbx.previews.rotate(port): every token issued for that port stops working, and the call returns a new one.

On Runtime a preview is private from the moment you create it, and one call revokes every link you have handed out. The address stays the same, so a bookmark keeps working for anyone you give the new token. Previews live under runtimehost.com, never under withruntime.com, so what a sandbox serves never shares an origin with your account. A fresh sandbox to serve from ran its first command 351 ms after the request at the median on 24 September 2026 (speed).

Rotate the token

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create();await sbx.spawn("python3 -m http.server 3000");const first = await sbx.previews.create(3000);const fresh = await sbx.previews.rotate(3000); // first.token is refused from now onconst page = await fetch(fresh.url, {  headers: { "x-runtime-preview-token": fresh.token! },});console.log(fresh.url === first.url, page.status);
Pythonfrom withruntime import Sandboxwith Sandbox.create() as sbx:    sbx.spawn("python3 -m http.server 3000")    first = sbx.previews.create(3000)    fresh = sbx.previews.rotate(3000)  # first["token"] is refused from now on    print(fresh["url"] == first["url"], fresh["token"] is not None)

Over plain HTTPS the same call is a POST to the preview's :rotate route (API reference):

Terminalcurl -sS -X POST "https://api.withruntime.com/v1/sandboxes/${ID}/previews/3000:rotate" \  -H "Authorization: Bearer ${RUNTIME_API_KEY}"

The answer carries the new token and a new one-time urlWithToken for a browser. Send the token as the x-runtime-preview-token header from code.

When to rotate

  • A link went somewhere it should not: a public chat, a ticket, a screenshot, a log.
  • Someone who had access leaves the project. Rotation cuts off every holder at once, whoever they forwarded the link to.
  • A demo or review is over but the sandbox keeps running for you.
  • On a schedule, for a preview that stays up for days, so no token stays useful for long.

Rotate, delete or leave public

Call What happens
sbx.previews.create(3000) Shares the port, private: a request needs the token
sbx.previews.rotate(3000) Refuses every token issued for the port so far and returns a new one
sbx.previews.delete(3000) Stops sharing the port; runtime sandbox unshare <id> 3000 from the CLI
sbx.previews.create(3000, { visibility: "public" }) Anyone with the address can open it; no token to rotate
runtime sandbox previews <id> Lists the sandbox's shared ports

Rotating keeps the port shared and the server running. Deleting stops the sharing altogether. Choose rotate when the right people still need the page and delete when nobody does. MCP agents create, list and delete previews with runtime_sandbox_previews_create, _list and _delete (MCP).

Mistakes and how Runtime handles them

  • Forwarding urlWithToken. That link carries its token once, for one browser. Give each person their own, or send the token in the header from code.
  • Expecting a public preview to be protected. A public address needs no token, so rotating protects nothing. Keep previews that show private data private.
  • The page stops answering after a rotate. Old tokens are refused by design. Hand out the new one; the server inside the sandbox was not touched.
  • The server dies with its command. Start it with spawn, not exec, and have it listen on 0.0.0.0 or localhost inside the sandbox (the sandbox environment).
  • A paused sandbox. A visit to a shared port wakes it; the browser sees a short "Waking up" page that reloads itself (wake on request).

Every answer from a preview carries an X-Runtime-Report header, through which anyone can report it, and Runtime can turn a reported preview off (custom domains work the same way).

For your own hostname

A preview address is Runtime's. To serve the same port at a name you own, with HTTPS, add a custom domain. To reach the port from your own machine only, with no link at all, use port forwarding.

Facts on this page were checked on 25 September 2026.