Windsurf Setup Guide: Custom Models and the BYOK Question
What Windsurf needs to talk to a model you chose, how to find the provider settings in your build, and the local proxy fallback when there is no slot for one.
Windsurf is an agentic editor built around Cascade, a flow that reads your workspace, plans a change and applies it across files. Unlike a plain chat client, it is designed around a credit system and a curated model list, and that design decision is the thing that determines how much freedom you have to bring your own endpoint.
Before hunting through menus, it is worth being clear about what any integration of this kind needs: a base URL for an OpenAI-compatible surface, a key, and a model identifier the endpoint will accept. If your build exposes those three, you are five minutes from done. If it does not, no amount of clicking will produce them, and the honest answer is a different approach rather than a hidden setting.
Check what your build actually exposes
Open the settings surface and look for a section about models, providers or accounts. What you are looking for is either a list of first-party models with a plan attached, or a section that lets you add credentials for a provider of your own — commonly labelled something like bring your own key.
Two things distinguish a real custom-endpoint option from a vendor-key option. A vendor-key field takes a key for a named provider and nothing else; the model list stays fixed. A genuine custom-endpoint option gives you a base URL field as well, and usually a free-text model name, because those are the two pieces that let it talk to a service it has never heard of.
This capability has moved around between releases and editions, so rather than trusting a click path from a blog post, search the settings pane for the word describing a base URL or endpoint. If there is no such field anywhere, your build does not support arbitrary providers, and that is a product decision rather than a misconfiguration.
If the fields exist, fill them carefully
The base URL should be the root of the OpenAI-compatible surface, ending at the version segment. Do not append the path for a specific operation; most clients add it themselves, and doubling it produces a 404 that reads like an auth failure. The distinction between the parts of that surface that are reliably portable and the parts that are not is covered in what OpenAI compatibility actually means.
The key goes in as a bearer token. The model identifier is passed through verbatim, so it must match exactly what your provider publishes; there is no fuzzy matching and no substitution when a name is unknown.
If the settings offer capability toggles — tool or function calling, streaming, a context window size — set them from the provider documentation rather than leaving defaults. An agentic editor lives on tool calls, and a model that cannot negotiate them turns Cascade into something that narrates changes instead of making them. That mechanism is worth understanding once, in the tool calling explainer.
When there is no custom provider slot
The workable fallback is to stop trying to change the editor and change what sits behind the address it already accepts. If your build allows a key for a well-known provider but no base URL, you can run a small local proxy that presents the exact API shape that provider uses and forwards requests to the endpoint you actually want, translating model names on the way through.
This is not a hack so much as the normal gateway pattern applied locally. The proxy accepts the request, rewrites the model field to whatever your upstream calls the model, forwards it, and streams the response back unchanged. The same idea at production scale is described in model routing and fallbacks.
Be honest about the cost of this route. You now own a piece of infrastructure that sits in the path of every keystroke-adjacent request, you have to keep its streaming behaviour faithful or the editor feels broken, and any TLS pinning or certificate check in the client will defeat it. It is a reasonable answer for one developer evaluating a model and a poor answer for a team of thirty.
Credits, tokens and knowing which you are spending
Windsurf meters agent work in credits rather than raw tokens, which is convenient until you try to reconcile it with a provider bill. If you configure your own endpoint, you need to know which requests draw down credits and which bill you directly, because paying twice for the same session is easy and invisible.
The check is the same one that works everywhere: run a real task, then look at your provider dashboard and confirm requests appeared with the model name you configured and a plausible token count. If nothing appears, the editor never used your endpoint no matter what the settings say.
Do that check again after updates. This class of override tends to survive in the settings file and quietly stop applying, and nothing about the experience tells you. The general shape of that problem is laid out in the hidden costs of AI coding tools.
Rules matter more than the model
Windsurf reads rule files from the workspace, and they apply to every Cascade request. Model choice sets a ceiling on quality; rules decide whether you reach it.
Write down the concrete things: the package manager, the test command, which directories are generated, the error-handling convention, and an explicit instruction to make the smallest change that satisfies the request and to ask before touching adjacent code. Agentic editors over-reach by default, and one sentence about scope removes most of the cleanup.
Keep those files in the repository rather than in a personal settings directory, so a review can see them and a new joiner inherits them automatically.
Verifying and troubleshooting
Test in three steps, smallest first. A one-sentence chat answer proves the URL, key and model name agree. Asking the agent to read a named file and quote a line proves tool access, which is a separate code path. Only then hand it a real task, and only on a branch.
When it fails: a 401 is a key from the wrong provider or whitespace from a paste; a 404 on the endpoint is a duplicated version segment; a 404 naming the model is a name your provider does not serve; and output that arrives in one lump instead of streaming means something in the path is buffering. If you are coming from a hosted default and want a checklist for the whole move, migrating away from a first-party API covers the parts that are not editor-specific.
The takeaway
Look for a base URL field first — its presence or absence answers the whole question. If it exists, set URL, key and exact model name, then confirm a real request on your provider dashboard rather than trusting a saved form. If it does not exist, decide honestly whether a local proxy is worth owning, or whether an editor that is a plain client of your endpoint, such as Cline, fits your requirement better.
Common questions
Can Windsurf use any OpenAI-compatible endpoint?
It depends on the build and edition. The test is whether the settings expose a base URL or custom endpoint field alongside the key. A key field on its own only lets you supply credentials for providers the product already knows about.
What is the local proxy fallback and should I use it?
A small service that speaks the API shape the editor expects, rewrites the model name and forwards to your real provider. It works for a single developer evaluating a model, but it puts you in the request path for everything and is a poor fit for a team.
How do I know whether I am spending credits or my own tokens?
Run a real task, then check your provider dashboard for a request with the model name you configured and a plausible token count. If nothing appears, the editor is still using its own routing regardless of what the settings show.