Skip to main content
OpenClaw reaches any OpenAI-compatible endpoint through a custom provider. Onboarding writes the entry for you, and the config file holds it afterwards. OpenClaw has no per-request deadline field of its own, so the deadline goes on the key. Create one first (see agent keys).

Set this up with an agent

Open the block below and copy it into any coding agent. The prompt never asks for your API key: the agent configures everything else, then prints the one export line for you to run yourself.

Onboard a custom provider

  1. Start the guided setup.
  2. Pick the custom provider option when it asks about auth. That is custom-api-key.
  3. Enter the router as the base URL, including the /v1 suffix.
  4. Paste your agent key.
  5. Leave the compatibility mode on openai. That is our Chat Completions surface.
  6. Enter a model id we run, such as gpt-5.6-sol.
The prompt never puts your key on a command line, which is why it’s the path shown here. openclaw onboard --non-interactive exists too, but its custom-api-key auth mode reads the credential from --custom-api-key, so the secret ends up in your shell history and in process arguments. Script the setup with config commands and a secret reference instead, which is the same result without the exposure. Whichever route you take, set the provider id yourself:
Left to itself, OpenClaw derives the id from the host and ends up with custom-api-flexinference-com, and every later command on this page would need that name instead. The write includes a model row because it has to. OpenClaw refuses a third-party provider that declares no models, so a baseUrl-only write fails schema validation. Replace the whole row in the next section. The compatibility mode maps to api. openai writes openai-completions, which is the one our Chat Completions endpoint works with. The other choices are openai-responses and anthropic.

The config file

Onboarding writes into ~/.openclaw/openclaw.json under models.providers. Print the path OpenClaw is using with openclaw config file.
"mode": "merge" keeps your built-in providers and adds this one beside them. api must be openai-completions. The onboarding openai compatibility mode writes exactly that. apiKey takes a plain string too, which is what onboarding writes. The reference shown here keeps the secret out of the file. See keep the key out of the config file. List your models yourself. Only OpenClaw’s built-in provider ids may leave models out. A third-party id must declare both baseUrl and models, so add a row per model you want in the picker. Set compat.supportsUsageInStreaming. OpenClaw makes streaming usage opt-in for a third-party endpoint, because some servers refuse it. Without this flag we never get the request for a usage frame, so every streamed turn reports zero tokens and no cost.

Fill the model list from our catalog

OpenClaw won’t call GET /v1/models for a provider you define in config. Model discovery is a plugin capability, and the bundled plugins that have it are the only ones that use it. A config-defined provider reads its models array and nothing else. Generate that array from our catalog instead, and write it in one command.
config patch merges objects and replaces arrays, so this swaps the model list and leaves baseUrl and apiKey untouched. Add --dry-run to see the write first. Keep only the models that race the cheaper tier by filtering on the catalog’s own flag.
Our catalog publishes no context window and no token ceiling, so rows made this way have neither. Add contextWindow and maxTokens yourself where OpenClaw’s defaults don’t fit the model. Re-run the command whenever our catalog changes. Check the result:

Global config and profiles

OpenClaw keeps one config per profile, not one per folder. The working directory never changes which file it reads. Use a named profile to try FlexInference without touching your usual setup.
A profile isolates state as well as config, so its gateway port and workspace are separate too.

Keep the key out of the config file

Onboarding writes the key into openclaw.json in plain text. Set apiKey to a secret reference instead, and the config stores the variable’s name rather than its value.
  1. Export the key in the shell you will run these commands from.
  2. Declare an environment secrets provider and allow that one variable.
  3. Point the provider’s apiKey at it.
The config then holds {"source": "env", "provider": "default", "id": "FLEXINFERENCE_API_KEY"} and no secret. The key never reaches a command line either, because step 3 passes only the variable’s name. OpenClaw resolves the reference when you run step 3, so export the variable first. A missing or empty variable fails the write with SecretRefResolutionError rather than storing something broken. Add --dry-run to check without writing. Check what’s exposed with the built-in audit.

Confirm the key applied

Every response comes with x-flexinference-defaults-applied. OpenClaw doesn’t show response headers, so read the request in the dashboard under Logs instead.

Troubleshooting

The model picker is short, or a model is missing. A config-defined provider never calls GET /v1/models, so it shows only the rows you wrote. Regenerate the list from our catalog. Turns report zero tokens and no cost. OpenClaw didn’t ask us for streaming usage, so we sent no usage frame. Set compat.supportsUsageInStreaming to true on each model row. A model id is refused. Rows you wrote by hand can drift from what we run, since the id goes out exactly as written. Regenerate the list from our catalog rather than editing ids. Config edits don’t take effect. The gateway holds the old config. Restart it, and confirm you edited the file that openclaw config file prints. See errors for every refusal we return, and agent keys for the ones that are not specific to OpenClaw.