Docs

Docs

goose

goose splits the endpoint in two: a Host URL and a request path it appends itself. Give it the bare origin and leave the path alone, and the built-in OpenAI provider is talking to Claude and GPT through one key.

Settings → Models → Configure providers → OpenAI: Host URL takes the bare origin, because goose appends the request path (v1/chat/completions) itself.

Configure providers → OpenAI, or the environment
# goose Desktop → Settings → Models → Configure providers → OpenAI
API Key           sk-kn-...
Host URL          https://api.kunavo.com
Organization ID   (leave blank)
Project           (leave blank)

# …or as environment variables, which goose CLI reads too:
OPENAI_API_KEY=sk-kn-...
OPENAI_HOST=https://api.kunavo.com

# OPENAI_BASE_PATH is left unset on purpose. Its default is
# v1/chat/completions, which is the path Kunavo serves — that default is
# exactly why Host URL above carries no /v1.
Host URL takes no /v1. goose documents OPENAI_BASE_PATH as the “Request path appended to the host (defaults to v1/chat/completions)”, and tells proxy users to set OPENAI_HOST to “your proxy's root (no trailing path)”. That pair is what settles the form: the origin goes in the field, the /v1 arrives with the default path. Typing https://api.kunavo.com/v1 asks for /v1/v1/chat/completions — and the same page reads a 404 as the path being wrong, not the key.
This configuration was read off goose's own documentation on the date below. Kunavo has not run goose against its endpoint — not a session, not a streamed turn, not a tool round-trip. A published setup page is not a test, and nothing here should be read as one; the curl below is the part you can check in ten seconds, and the client's behaviour is between you and goose.
Kunavo serves no embedding, text-to-speech or speech-to-text model, so this endpoint answers chat completions and nothing else. Anything in your goose setup that transcribes audio or builds a vector index keeps whatever provider key it already has — pointing the OpenAI provider here does not move those calls.
No key yet? Create a Kunavo account, make a key (it starts with sk-kn-) and add credit from $10 — calls are paid from that balance, and failed calls are not billed. The dashboard then opens on the goose setup.

Step by step

  1. Create a key at /app/keys and copy it — it is shown once.
  2. In goose Desktop: sidebar → Settings → Models → Configure providers → OpenAI. In the CLI: goose configure → Configure Providers → OpenAI.
  3. Fill in API Key and Host URL. Leave Organization ID and Project empty — goose documents them for usage tracking and resource management on OpenAI's own accounts, and Kunavo has no equivalent to put there. Click Submit.

    goose’s provider table also documents OPENAI_CUSTOM_HEADERS — optional extra request headers written as HEADER_A=VALUE_A,HEADER_B=VALUE_B and settable from the environment, the config file or the CLI — and the current release is goose v1.56.0 of October 23, 2026 (goose-docs.ai providers page and GitHub releases, read October 25, 2026).

  4. Pick the model. goose's note is explicit that goose configure “doesn't support entering custom model names” — so if the id you want is not in the list that comes back, type it in goose Desktop or set GOOSE_MODEL in config.yaml, which overrides the file for that process.
  5. Start a session and give it a task that touches a file. goose leans on tool calling for almost everything it does — its own provider page warns that a model without tool calling “can only do chat completion” and that extensions have to be disabled for one — so a first run that reads and edits something tells you more than a greeting does.

Checked against goose's Configure LLM Provider page on September 29, 2026. Third-party settings move; if a field name here no longer matches what you see, that page is the authority, not this one.

Verify before you debug the client

One request settles whether a failure is the endpoint, the key, or the configuration file. If this returns JSON, the same base URL and key work in goose.

# Settles whether a failure is the endpoint, the key, or the client.
curl -sS https://api.kunavo.com/v1/models \
  -H "Authorization: Bearer sk-kn-..."

Which model id to put in the field

Every text model is reachable as a model id — the live list is GET /v1/models, and the catalog with prices is on the models page. Rates are USD per 1M tokens, input / output.

Model idKunavo in / outWhere it fits in goose
claude-sonnet-5$1.40 / $7.00the default working model for sessions that edit files
claude-opus-5$3.50 / $17.50planning a change that would be expensive to get wrong
claude-haiku-4-5$0.70 / $3.50cheap turns — triage, summaries, the loop that runs all day
gpt-5-6-sol$2.00 / $12.00a second opinion from another family, same key and same Host URL
Billing is per token from a prepaid balance with no monthly fee — see billing. On repeated context — which is most of what an editor or a chat client sends — prompt caching moves the bill more than the model choice does.

The other route: Kunavo's provider file

