# Custom models

> Select models via -m and /model; configure BYOK and OpenAI-compatible or Ollama endpoints; per-model overrides; grok models listing and provider-neutral endpoint settings.

- Repository: xai-org/grok-build
- GitHub: https://github.com/xai-org/grok-build
- Human docs: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458
- Complete Markdown: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458/llms-full.txt

## Source Files

- `crates/codegen/xai-grok-pager/docs/user-guide/11-custom-models.md`
- `crates/codegen/xai-grok-models/src/lib.rs`
- `crates/codegen/xai-grok-models/src/catalog.rs`
- `crates/codegen/xai-grok-shell/src/cli_models.rs`
- `crates/codegen/xai-grok-shell/src/sampling/mod.rs`
- `crates/codegen/xai-grok-pager/src/models.rs`

---

---
title: "Custom models"
description: "Select models via -m and /model; configure BYOK and OpenAI-compatible or Ollama endpoints; per-model overrides; grok models listing and provider-neutral endpoint settings."
---

Grok Build resolves a **model catalog** from built-in defaults, optional remote `/v1/models` prefetch, and user `[model.*]` tables in `~/.grok/config.toml`, then routes inference through `api_backend` (`chat_completions`, `responses`, or `messages`) and per-model credentials (BYOK `api_key` / `env_key`, session token, or `XAI_API_KEY`). Selection is CLI (`-m` / `--model`), TUI (`/model`, `/m`, model picker), or persistent `[models].default`.

## Default catalog

Without custom config, new sessions use the baked-in default from `default_models.json` (currently `grok-build`). Aux roles also have baked-in pins (for example web search and image description) that fall back to the primary default when unset.

```bash
grok models
```

`grok models` prints auth banner status (API key, OAuth host, per-model BYOK, deployment key, or unauthenticated), the resolved default, and the available model list (current marked with `*`).

## Selecting a model

### CLI

```bash
grok -m grok-build
grok -p "Hello" --model my-model
grok -m my-model --reasoning-effort high
```

`-m` / `--model` sets the session model. `--reasoning-effort` / `effort` sets reasoning effort when the selected model supports it.

### Slash command

In the TUI:

```
/model grok-build
/m grok-build
/model reasoning-model high
```

`/model` (alias `/m`) switches the active model. Optional trailing effort tokens are accepted for models that expose a reasoning-effort menu. Exact catalog name/id match is preferred so multi-word display names resolve correctly.

### Model picker

From the scrollback pane, open the model picker (documented as `Ctrl+M` in the user guide). With the prompt focused, that binding toggles multiline input instead—use `/model` from the prompt.

### Persistent default

```toml
[models]
default = "grok-build"
```

Resolution order for the active model is typically CLI/session selection over config default over built-in default. Use `grok inspect` (see [Configure Grok](/configure-grok)) to dump the effective config when debugging precedence.

## API backends

Set `api_backend` on a `[model.*]` entry. Omitted value defaults to OpenAI Chat Completions.

| Config value | Protocol | Path shape |
|--------------|----------|------------|
| `chat_completions` (default) | OpenAI Chat Completions | `/v1/chat/completions` |
| `responses` | OpenAI Responses | `/v1/responses` |
| `messages` | Anthropic Messages | `/v1/messages` |

Provider-specific auth headers (for example Anthropic `x-api-key` and `anthropic-version`) go in `extra_headers`; they are sent verbatim on inference requests.

## Per-model configuration

Declare custom or override entries under `[model.<catalog-key>]` in `~/.grok/config.toml`:

```toml
[model.my-model]
model = "model-id"                        # routing slug sent to the API
base_url = "https://api.example.com/v1"   # OpenAI-compatible or other endpoint
name = "Display Name"                     # picker / UI label
description = "Optional description"
api_key = "sk-..."                        # inline BYOK (optional)
env_key = "PROVIDER_API_KEY"              # string or array of env names
api_backend = "chat_completions"          # chat_completions | responses | messages
temperature = 0.7
top_p = 0.95
max_completion_tokens = 8192
context_window = 128000                   # tokens; drives auto-compaction
extra_headers = { "x-api-key" = "sk-..." }
stream_tool_calls = false                 # opt out if endpoint rejects the field
```

### Field notes

| Field | Role |
|-------|------|
| `model` | Wire-level model id (may differ from the TOML table key). |
| `base_url` | Inference base URL for this catalog entry. |
| `api_base_url` | Optional alternate base when using global API-key auth (session still uses `base_url`). |
| `api_key` / `env_key` | BYOK credentials; `env_key` may be one name or an ordered list (first non-empty wins). |
| `context_window` | Token budget for compaction. New models without this field default to **200,000**. Overrides of known models inherit the donor window when possible. |
| `hidden` / `supported_in_api` | Picker visibility. `hidden` hides for all auth; `supported_in_api = false` hides for API-key users but still shows for OAuth. |
| `supports_backend_search` | Enables server-side web search for that model when the build supports it (independent of `api_backend`). |
| `reasoning_effort` / `reasoning_efforts` | Default and menu for reasoning models. |

