# InferSpeed for agents

You are an agent (or a harness) that needs a model backend. InferSpeed is a pay-per-token model
API with OpenAI- and Anthropic-compatible HTTP endpoints, billed from a prepaid balance. Models on sale and live prices:
https://inferspeed.ai/model-plaza (JSON: https://inferspeed.ai/api/v1/public/pricing). This file
tells you how to configure yourself.

## What you need from your human

One InferSpeed API key. They create it at https://inferspeed.ai/keys (sign-in required) and put it
in the environment as `INFERSPEED_API_KEY`. Never write the key into files that are committed or
shared.

## Settings

- OpenAI-compatible base URL: `https://api.inferspeed.ai/v1` (clients append `/chat/completions`
  or `/responses`)
- Anthropic-compatible base URL: `https://api.inferspeed.ai` (clients append `/v1/messages`; do not
  add `/v1` or any other path to it)
- Use only the two base URLs above; there is no other API version or host (no `/v2`, no `/v3`).
- API key environment variable: `INFERSPEED_API_KEY`
- Auth header: `Authorization: Bearer $INFERSPEED_API_KEY` (`x-api-key` also works)
- Model IDs: every public model is listed, with prices, at
  `GET https://inferspeed.ai/api/v1/public/pricing` (no key needed; use `data.models[].id`). The
  examples here use `glm-5.3`; put any listed ID in its place.
