Skip to main content

Documentation Index

Fetch the complete documentation index at: https://hyperbrowser.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Sandboxes have real URL endpoints when you start it. No extra configuration required. Pick your favorite framework and get started. Sandboxes have two types of URLs:
  • runtime - This is the URL you use to access the sandbox’s runtime API. It is reserved on port 4001.
  • custom - This is any other port you wish to expose within the sandbox that is not reserved. You can set up any process you want on the sandbox on the specified port.

Runtime URL vs Custom Port URL

Every running sandbox includes a runtime base URL for API calls.
const sandbox = await client.sandboxes.create({
  imageName: "node",
});

console.log("Runtime URL:", sandbox.runtime.baseUrl);

// The SDK sends this to sandbox.runtime.baseUrl + /sandbox/exec for you.
const result = await sandbox.exec(`node -e 'console.log("hello from runtime")'`);
console.log(result.stdout.trim());
SDK handles the sandbox runtime layer for you URL for you when you use the runtime functions, see Node SDK sandboxes and Python SDK sandboxes.
To make a service reachable, start it inside the sandbox and expose its port. For example:
  • runtime.baseUrl looks like https://<runtime-host>/
  • exposed port 3000 looks like https://3000-<runtime-host>/
The SDK can derive that URL locally:
sandbox.getExposedUrl(3000);

Example: Expose a Public HTTP Server

The example below provides a public URL which you can use for running your own services inside the sandbox. For sensitive workloads, treat this as any other publicly accessible endpoint and authenticate your requests properly.
Start a simple HTTP server inside the sandbox, expose port 3000, and call it from outside the sandbox.
const sandbox = await client.sandboxes.create({
  imageName: "node",
});

const server = await sandbox.processes.start(`node -e "const http = require('http');

http
  .createServer((_, res) => {
    res.writeHead(200, { 'content-type': 'text/plain' });
    res.end('hello from sandbox');
  })
  .listen(3000, '0.0.0.0')"`);

await new Promise((resolve) => setTimeout(resolve, 1000));

const exposure = await sandbox.expose({
  port: 3000,
  auth: false,
});

console.log("Service URL:", exposure.url);

const response = await fetch(exposure.url);
console.log(await response.text());

Auth Enabled (auth: true)

When auth is true, the exposed custom URL now requires the auth token to be passed on each request.
Call exposure.url programmatically and pass the sandbox bearer token in the Authorization header.
Open exposure.browserUrl in a browser when you need a user-facing flow for an auth-protected endpoint.
browserUrl performs auth bootstrap first and then redirects to the path in next.
Use auth: false when you want open browser access and keep auth/authorization logic inside your own application.

Backend Workflow (Bearer Token)

This flow is best for backend automation and API calls. Call the protected exposed URL with the sandbox bearer token.
const sandbox = await client.sandboxes.create({
  imageName: "node",
});

await sandbox.processes.start(`node -e "const http = require('http');

http
  .createServer((req, res) => {
    if (req.url === '/api/status') {
      res.writeHead(200, { 'content-type': 'application/json' });
      res.end(JSON.stringify({ ok: true }));
      return;
    }
    res.writeHead(404);
    res.end('not found');
  })
  .listen(3000, '0.0.0.0')"`);

await new Promise((resolve) => setTimeout(resolve, 1000));

const exposure = await sandbox.expose({
  port: 3000,
  auth: true,
});

const detail = await sandbox.info();
const apiUrl = new URL("/api/status", exposure.url);

const response = await fetch(apiUrl, {
  headers: {
    Authorization: `Bearer ${detail.token}`,
  },
});

console.log(await response.text());

Browser Workflow (Preview URL Redirect)

Use the auth-enabled endpoint to generate a protected preview URL for browser access.
const sandbox = await client.sandboxes.create({
  imageName: "node",
});

await sandbox.processes.start(`node -e "const http = require('http');

http
  .createServer((req, res) => {
    if (req.url === '/preview') {
      res.writeHead(200, { 'content-type': 'text/html' });
      res.end('<h1>Sandbox Preview</h1><p>Protected by sandbox auth.</p>');
      return;
    }
    res.writeHead(404);
    res.end('not found');
  })
  .listen(3000, '0.0.0.0')"`);

await new Promise((resolve) => setTimeout(resolve, 1000));

const exposure = await sandbox.expose({
  port: 3000,
  auth: true,
});

const browserUrl = new URL(exposure.browserUrl);
browserUrl.searchParams.set("next", "/preview");

console.log("Open preview URL:", browserUrl.toString());
browserUrl is not the raw port API URL. It is a bootstrap URL that sets the auth cookie and then redirects to next. Use url for programmatic clients, and use browserUrl when you want to land a browser on a protected page.