# OpenClaw on ORB Cloud

[OpenClaw](https://github.com/openclaw/openclaw) is a long-lived gateway daemon — exactly the shape ORB Cloud is built for. It idles 90%+ of its life waiting for inbound messages; on ORB that idle time costs $0.

There are two ways to run it: a **one-click deploy** for the common cases, or a **manual `orb.toml`** if you want full control.

## One-click deploy

Two pre-built templates, both 3 commands.

### Z.AI GLM Coding Plan

Cheapest if you already have a GLM Coding Plan key.

```bash
export ORB_API_KEY=orb_...                   # https://orbcloud.dev/dashboard/keys
export ZAI_API_KEY=<32hex>.<rest>             # https://z.ai/manage-apikey/apikey-list

bash <(curl -fsSL https://orbcloud.dev/templates/openclaw)
```

### OpenRouter (any model)

Pick any model in OpenRouter's catalog — Claude, GPT-5, Gemini, DeepSeek, Llama, etc.

```bash
export ORB_API_KEY=orb_...                   # https://orbcloud.dev/dashboard/keys
export OPENROUTER_API_KEY=sk-or-v1-...        # https://openrouter.ai/keys

bash <(curl -fsSL https://orbcloud.dev/templates/openclaw-openrouter)
```

Pin a specific model with `export OPENROUTER_MODEL=anthropic/claude-sonnet-4.5` (or any slug from <https://openrouter.ai/models>) before the `bash` line. Omit to let `openclaw onboard` pick a sensible default.

Both templates expose the gateway at `https://<computer-id>.orbcloud.dev/`, enable the OpenAI-compatible `/v1/chat/completions` endpoint, and print a gateway auth token you can use to send messages via curl.

## Manual `orb.toml`

If you're embedding openclaw in your own setup or need build steps the templates don't cover, the contract is: install OpenClaw in the sandbox, run the gateway from a wrapper script, expose the gateway port, point openclaw's provider config at ORB's per-computer LLM proxy.

`orb.toml`:

```toml
[agent]
name = "my-openclaw"
lang = "binary"
entry = "/agent/code/start.sh"

[agent.env]
ANTHROPIC_API_KEY = "${ANTHROPIC_API_KEY}"   # or OPENROUTER_API_KEY, ZAI_API_KEY, etc.
HOME = "/root"
NODE_ENV = "production"
# Move Node's V8 compile cache off /tmp — its tmpfs shadows the underlying
# bind mount, which makes CRIU's pre-dump fail on the inotify watch openclaw
# opens against this file. The /agent/cache path lives on the per-computer
# ext4 bind, no overlay, so pre-dump resolves cleanly.
NODE_COMPILE_CACHE = "/agent/cache/node"

[build]
steps = [
  "mkdir -p /agent/code",
  "cat > /agent/code/start.sh <<'SH'",
  "#!/bin/bash",
  "set -e",
  "export PATH=\"/root/.npm-global/bin:/usr/local/bin:/usr/bin:/bin\"",
  "mkdir -p \"${NODE_COMPILE_CACHE:-/agent/cache/node}\"",
  "exec openclaw gateway --port 18789 --verbose",
  "SH",
  "chmod +x /agent/code/start.sh",
  "npm install -g openclaw@latest",
]
working_dir = "/agent/code"

[ports]
expose = [18789]

[llm]
base_url = "https://api.anthropic.com"

[resources]
runtime = "2GB"
disk    = "8GB"
```

After deploy, run `openclaw onboard` once via the [web terminal](../terminal.md) at `https://api.orbcloud.dev/terminal/<computer-id>` to write the auth profile. Or do it from a build step with `--non-interactive --accept-risk` — see the [openclaw template's `start.sh`](https://github.com/AWLSEN/orb-templates/blob/main/openclaw/start.sh) for a working non-interactive example.

### Framework config

OpenClaw reads `baseUrl` from `~/.openclaw/openclaw.json`, not from env vars. Patch the provider you're using to point at the per-computer proxy at `http://127.0.0.1:8080`:

```json
{
  "models": {
    "providers": {
      "anthropic": {
        "baseUrl": "http://127.0.0.1:8080"
      }
    }
  }
}
```

You can apply this from `start.sh` after onboard runs, or write it directly into `~/.openclaw/openclaw.json` from a build step:

```bash
mkdir -p /root/.openclaw
python3 -c '
import json, os
p = "/root/.openclaw/openclaw.json"
d = json.load(open(p)) if os.path.exists(p) else {}
d.setdefault("models", {}).setdefault("providers", {}).setdefault("anthropic", {})["baseUrl"] = "http://127.0.0.1:8080"
json.dump(d, open(p, "w"), indent=2)
'
```

The provider key (`anthropic`, `openrouter`, `zai`, `openai`, …) must match whichever provider you onboarded against — that's the entry in `models.providers` whose `baseUrl` openclaw reads when it routes a request.

### Common upstreams

```toml
# Anthropic
[llm]
base_url = "https://api.anthropic.com"

# OpenRouter
[llm]
base_url = "https://openrouter.ai/api/v1"

# Z.AI GLM Coding Plan
[llm]
base_url = "https://api.z.ai/api/anthropic"
```

ORB's proxy forwards request paths verbatim to `[llm] base_url`, so the upstream URL must include any path prefix the provider expects (e.g. `/api/v1` for OpenRouter, `/api/anthropic` for Z.AI).