### Credential resolution (sampling)

For a request, credentials resolve in this order:

1. Model BYOK: non-empty `api_key`, else first set non-empty `env_key`
2. Signed-in session token (`grok login`)
3. Global `XAI_API_KEY` (also accepts legacy `GROK_CODE_XAI_API_KEY`)

When only a global API key applies, `api_base_url` is preferred over `base_url` if set.

**Note:** The `grok models` banner uses a different display order (env key → session → BYOK → deployment → none) so logged-in users see the auth host even when BYOK is also configured.

### Catalog merge priority

Final map assembly (highest wins):

1. User `[model.*]` overrides and additions
2. Prefetched remote models from the models list endpoint
3. Hardcoded defaults from `default_models.json` (skipped when a custom models endpoint is active)

When `models_base_url` or `models_list_url` is set, built-in xAI defaults are **not** loaded; the catalog comes from the remote list plus your `[model.*]` tables.

### Global `[models]` defaults

Apply the same scalar defaults or headers to every catalog entry:

```toml
[models]
default = "my-model"
temperature = 0.7
top_p = 0.95
max_completion_tokens = 8192
max_retries = 8
inference_idle_timeout_secs = 600
stream_tool_calls = true
extra_headers = { "X-Request-Tags" = "team=example,env=prod" }
web_search = "grok-4.20-multi-agent"
image_description = "grok-build"
session_summary = "grok-build"
allowed_models = ["grok-*", "my-model"]
hidden_models = ["internal-slug"]
disabled_models = ["retired-slug"]
```

- Per-model values always win over global defaults.
- Global `extra_headers` merge as a base; per-model keys override case-insensitively.
- `allowed_models` globs restrict what appears in the picker and what `-m` / `/model` may select for normal chat (internal/aux roles are exempt). `disabled_models` removes entries from the catalog entirely and wins over `hidden_models`.
- Identity fields (`model`, `base_url`, `api_key`, `context_window`, …) cannot be set as globals—only per model.
- `[models].agent_type` is deprecated; set `agent_type` on each `[model.X]` instead.

## Overriding built-in models

Specify only the fields to change:

```toml
[model.grok-build]
temperature = 0.5
api_key = "sk-custom"
```

Unspecified fields inherit from the default/prefetched entry (including the correct `base_url` for first-party models).

## Provider-neutral endpoint examples

Grok is **BYOK / BYOC friendly**: any OpenAI-compatible Chat Completions or Responses server, Anthropic Messages API, or local runtime can be a catalog entry. No proprietary connector is required beyond `base_url`, credentials, and `api_backend`.

### Anthropic Messages

```toml
[model.claude-opus]
model = "claude-opus-4-6"
base_url = "https://api.anthropic.com/v1"
name = "Claude Opus 4.6"
api_backend = "messages"
context_window = 200000
extra_headers = { "x-api-key" = "sk-ant-...", "anthropic-version" = "2023-06-01" }
```

### OpenAI Chat Completions

```toml
[model.gpt-4o]
model = "gpt-4o"
base_url = "https://api.openai.com/v1"
name = "GPT-4o"
env_key = "OPENAI_API_KEY"
```

### OpenAI Responses

```toml
[model.gpt-4o-responses]
model = "gpt-4o"
base_url = "https://api.openai.com/v1"
api_backend = "responses"
env_key = "OPENAI_API_KEY"
```

### Ollama (local)

```toml
[model.ollama-codellama]
model = "codellama"
base_url = "http://localhost:11434/v1"
name = "CodeLlama (Ollama)"
context_window = 16384
```

Run `ollama serve` and `ollama pull codellama` first. Many local servers need no API key.

### Any OpenAI-compatible gateway

```toml
[model.local-llama]
model = "llama-3.1-70b"
base_url = "http://localhost:8080/v1"
name = "Local Llama"
temperature = 0.8
context_window = 128000
```

### Together AI (and similar hosts)

```toml
[model.together-mixtral]
model = "mistralai/Mixtral-8x7B-Instruct-v0.1"
base_url = "https://api.together.xyz/v1"
name = "Mixtral 8x7B"
env_key = "TOGETHER_API_KEY"
```

## Custom models list endpoint

Point the whole client at a corporate gateway or self-hosted catalog instead of the public default.

### Environment

| Variable | Required | Description |
|----------|----------|-------------|
| `GROK_MODELS_BASE_URL` | Yes* | Inference base; list defaults to `{base}/models`. |
| `GROK_MODELS_LIST_URL` | No | Override list URL when it is not `{base}/models`. |
| `XAI_API_KEY` | Typical | Bearer key for list + inference when not using session auth. |

