Skip to main content
Sandboxes instantly launch with the configuration you need. When a sandbox is created, it is always running until you stop it or it times out. By default, this is based on your team’s default Session Timeout setting which you can change on the Settings page. You can also configure the timeout per session during sandbox session creation For example, set a custom session timeout when creating the sandbox:
const sandbox = await client.sandboxes.create({
  imageName: "node",
  timeoutMinutes: 30,
});

Getting a Sandbox

Fetch a detailed sandbox handle by ID:
const sandbox = await client.sandboxes.get("sandbox-id");

// {
//   "id": "sandbox-id",
//   "teamId": "team-id",
//   "status": "active",
//   "endTime": null,
//   "startTime": 1712749200000,
//   "createdAt": "2026-04-10T11:59:00.000Z",
//   "updatedAt": "2026-04-10T12:00:00.000Z",
//   "region": "us-west",
//   "sessionUrl": "https://app.hyperbrowser.ai/sandbox/sandbox-id",
//   "duration": 30,
//   "proxyBytesUsed": 0,
//   "cpu": 2,
//   "memoryMiB": 2048,
//   "diskMiB": 8192,
//   "runtime": {
//     "transport": "regional_proxy",
//     "host": "runtime-usw2.example.hyperbrowser.ai",
//     "baseUrl": "https://your-runtime-url"
//   },
//   "exposedPorts": [
//     {
//       "port": 3000,
//       "auth": true,
//       "url": "https://your-runtime-url/p/3000",
//       "browserUrl": "https://your-runtime-url/_hb/auth?grant=token&next=%2F",
//       "browserUrlExpiresAt": "2026-04-10T12:10:00.000Z"
//     }
//   ],
//   "token": "sandbox-runtime-token",
//   "tokenExpiresAt": "2026-04-10T12:00:00.000Z"
// }

Listing Sandboxes

List your sandboxes with optional filtering:
const response = await client.sandboxes.list({
  status: "active",
  page: 1,
  limit: 20,
});

// {
//   "totalCount": 1,
//   "sandboxes": [
//     {
//       "id": "sandbox-id",
//       "status": "active",
//       "region": "us-west"
//     }
//   ]
// }

Refreshing and Connecting

Connect to an existing sandbox or refresh the runtime token.
The runtime token is given when the sandbox is created. For long running sandboxes, refresh may be needed to extend the token lifetime. For a more detailed guide to runtime tokens, see Sandbox Runtime URLs.
// Refresh an existing handle
await sandbox.refresh();

// Reconnect from an ID
const reattached = await client.sandboxes.connect("sandbox-id");

// {
//   "id": "sandbox-id",
//   "runtime": {
//     "baseUrl": "https://your-runtime-url"
//   }
// }

Stopping a Sandbox

Always stop a sandbox when you are done with it:
await sandbox.stop();

// {
//   "id": "sandbox-id",
//   "status": "stopped"
// }
Stopping a sandbox is safe to call more than once.

Exposing Ports

Expose a port when you need a custom process to be accessible from outside from the sandbox. This provides a custom runtime URL for that exposed port.
const exposure = await sandbox.expose({
  port: 3000,
  auth: true,
});

// {
//   "port": 3000,
//   "auth": true,
//   "url": "https://your-runtime-url/p/3000",
//   "browserUrl": "https://your-runtime-url/_hb/auth?grant=token&next=%2F",
//   "browserUrlExpiresAt": "2026-04-10T12:00:00Z"
// }

// Helper for deriving the URL for an exposed port:
// sandbox.getExposedUrl(3000)
If auth is enabled, send the sandbox bearer token when calling the exposed URL:
const detail = await sandbox.info();
const response = await fetch(`${exposure.url}/health`, {
  headers: {
    Authorization: `Bearer ${detail.token}`,
  },
});

const body = await response.text();

// {
//   "status": 200,
//   "body": "<service response>"
// }
For a dedicated guide to runtime URLs, exposed service URLs, browser auth links, and end-to-end examples, see Sandbox Runtime URLs.
Port 4001 is reserved for the sandbox runtime API url and cannot be exposed.