> For the complete documentation index, see [llms.txt](https://docs.avis.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.avis.xyz/integrations/assistant/openclaw.md).

# OpenClaw

This document explains how to integrate [OpenClaw](https://openclaw.ai) with the AVIS API.

### What is OpenClaw

OpenClaw is an open-source local AI assistant that interacts with you through WhatsApp, Telegram, and Slack, and can perform actions like email and calendar management while keeping data local. It routes model calls through a `gateway` process, configured via `~/.openclaw/openclaw.json`, and dispatches to one or more `agents` backed by whichever model providers you register.

### 1) Install OpenClaw

```bash
# macOS / Linux
curl -sSL https://openclaw.ai/install.sh | bash

# Windows PowerShell
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1)))
```

### 2) Get an AVIS API key

See Authentication — sign in at [avis.xyz](https://avis.xyz), go to **Settings → API Keys**, and create one.

### 3) Quick start via onboarding

```bash
openclaw onboard
```

The wizard walks through auth, models, Gateway, workspace, channels, and skills. When it asks for an **auth/provider choice**, pick the custom API key option (`custom-api-key`) rather than one of the named providers (OpenAI, Anthropic, etc. are for *their* hosted APIs, not a compatible proxy like AVIS). It will then prompt for:

| Prompt                 | Value                                              |
| ---------------------- | -------------------------------------------------- |
| Base URL               | `https://api.avis.xyz/api/anthropic`               |
| API Key                | your AVIS API key                                  |
| Compatibility          | `anthropic`                                        |
| Model ID               | `anthropic/claude-sonnet-4.6`                      |
| Provider ID (optional) | `avisai-anthropic` (or leave blank to auto-derive) |

This writes the equivalent `avisai-anthropic` provider block into `~/.openclaw/openclaw.json` — see §4 for the resulting shape, or to edit it by hand instead.

#### Non-interactive (scriptable)

The same setup, no prompts, using the wizard's underlying flags:

```bash
openclaw onboard \
  --non-interactive --accept-risk \
  --auth-choice custom-api-key \
  --custom-provider-id avisai-anthropic \
  --custom-base-url https://api.avis.xyz/api/anthropic \
  --custom-api-key <your-avis-api-key> \
  --custom-compatibility anthropic \
  --custom-model-id anthropic/claude-sonnet-4.6
```

`--custom-compatibility` (onboarding flag only) — use `anthropic` here. When hand-editing `openclaw.json` directly, the `api` field uses a different literal value for the same thing (see §4/§6: `anthropic-messages`, not `anthropic`) — don't assume the wizard's flag values match the config file's `api` values 1:1.

`--accept-risk` is required by `--non-interactive` (it's OpenClaw's standard acknowledgment that agents get full system access, unrelated to AVIS itself).

Once onboarding finishes, start the gateway if it wasn't installed as a service already:

```bash
openclaw daemon start
```

### 4) Manual configuration (`~/.openclaw/openclaw.json`)

#### Provider block

Register each AVIS surface you want under `models.providers`. Real working example — one Anthropic-surface provider and one OpenAI-surface provider side by side:

```json
{
  "models": {
    "providers": {
      "avisai-anthropic": {
        "baseUrl": "https://api.avis.xyz/api/anthropic",
        "apiKey": "<your-avis-api-key>",
        "api": "anthropic-messages",
        "models": [
          {
            "id": "anthropic/claude-sonnet-4.6",
            "name": "Claude Sonnet 4.6",
            "input": ["text", "image"],
            "contextWindow": 200000,
            "maxTokens": 64000
          },
          {
            "id": "anthropic/claude-opus-4.8",
            "name": "Claude Opus 4.8",
            "reasoning": true,
            "input": ["text", "image"],
            "contextWindow": 200000,
            "maxTokens": 128000
          },
          {
            "id": "anthropic/claude-haiku-4.5",
            "name": "Claude Haiku 4.5",
            "input": ["text", "image"],
            "contextWindow": 200000,
            "maxTokens": 64000
          }
        ]
      },
      "avisai-openai": {
        "baseUrl": "https://api.avis.xyz/api/openai/v1",
        "apiKey": "<your-avis-api-key>",
        "api": "openai-completions",
        "models": [
          {
            "id": "gpt-4o-mini",
            "name": "GPT-4o mini",
            "input": ["text", "image"],
            "contextWindow": 128000,
            "maxTokens": 16384
          },
          {
            "id": "gpt-5-5",
            "name": "GPT-5.5 Codex",
            "reasoning": true,
            "input": ["text", "image"],
            "contextWindow": 200000,
            "maxTokens": 64000
          }
        ]
      }
    }
  }
}
```

Notes:

* `apiKey` supports `${ENV_VAR}` syntax if you'd rather keep the key out of the file, e.g. `"apiKey": "${AVIS_API_KEY}"`.
* `input` lists accepted modalities (`text`, `image`, `file`, `audio`) — only set what the chosen model actually supports.
* `contextWindow`/`maxTokens` are advertised to OpenClaw for display/UX only — **not enforced**, and not validated against AVIS.

> ⚠️ **`models[].id` here is metadata, not routing.** Writing an `id` in this array does *not* make it valid — it only shows up in menus/aliases. The actual value that gets sent to AVIS is the `<model-id>` half of whatever key you reference in `agents.defaults.models` (§4 below) or `model.primary`. That string must exactly match what AVIS expects for the surface's `api` type — see §6 for which `api` values actually work against AVIS.

#### Agents block

Reference provider models as `<provider-name>/<model-id>`. `defaults` applies to every agent unless overridden per-entry in `list`:

```json
{
  "agents": {
    "defaults": {
      "model": {
        "primary": "avisai-anthropic/anthropic/claude-sonnet-4.6",
        "fallbacks": ["avisai-anthropic/anthropic/claude-haiku-4.5"]
      },
      "models": {
        "avisai-anthropic/anthropic/claude-opus-4.8": { "alias": "opus" },
        "avisai-anthropic/anthropic/claude-sonnet-4.6": { "alias": "sonnet" },
        "avisai-anthropic/anthropic/claude-haiku-4.5": { "alias": "haiku" },
        "avisai-openai/gpt-4o-mini": { "alias": "gpt4o-mini" },
        "avisai-openai/gpt-5-5": { "alias": "codex" }
      },
      "thinkingDefault": "low",
      "timeoutSeconds": 600,
      "maxConcurrent": 3
    },
    "list": [
      { "id": "main", "default": true },
      { "id": "research", "model": { "primary": "avisai-anthropic/anthropic/claude-opus-4.8" } },
      { "id": "quick", "model": { "primary": "avisai-anthropic/anthropic/claude-haiku-4.5" } }
    ]
  }
}
```

* `fallbacks` are tried in order if `primary` errors.
* `alias` entries let you switch models mid-conversation with `/model opus`, `/model codex`, etc.
* Per-agent `model.primary` overrides the default for that agent only (e.g. `research` always uses Opus).
* **`agents.defaults.models` is also the allowlist for `/model`.** A `<provider>/<model-id>` not listed here — even with a perfectly valid provider block — gets rejected with `model not allowed: ...` when you try to switch to it. See §7.

### 5) Run OpenClaw

Start the gateway as a background service:

```bash
openclaw daemon start   # background service (launchd/systemd/schtasks)
```

Open a chat against it:

```bash
openclaw chat            # local terminal UI (alias for `openclaw tui --local`)
```

Check the gateway is up and see which config it actually loaded:

```bash
openclaw daemon status
```

Validate the config file's shape (catches typos and invalid `api` enum values *before* you restart and get a cryptic runtime error):

```bash
openclaw config validate
```

Inside a chat session, switch models using the aliases defined in §4's `agents.defaults.models`:

```
/model opus
/model codex
/model gpt4o-mini
```

**Config changes require a restart.** The gateway reads `openclaw.json` once at startup — editing the file while the service is already running (e.g. fixing a `baseUrl`, adding a provider, or adding a model to the allowlist) has no effect until you restart it:

```bash
openclaw daemon restart
```

Skipping this is a common cause of confusing `fetch failed (timeout)` errors that persist even after the config on disk looks correct.

### 6) AVIS surfaces supported

| `api`                | Base URL                                | AVIS endpoint it targets                    |
| -------------------- | --------------------------------------- | ------------------------------------------- |
| `anthropic-messages` | `https://api.avis.xyz/api/anthropic/v1` | `POST /messages`                            |
| `openai-completions` | `https://api.avis.xyz/api/openai/v1`    | `POST /chat/completions`                    |
| `openai-responses`   | `https://api.avis.xyz/api/openai/v1`    | `POST /responses` (Codex CLI/Desktop style) |

Use `openai-completions` for normal chat with any non-Anthropic model, including Gemini — AVIS's OpenAI-compatible catalog includes Gemini models under their own canonical id (e.g. `gemini-2-5-flash`, `gemini-2-5-pro`; check `GET /api/openai/v1/models` for the exact list). There's no need for a separate Gemini-specific provider block. Use `openai-responses` instead only if the client/agent specifically speaks the Responses API shape.

The same `apiKey` works across all three — it's tied to your AVIS account, not the surface.

### 7) Troubleshooting

* `401 Unauthorized`
  * AVIS key is invalid, revoked, or missing.
  * Re-check `apiKey` in `openclaw.json` and Authentication.
* `auth or provider access failed for <provider>. Run /auth <provider> to refresh credentials...`
  * OpenClaw's generic wrapper around an upstream auth failure — same root cause as `401 Unauthorized` above, not a new one. Verify the key directly with `curl` against the AVIS endpoint before assuming OpenClaw-side config is at fault.
* `model not allowed: <provider>/<model-id>`
  * The model isn't in `agents.defaults.models` (§4) — that map is an allowlist, not just aliases. Add an entry for it (with or without an `alias`), then `openclaw daemon restart`.
* `404` or model not found
  * The `id` in a provider's `models[]` doesn't match a real AVIS model id.
  * Check `GET /api/anthropic/v1/models` / `GET /api/openai/v1/models` for valid ids.
* Wrong `baseUrl` for the protocol
  * Each `api` type must be paired with its matching AVIS base URL (see table in §6) — mismatching them (e.g. `anthropic-messages` pointed at the OpenAI base URL) fails at the transport level.
* Agent references a model that doesn't resolve
  * Agent `model.primary`/`fallbacks`/`models` keys must be `<provider-name>/<model-id>`, matching the provider name under `models.providers` exactly.
* `403` with a valid key
  * Account balance is depleted — see Errors.
* Invalid `api` value rejected at `openclaw daemon restart` / `openclaw config validate`
  * The onboarding wizard's `--custom-compatibility` flag values aren't the same as the config file's `api` values. Use `anthropic-messages` / `openai-completions` (§6) when hand-editing.
* `fetch failed (timeout)` on every model, even though `curl`-ing the AVIS `baseUrl` directly works
  * The gateway is running as a background service and hasn't reloaded `openclaw.json` since your last edit (see §5). Run `openclaw daemon restart`.
  * Check `openclaw daemon status` — compare "Runtime: running (pid ...)" against `ps -o lstart -p <pid>` vs. the config file's mtime; if the process predates the edit, restart it.
* `baseUrl` uses `[::1]` (IPv6 loopback) against a local AVIS instance, or the bind flips between restarts
  * If AVIS's `HOST` env var is `localhost` (rather than `0.0.0.0`), the local server's bind address depends on how the OS resolves `localhost` — which can flip between IPv4 and IPv6 across restarts. Set `HOST=0.0.0.0` in AVIS's `.env` for a deterministic IPv4 bind, and use `127.0.0.1` (not `localhost` or `[::1]`) in `openclaw.json`'s `baseUrl`.

### 8) Minimal End-to-End Checklist

1. AVIS API key created (§2).
2. `~/.openclaw/openclaw.json` has an `avisai-*` provider block with a valid `baseUrl`/`apiKey`/`api` combination — `openclaw config validate` passes.
3. The model you want to use is listed in `agents.defaults.models` (allowlist) as `<provider-name>/<model-id>`, with that `<model-id>` confirmed against AVIS's actual `/models` catalog for that surface.
4. `agents.defaults.model.primary` (or a per-agent override) points at a valid entry from that block.
5. Gateway restarted after any config edit (`openclaw daemon restart`, if running as a service).
6. `openclaw chat` opens, and a message through OpenClaw returns model output.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.avis.xyz/integrations/assistant/openclaw.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