\*Either env or `[endpoints]` config.

### Config

```toml
[endpoints]
models_base_url = "https://api.acme.com/v1"
# models_list_url = "https://api.acme.com/v1/custom/models"  # optional

[model.company-grok]
model = "grok-build"
name = "Grok via proxy"
context_window = 128000
```

With a custom endpoint active:

- Built-in defaults are skipped; models come from the remote list + your overrides.
- Partial `[model.*]` entries inherit `base_url` from endpoint resolution when not specified.
- API-key auth is sufficient; `grok login` is not required for that path.

List URL resolution: `models_list_url` → `{models_base_url}/models` → `{proxy}/models`.

## Auxiliary model pins

Separate catalog keys for non-chat roles:

```toml
[models]
web_search = "my-search-model"
image_description = "my-vision-model"
session_summary = "my-summary-model"
prompt_suggestion = "my-suggest-model"
```

Environment counterparts exist for several pins (for example `GROK_WEB_SEARCH_MODEL`). If the pin is a custom id, define a matching `[model.*]` entry so credentials and `base_url` resolve.

Backend web search additionally needs:

```toml
[model.my-search-model]
model = "my-search-model"
supports_backend_search = true
```

## Everyday usage

```bash
# List catalog + auth banner
grok models

# Headless with explicit model
grok -p "Refactor this module" -m my-model

# Interactive switch
# /model my-model

# Persist default
# [models] default = "my-model"
```

## Enterprise sketch

```toml
[cli]
auto_update = false

[models]
default = "company-grok"

[model.company-grok]
model = "grok-build"
base_url = "https://grok-proxy.acme.com/"
name = "Grok Build (Proxy)"
context_window = 128000

[endpoints]
models_base_url = "https://grok-proxy.acme.com/v1"
deployment_key = "..."  # management / telemetry attribution

[features]
telemetry = false
```

## Troubleshooting

| Symptom | Checks |
|---------|--------|
| Model not found | `grok models`; typos in `[model.*]` keys vs `-m` id; `allowed_models` / `disabled_models` filters. |
| Connection / 401 | Curl `{base_url}/models` with the same Bearer or headers; confirm `api_key` / `env_key` / `extra_headers`. |
| Wrong protocol | Set `api_backend` to match the host (`messages` for Anthropic, `responses` where required). |
| Unexpected compaction | Set `context_window` explicitly on new custom models (default 200k if omitted). |
| `stream_tool_calls` errors | Disable globally or per model for providers that reject the field. |
| Custom endpoint empty catalog | Verify `GROK_MODELS_BASE_URL` / `models_list_url` and that remote fetch is not disabled by managed policy. |

Debug tracing:

```bash
RUST_LOG=debug GROK_LOG_FILE=/tmp/grok.log grok
# look for model_key, base_url, sampling, resolve_model_list
```

## Related pages

<CardGroup cols={2}>
  <Card title="Configure Grok" href="/configure-grok">
    config.toml precedence, feature flags, and `grok inspect`.
  </Card>
  <Card title="Authentication" href="/authentication">
    OAuth, device code, and `XAI_API_KEY` for CI.
  </Card>
  <Card title="Configuration reference" href="/configuration-reference">
    Schema-oriented `[models]`, `[model.*]`, and `[endpoints]` keys.
  </Card>
  <Card title="CLI reference" href="/cli-reference">
    Top-level flags including `-m` and `grok models`.
  </Card>
  <Card title="Slash commands" href="/slash-commands">
    `/model` and other interactive commands.
  </Card>
  <Card title="Headless mode" href="/headless-mode">
    Non-interactive runs with explicit model and output formats.
  </Card>
</CardGroup>

## Next

<CardGroup cols={2}>
  <Card title="MCP servers" href="/mcp-servers">
    Register stdio/HTTP MCP servers alongside custom inference endpoints.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Terminal, auth recovery, and diagnostics probes.
  </Card>
</CardGroup>

<code-citation><citation-definition file="crates/codegen/xai-grok-pager/docs/user-guide/11-custom-models.md" start="1" end="382" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-models/src/lib.rs" start="1" end="70" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-models/default_models.json" start="1" end="18" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/cli_models.rs" start="1" end="90" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-pager/src/models.rs" start="1" end="40" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="140" end="161" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="273" end="538" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="973" end="1043" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="3106" end="3226" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="3413" end="3529" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-shell/src/agent/config.rs" start="4263" end="4324" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-sampling-types/src/types.rs" start="1010" end="1021" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-pager/src/app/cli.rs" start="235" end="244" repo="https://github.com/xai-org/grok-build" /></code-citation>
<code-citation><citation-definition file="crates/codegen/xai-grok-pager/src/slash/commands/model.rs" start="1" end="99" repo="https://github.com/xai-org/grok-build" /></code-citation>
