INTEGRITY Cloudflare Docs

Ports

Expose services running in your sandbox via public preview URLs. See Preview URLs concept for details.

Module functions

proxyToSandbox()

Route incoming HTTP and WebSocket requests to the correct sandbox container. Call this at the top of your Worker's fetch handler, before any application logic, so that it intercepts and forwards preview URL requests automatically.

proxyToSandbox(request: Request, env: Env): Promise<Response | null>

Parameters:

Returns: Promise<Response | null> — a Response if the request matched a preview URL and was routed to the sandbox, or null if the request did not match and should be handled by your application logic.

The function inspects the request hostname to determine whether it matches the subdomain pattern of an exposed port (for example, 8080-sandbox-id-token.yourdomain.com). If it matches, proxyToSandbox() proxies the request to the correct Durable Object, and the sandbox service handles it. Both HTTP and WebSocket upgrade requests are supported.

import { proxyToSandbox, getSandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
	async fetch(request, env) {
		// Always call proxyToSandbox first to handle preview URL requests
		const proxyResponse = await proxyToSandbox(request, env);
		if (proxyResponse) return proxyResponse;

		// Your application routes
		const sandbox = getSandbox(env.Sandbox, "my-sandbox");
		// ...
		return new Response("Not found", { status: 404 });
	},
};
import { proxyToSandbox, getSandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Always call proxyToSandbox first to handle preview URL requests
    const proxyResponse = await proxyToSandbox(request, env);
    if (proxyResponse) return proxyResponse;

    // Your application routes
    const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
    // ...
    return new Response('Not found', { status: 404 });
  }
};

Methods

exposePort()

Expose a port and get a preview URL for accessing services running in the sandbox.

const response = await sandbox.exposePort(port: number, options: ExposePortOptions): Promise<ExposePortResponse>

Parameters:

Returns: Promise<ExposePortResponse> with port, url (preview URL), name

// Extract hostname from request
const { hostname } = new URL(request.url);

// Basic usage with auto-generated token
await sandbox.startProcess("python -m http.server 8000");
const exposed = await sandbox.exposePort(8000, { hostname });

console.log("Available at:", exposed.url);
// https://8000-sandbox-id-abc123random.yourdomain.com

// With custom token for stable URLs across restarts
const stable = await sandbox.exposePort(8080, {
	hostname,
	token: "my_service_v1", // 1-16 chars: a-z, 0-9, _
});
console.log("Stable URL:", stable.url);
// https://8080-sandbox-id-my_service_v1.yourdomain.com

// With custom token for stable URLs across deployments
await sandbox.startProcess("node api.js");
const api = await sandbox.exposePort(3000, {
	hostname,
	name: "api",
	token: "prod-api-v1", // URL stays same across restarts
});

console.log("Stable API URL:", api.url);
// https://3000-sandbox-id-prod-api-v1.yourdomain.com

// Multiple services with custom tokens
await sandbox.startProcess("npm run dev");
const frontend = await sandbox.exposePort(5173, {
	hostname,
	name: "frontend",
	token: "dev-ui",
});
// Extract hostname from request
const { hostname } = new URL(request.url);

// Basic usage with auto-generated token
await sandbox.startProcess('python -m http.server 8000');
const exposed = await sandbox.exposePort(8000, { hostname });

console.log('Available at:', exposed.url);
// https://8000-sandbox-id-abc123random.yourdomain.com

// With custom token for stable URLs across restarts
const stable = await sandbox.exposePort(8080, {
  hostname,
  token: 'my_service_v1' // 1-16 chars: a-z, 0-9, _
});
console.log('Stable URL:', stable.url);
// https://8080-sandbox-id-my_service_v1.yourdomain.com

// With custom token for stable URLs across deployments
await sandbox.startProcess('node api.js');
const api = await sandbox.exposePort(3000, {
  hostname,
  name: 'api',
  token: 'prod-api-v1'  // URL stays same across restarts
});

console.log('Stable API URL:', api.url);
// https://3000-sandbox-id-prod-api-v1.yourdomain.com

// Multiple services with custom tokens
await sandbox.startProcess('npm run dev');
const frontend = await sandbox.exposePort(5173, {
  hostname,
  name: 'frontend',
  token: 'dev-ui'
});

Custom Tokens for Stable URLs

