Quick start
This launches your OpenClaw gateway site (web UI for chatting with agents).import { Sandbox } from 'e2b'
const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
// 1. Create sandbox
const sandbox = await Sandbox.create('openclaw', {
envs: { OPENAI_API_KEY: process.env.OPENAI_API_KEY },
timeoutMs: 3600_000,
})
// 2. Set the default model
await sandbox.commands.run('openclaw config set agents.defaults.model.primary openai/gpt-5.2')
// 3. Set insecure control UI flags and start the gateway with token auth
await sandbox.commands.run(
`bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && ` +
`openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && ` +
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}'`,
{ background: true }
)
// 4. Wait for the gateway to start listening
for (let i = 0; i < 45; i++) {
const probe = await sandbox.commands.run(
`bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'`
)
if (probe.stdout.trim() === 'ready') break
await new Promise((r) => setTimeout(r, 1000))
}
const url = `https://${sandbox.getHost(PORT)}/?token=${TOKEN}`
console.log(`Gateway: ${url}`)
import os, time
from e2b import Sandbox
TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token")
PORT = 18789
# 1. Create sandbox
sandbox = Sandbox.create("openclaw", envs={
"OPENAI_API_KEY": os.environ["OPENAI_API_KEY"],
}, timeout=3600)
# 2. Set the default model
sandbox.commands.run("openclaw config set agents.defaults.model.primary openai/gpt-5.2")
# 3. Set insecure control UI flags and start the gateway with token auth
sandbox.commands.run(
f"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && "
f"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && "
f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}'",
background=True,
)
# 4. Wait for the gateway to start listening
for _ in range(45):
probe = sandbox.commands.run(
f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\''
)
if probe.stdout.strip() == "ready":
break
time.sleep(1)
url = f"https://{sandbox.get_host(PORT)}/?token={TOKEN}"
print(f"Gateway: {url}")
Gateway URL in your browser.
If you run in secure mode (set gateway.controlUi.dangerouslyDisableDeviceAuth false), run this after opening the URL to poll pending pairing requests and approve the first one.
// 5. Poll for the browser's pending device request and approve it
for (let i = 0; i < 30; i++) {
try {
const res = await sandbox.commands.run(
`openclaw devices list --json --url ws://127.0.0.1:${PORT} --token ${TOKEN}`
)
const data = JSON.parse(res.stdout)
if (data.pending?.length) {
const rid = data.pending[0].requestId
await sandbox.commands.run(
`openclaw devices approve ${rid} --token ${TOKEN} --url ws://127.0.0.1:${PORT}`
)
console.log(`Device approved: ${rid}`)
break
}
} catch {}
await new Promise((r) => setTimeout(r, 2000))
}
import json
# 5. Poll for the browser's pending device request and approve it
for _ in range(30):
try:
res = sandbox.commands.run(
f"openclaw devices list --json --url ws://127.0.0.1:{PORT} --token {TOKEN}"
)
data = json.loads(res.stdout)
if data.get("pending"):
rid = data["pending"][0]["requestId"]
sandbox.commands.run(
f"openclaw devices approve {rid} --token {TOKEN} --url ws://127.0.0.1:{PORT}"
)
print(f"Device approved: {rid}")
break
except Exception:
pass
time.sleep(2)
How it works
| Step | What happens |
|---|---|
--bind lan | Gateway listens on 0.0.0.0 so E2B can proxy it |
--auth token | Requires ?token= on the URL for HTTP and WebSocket auth |
| Browser opens URL | Gateway serves the UI, browser opens a WebSocket |
code=1008 pairing required | Gateway closes the WebSocket until the device is approved (secure mode only) |
devices approve | Approves the browser’s device fingerprint (secure mode only) |
| Browser reconnects | WebSocket connects successfully, UI is live |
Gateway flags reference
| Flag | Purpose |
|---|---|
--allow-unconfigured | Start without a full config file |
--bind lan | Bind to 0.0.0.0 (required for E2B port proxying) |
--auth token | Enable token-based authentication |
--token <value> | The auth token (passed as ?token= in the URL) |
--port <number> | Gateway listen port (default: 18789) |
How to restart the gateway
Use this when the gateway is already running and you want a clean restart (for example, after changing model or env settings).We can’t use the
openclaw gateway restart command here. Some SDK environments cannot target a specific Unix user in commands.run. The commands below use the default command user context.const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
// 1) Kill existing gateway processes if present
await sandbox.commands.run(
`bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'`
)
await new Promise((r) => setTimeout(r, 1000))
// 2) Start gateway again
await sandbox.commands.run(
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`,
{ background: true }
)
// 3) Wait for listening socket
for (let i = 0; i < 45; i++) {
const probe = await sandbox.commands.run(
`bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'`
)
if (probe.stdout.trim() === 'ready') break
await new Promise((r) => setTimeout(r, 1000))
}
import os, time
TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token")
PORT = 18789
# 1) Kill existing gateway processes if present
sandbox.commands.run(
"""bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do
for pid in $(pgrep -f "$p" || true); do
kill "$pid" >/dev/null 2>&1 || true
done
done'"""
)
time.sleep(1)
# 2) Start gateway again
sandbox.commands.run(
f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}",
background=True,
)
# 3) Wait for listening socket
for _ in range(45):
probe = sandbox.commands.run(
f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\''
)
if probe.stdout.strip() == "ready":
break
time.sleep(1)
Turn insecure flags off (recommended after testing)
Use this to restore secure device authentication after initial testing.const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
await sandbox.commands.run(
`bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && ` +
`openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'`
)
await sandbox.commands.run(
`bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'`
)
await sandbox.commands.run(
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`,
{ background: true }
)
import os
TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token")
PORT = 18789
sandbox.commands.run(
"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && "
"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'"
)
sandbox.commands.run(
"""bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do
for pid in $(pgrep -f "$p" || true); do
kill "$pid" >/dev/null 2>&1 || true
done
done'"""
)
sandbox.commands.run(
f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}",
background=True,
)
Related
OpenClaw Telegram
Connect OpenClaw to Telegram and approve pairing