- One key, every model: an API key (create one at https://inferspeed.ai/keys) calls every live
  model, such as `glm-5.3`, `kimi-k3` and `MiniMax-M3`. Name the model in the request; each request is
  billed at that model's price. `glm-5.3-flash` is served on `POST /v1/chat/completions` only.
- List the models the key can call: `GET https://api.inferspeed.ai/v1/models`
- `glm-5.3` limits: `max_tokens` up to 131072 (reasoning tokens count toward it). Context window:
  at least 324,955 prompt tokens accepted.
- Reasoning models (such as `glm-5.3` and `kimi-k3`) think before answering and the reasoning
  counts as output tokens. Do not set `max_tokens` very low or the answer can come back empty.

## Pick your wire format

- You speak OpenAI Responses (Codex CLI): `POST /v1/responses`
- You speak OpenAI Chat Completions (most others): `POST /v1/chat/completions`
- You speak Anthropic Messages (Claude Code, Anthropic SDK): `POST /v1/messages`
- You speak legacy OpenAI Completions: `POST /v1/completions`
- You speak Google Gemini native (`google-genai` SDK, Gemini CLI): `POST /v1beta/models/{model}:generateContent` or `:streamGenerateContent` (also `:countTokens`); send the key as `x-goog-api-key`, `Authorization: Bearer` or `?key=`

Exact config blocks for Codex CLI, Claude Code, OpenCode, CC Switch and OpenAI-compatible tools,
plus SDK examples: https://inferspeed.ai/developers.md. Verified against production on 2026-10-14
with Claude Code 2.1.296 and Codex CLI 0.162.1 (tool use, multi-turn, long streams).

Installer (ask your human first; it reads the key from `INFERSPEED_API_KEY`, prints the one file it
will change with a diff, backs it up, then tests the connection):
`curl -fsSL https://inferspeed.ai/setup.sh | sh -s -- <claude|codex|opencode|openclaw> [--model <id>] [--dry-run]`
Without `--model` it uses the first model your key can call (`GET /v1/models`).

One-click scripts, one per tool (same rules: key only from `INFERSPEED_API_KEY`, never written to
disk unless `--persist`, backup before any change, idempotent, no network calls, prints a verify
`curl`): `https://inferspeed.ai/install/codex.sh`, `claude-code.sh`, `opencode.sh`, `openclaw.sh`,
and `codex.ps1`, `claude-code.ps1` for Windows. Usage: `curl -fsSL https://inferspeed.ai/install/codex.sh | sh -s -- [--model <id>] [--dry-run]`.

Skill file with the same facts plus balance checks and key-handling rules: https://inferspeed.ai/skill.md

## OpenClaw

Last verified: 2026-10-16 against OpenClaw's custom-provider and environment-variable docs
(https://docs.openclaw.ai/gateway/config-tools/custom-providers).

OpenClaw speaks OpenAI Chat Completions. Merge this into `~/.openclaw/openclaw.json` (JSON5; or the
file `OPENCLAW_CONFIG_PATH` points at), then run `openclaw doctor`. OpenClaw fills
`${INFERSPEED_API_KEY}` from the environment, so the key stays out of the file.

```
{
  models: {
    mode: "merge",
    providers: {
      inferspeed: {
        baseUrl: "https://api.inferspeed.ai/v1",
        apiKey: "${INFERSPEED_API_KEY}",
        api: "openai-completions",
        models: [{ id: "glm-5.3", name: "glm-5.3" }],
      },
    },
  },
  agents: { defaults: { model: { primary: "inferspeed/glm-5.3" } } },
}
```

Or ask your human to run `curl -fsSL https://inferspeed.ai/install/openclaw.sh | sh` (it merges a
plain-JSON file, backs it up first, and leaves a JSON5 file untouched).

## Prices and balance

- Prices, USD per 1M tokens, no key needed: `GET https://inferspeed.ai/api/v1/public/pricing`
- Balance and usage for your key: `GET https://api.inferspeed.ai/v1/usage` (`remaining`, `unit`,
  `usage.today.actual_cost`; details in https://inferspeed.ai/skill.md)
- Low balance: call `POST https://inferspeed.ai/api/v1/billing/topup` with your key and
  `{"amount_usd": 10}`, and give the returned `data.payment_url` (or `data.qr_code_png`) to your
  user. Poll `data.status_url` until `status` is `completed`, then continue. Your human pays on a
  Stripe page; you never handle card details. Full contract: https://inferspeed.ai/skill.md

## Check that it works

```
curl https://api.inferspeed.ai/v1/chat/completions \
  -H "Authorization: Bearer $INFERSPEED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "glm-5.3", "messages": [{"role": "user", "content": "Reply with OK."}]}'
```

## When a request fails

Branch on the status code and the error code (`code`, or `error.code` / `error.type`), not on
the message text (message wording is not stable and may not be in English).

- 400: the request is invalid or the model name is unknown. Fix it; the same body fails again.
- 401: the key is missing, wrong or disabled. Stop and ask your human.
- 403 `INSUFFICIENT_BALANCE`: the balance is used up. Retrying will not help. Create a top-up
  (`POST https://inferspeed.ai/api/v1/billing/topup`) and give the payment URL to your human, or
  send them to https://inferspeed.ai/purchase. Other 403s (expired key, IP not allowed): stop and
  ask.
- 403 `API_KEY_QUOTA_EXHAUSTED` (`error.code` `insufficient_quota`): the spend cap on this key
  is reached. Stop and ask your human to raise it. Retrying will not help.
- 403 `permission_denied` with `error.type` `billing_error`: the balance ran out while the
  request waited. Same as `INSUFFICIENT_BALANCE`, but the body has no `topup_url`.
- 429 `USAGE_LIMIT_EXCEEDED`, or any 429 with an `x-should-retry: false` header: a spend cap on
  this key (5-hour, daily or 7-day) or an allowance is used up until its window resets
  (`Retry-After`, when set, is the seconds until then). Retrying soon will not help; stop and ask
  your human.
- Any other 429: rate limited or at capacity. Wait `Retry-After` seconds, then retry with backoff.
- 524, or a non-streaming request cut off after about 100 seconds: the response took too long to
  arrive in one piece. Retry once with `"stream": true` (or a lower `max_tokens`); the same
  non-streaming request will hit the same limit. Use `"stream": true` for long outputs.
- 503 and other 5xx: temporary. Retry with backoff; https://inferspeed.ai/status shows live checks.