Custom tokens enable consistent preview URLs across container restarts and deployments. This is useful for:

Token Requirements:

// Production API with stable URL
const { url } = await sandbox.exposePort(8080, {
	hostname: "api.example.com",
	token: "v1-stable", // Always the same URL
});

// Error: Token collision prevention
await sandbox.exposePort(8081, { hostname, token: "v1-stable" });
// Throws: Token 'v1-stable' is already in use by port 8080

// Success: Re-exposing same port with same token (idempotent)
await sandbox.exposePort(8080, { hostname, token: "v1-stable" });
// Works - same port, same token
// Production API with stable URL
const { url } = await sandbox.exposePort(8080, {
  hostname: 'api.example.com',
  token: 'v1-stable'  // Always the same URL
});

// Error: Token collision prevention
await sandbox.exposePort(8081, { hostname, token: 'v1-stable' });
// Throws: Token 'v1-stable' is already in use by port 8080

// Success: Re-exposing same port with same token (idempotent)
await sandbox.exposePort(8080, { hostname, token: 'v1-stable' });
// Works - same port, same token

validatePortToken()

Validate if a token is authorized to access a specific exposed port. Useful for custom authentication or routing logic.

const isValid = await sandbox.validatePortToken(port: number, token: string): Promise<boolean>

Parameters:

Returns: Promise<boolean> - true if token is valid for the port, false otherwise

// Custom validation in your Worker
export default {
	async fetch(request, env) {
		const url = new URL(request.url);

		// Extract token from custom header or query param
		const customToken = request.headers.get("x-access-token");

		if (customToken) {
			const sandbox = getSandbox(env.Sandbox, "my-sandbox");
			const isValid = await sandbox.validatePortToken(8080, customToken);

			if (!isValid) {
				return new Response("Invalid token", { status: 403 });
			}
		}

		// Handle preview URL routing
		const proxyResponse = await proxyToSandbox(request, env);
		if (proxyResponse) return proxyResponse;

		// Your application routes
		return new Response("Not found", { status: 404 });
	},
};
// Custom validation in your Worker
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    
    // Extract token from custom header or query param
    const customToken = request.headers.get('x-access-token');
    
    if (customToken) {
      const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
      const isValid = await sandbox.validatePortToken(8080, customToken);
      
      if (!isValid) {
        return new Response('Invalid token', { status: 403 });
      }
    }
    
    // Handle preview URL routing
    const proxyResponse = await proxyToSandbox(request, env);
    if (proxyResponse) return proxyResponse;
    
    // Your application routes
    return new Response('Not found', { status: 404 });
  }
};

unexposePort()

Remove an exposed port and close its preview URL.

await sandbox.unexposePort(port: number): Promise<void>

Parameters:

await sandbox.unexposePort(8000);
await sandbox.unexposePort(8000);

getExposedPorts()

Get information about all currently exposed ports.

const response = await sandbox.getExposedPorts(): Promise<GetExposedPortsResponse>

Returns: Promise<GetExposedPortsResponse> with ports array (containing port, url, name)

const { ports } = await sandbox.getExposedPorts();

for (const port of ports) {
	console.log(`${port.name || port.port}: ${port.url}`);
}
const { ports } = await sandbox.getExposedPorts();

for (const port of ports) {
  console.log(`${port.name || port.port}: ${port.url}`);
}

wsConnect()

Connect to WebSocket servers running in the sandbox. Use this when your Worker needs to establish WebSocket connections with services in the sandbox.

Common use cases:

For exposing WebSocket services via public preview URLs, use exposePort() with proxyToSandbox() instead. See WebSocket Connections guide for examples.

const response = await sandbox.wsConnect(request: Request, port: number): Promise<Response>

Parameters:

Returns: Promise<Response> - WebSocket response establishing the connection

import { getSandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
	async fetch(request, env) {
		if (request.headers.get("Upgrade")?.toLowerCase() === "websocket") {
			const sandbox = getSandbox(env.Sandbox, "my-sandbox");
			return await sandbox.wsConnect(request, 8080);
		}

		return new Response("WebSocket endpoint", { status: 200 });
	},
};
import { getSandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.headers.get('Upgrade')?.toLowerCase() === 'websocket') {
      const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
      return await sandbox.wsConnect(request, 8080);
    }

    return new Response('WebSocket endpoint', { status: 200 });
  }
};