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.
# 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./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.curl below is the part you can check in ten seconds, and the client's behaviour is between you and goose.Step by step
- Create a key at
/app/keysand copy it — it is shown once. - In goose Desktop: sidebar → Settings → Models → Configure providers → OpenAI. In the CLI:
goose configure→ Configure Providers → OpenAI. - 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.
- 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 setGOOSE_MODELinconfig.yaml, which overrides the file for that process. - 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 21, 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 id | Kunavo in / out | Where it fits in goose |
|---|---|---|
claude-sonnet-5 | $2.00 / $10.00 | the default working model for sessions that edit files |
claude-opus-5 | $2.00 / $10.00 | planning a change that would be expensive to get wrong |
claude-haiku-4-5 | $0.40 / $2.00 | cheap turns — triage, summaries, the loop that runs all day |
gpt-5-6-sol | $2.00 / $12.00 | a second opinion from another family, same key and same Host URL |
The other route: Add Custom Provider
goose has a second mechanism, and it is the better one if you already point goose at more than one endpoint: a custom provider gets its own entry in the provider list, its own display name, its own key and a stored model list, instead of overloading the slot named OpenAI. The docs describe it in goose Desktop as Configure providers → Add Custom Provider, and in the CLI as goose configure → Custom Providers → Add A Custom Provider, with these fields:
- Provider Type —
OpenAI Compatiblefor Kunavo's/v1/chat/completionssurface. (Anthropic Compatibleis offered too, and Kunavo answers/v1/messagesas well; this page does not describe that pairing because the docs show no value for the field in that mode either.) - Display Name — what you want to see in the picker.
- API URL — see the caveat below.
- API Key — your
sk-kn-key, stored in the keychain. - Available Models — a comma-separated list, which is where the ids from the table above go.
- Streaming Support — a toggle. Kunavo streams chat completions; whether goose's custom-provider path streams them the way you expect is one of the things Kunavo has not run.
The caveat: goose's docs describe API URL only as “The base URL of the API endpoint”, and the one concrete value they ever show for it — the base_url key in their example provider JSON — is a full https://api.company.com/v1/chat/completions, path included. No sentence on that page says which of the two a reader should type, so this page will not guess one into a config block: if you take this route, try the full https://api.kunavo.com/v1/chat/completions first, since that is the shape their own example uses, and fall back to the OpenAI provider above, where the host-and-path split is spelled out.
FAQ
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, on September 21 2026, is goose's own documentation — the field names, their order and the host-plus-path rule are quoted from it. 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.