goose also loads provider definitions from JSON files in its custom_providers directory, and a provider added that way gets its own entry in the picker, its own key and a stored model list instead of overloading the slot named OpenAI. Kunavo publishes one at kunavo.com/goose/kunavo.json. It is generated from the live catalog, so the model list is the set Kunavo serves today, and it carries the name of the key variable, never a key:

terminal
# macOS / Linux — goose reads every JSON file in this directory
mkdir -p ~/.config/goose/custom_providers
curl -fsSL https://kunavo.com/goose/kunavo.json \
  -o ~/.config/goose/custom_providers/kunavo.json

# The file names the variable; the key itself never goes in the file
export KUNAVO_API_KEY=sk-kn-...
goose session start --provider kunavo

On Windows the directory is %APPDATA%\Block\goose\config\custom_providers\. In goose Desktop the provider then shows up under Configure providers as Kunavo, where the key can go into the keychain instead of the environment.

  1. Endpoint. The file sets base_url to https://api.kunavo.com/v1. goose's docs never say whether that field wants the /v1 base or the full /v1/chat/completions their example shows; its source settles it — derive_base_path turns both into the same v1/chat/completions path.
  2. GPT ids use the Responses API. goose sends model ids that start with gpt-5 or gpt-6 to /v1/responses and everything else to /v1/chat/completions. Kunavo serves both, so the Claude and GPT ids in the file work under one key.
  3. Only models with tool calling are listed. goose leans on tools for nearly every turn, so image, video and audio models are left out of the file even though the same key calls them.

The same caveat as the rest of this page applies: this was read off goose's documentation and source, not run. Rather write the provider by hand? Configure providers → Add Custom Provider asks for the same things — type OpenAI Compatible, API URL https://api.kunavo.com/v1, your sk-kn- key, and a comma-separated model list.

Frequently asked questions

How do I point goose at a custom OpenAI-compatible API?

Use the built-in OpenAI provider and give it a host. In goose Desktop that is Settings → Models → Configure providers → OpenAI, where the fields are API Key, Host URL, Organization ID and Project; in the CLI it is `goose configure` → Configure Providers → OpenAI, which prompts for the same values. As environment variables the pair is OPENAI_API_KEY and OPENAI_HOST. If you need several endpoints at once, goose's Add Custom Provider flow gives each one its own entry in the provider list instead.

Does goose's Host URL need /v1 at the end?

No, and adding it breaks the request. goose documents OPENAI_BASE_PATH as the request path appended to the host, defaulting to v1/chat/completions, and tells proxy users to set OPENAI_HOST to the proxy's root with no trailing path. So the field takes the bare origin — https://api.kunavo.com — and the /v1 arrives from the default path. A host ending in /v1 asks for /v1/v1/chat/completions, which is a 404 rather than an authentication error.

Why does goose return 404 after I set a custom host?

goose's own answer is that a 404 usually means the base path is wrong for that endpoint: most proxies serve v1/chat/completions, some serve chat/completions with no v1, and the value you set has to match. Kunavo serves v1/chat/completions, which is goose's default, so a 404 against Kunavo most often means the /v1 was typed into the host as well and is now doubled. A 401 saying no API key was passed in is a different fault — goose documents that a key placed in config.yaml is ignored.

Can goose use Claude models through an OpenAI-compatible endpoint?

Yes. The provider type names a wire protocol, not a vendor: goose sends an OpenAI-shaped chat completion to the host you configured and passes the model id straight through, so a Claude id resolves at that endpoint rather than inside goose. One thing to keep in mind is that goose uses tool calling heavily and its provider page says a model without tool calling can only do chat completion, with extensions disabled — so pick ids that support tools.

Has this setup been tested by Kunavo?

No. What was checked is goose's own documentation (September 21 and 29, 2026) — the field names, their order and the host-plus-path rule are quoted from it — and, for the provider file, goose's provider source (September 29). Kunavo has not run a goose session against its endpoint and makes no claim about streaming, tool round-trips or extension behaviour in this client. The one thing you can settle in isolation is whether the endpoint and key work at all, which the curl on this page does.

Is there a ready-made Kunavo provider file for goose?

Yes: https://kunavo.com/goose/kunavo.json. Save it into goose's custom_providers directory (~/.config/goose/custom_providers/ on macOS and Linux, %APPDATA%\Block\goose\config\custom_providers\ on Windows), set KUNAVO_API_KEY, and Kunavo appears in the provider list with its model ids already filled in. The file is generated from the live catalog, so it lists only models Kunavo currently serves, and it contains no key.