Cline OpenAI Compatible 401: Invalid API Key and Base URL Fixes

You are three fields into Cline's settings panel. Provider dropdown, base URL, API key, model ID. You pasted all of them, hit save, started a task — and got 401 - invalid_api_key back. So you regenerate the key. Still 401. So you start editing the base URL, and now you are getting 404. Two hours later the key was fine the whole time and you have changed the one field that was correct.

If you searched cline openai compatible 401 invalid api key, that loop is probably why. The fix is not a different key. It is knowing which of the two failures you are looking at.

Authentication runs before routing. A 401 is the endpoint rejecting your credential. A 404 is the endpoint accepting your credential and then failing to find the path you asked for. The two errors point at different fields, and treating them as the same problem is what sends people in circles.

The four values Cline needs

Open the Cline panel, click the gear icon, and set the provider to OpenAI Compatible first. Nothing else appears until you do. Then fill these:

{
  "apiProvider": "OpenAI Compatible",
  "baseUrl": "https://aicomp.ai/v1",
  "apiKey": "sk-your-gateway-key",
  "modelId": "claude-sonnet-5"
}

That block is the four values in panel order, not a file to drop somewhere. Paste them into the fields.

Two rules before you touch anything else:

Now prove the key works before you blame Cline. One command, no SDK:

# Replace with your own key. A JSON list of model IDs means the credential is good.
curl -s https://aicomp.ai/v1/models \
  -H "Authorization: Bearer sk-your-gateway-key" \
  | jq -r '.data[].id' | head -40

If that prints IDs, the key and the base URL are both fine and the problem is downstream. If it prints Invalid token, the credential is broken and no amount of Cline configuration will fix it.

You need a key before the code below runs. Create an account, generate a key, and copy the base URL (https://aicomp.ai/v1). Create one free →
Check current rates → Free to sign up · $1 minimum top-up · No prepayment

What Cline actually does with the base URL field

Cline's own documentation describes the field as "the API endpoint specific to the provider" and calls entering it "a crucial step" — and that is the whole of it. The docs do not commit to a rule about path appending. Two incompatible rules circulate in third-party integration write-ups: one says the base URL must end at /v1 because Cline appends /chat/completions, the other says Cline appends the whole /v1/chat/completions and the /v1 must be left off. Both rules come from integration guides rather than Cline's documentation, and neither behaviour has been reproduced here on a single build — so treat neither as authoritative.

Do not guess. Bisect it.

Cline's panel does not show you the URL it built, so ask the endpoint which shape it serves and work backwards:

KEY=sk-your-gateway-key
for base in "https://aicomp.ai" "https://aicomp.ai/v1"; do
  for path in "/chat/completions" "/v1/chat/completions"; do
    code=$(curl -s -o /dev/null -w "%{http_code}" "$base$path" \
      -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
      -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"hi"}],"max_tokens":16}')
    echo "$base$path  ->  $code"
  done
done

Exactly one combination returns 200. That is the only chat URL your gateway serves. Now set the Base URL field so that what you typed plus whatever Cline appends lands on it:

Watch that log for a second reason. A completed Cline task proves nothing about which endpoint billed it. That matters because the quiet failure mode on this provider is a base URL field left empty, which sends traffic to OpenAI instead. That failure works: tasks succeed, and the invoice lands somewhere you were not watching.

Three things about this provider that catch people

The Base URL field does not exist until you change the dropdown

Under a named vendor provider — Anthropic, OpenAI, Gemini — there is no base URL field to override. This is the single most common reason people conclude Cline cannot do custom endpoints at all. It can; the field is just gated behind the OpenAI Compatible choice.

There is a related trap in the other direction. Cline's named providers each expose their own field set, and those sets move between releases. If a named provider does not show a base URL field, stop hunting for a hidden toggle — the generic OpenAI Compatible channel is the one that always has one. Reach Gemini model IDs through it rather than through the Gemini entry.

The model dropdown is a snapshot, not a live catalogue

Cline ships a static list. Your endpoint's catalogue changes whenever upstream does. So a model that exists and bills correctly can be absent from the dropdown, and an empty or short dropdown is not evidence that your endpoint is broken.

Pull the list yourself and copy from it:

curl -s "$BASE/models" -H "Authorization: Bearer $KEY" \
  | jq -r '.data[] | "\(.id)\t\(.context_length // "n/a")\t\(.max_output_tokens // "n/a")"'

Those last two columns are the numbers the next section wants.

Model Configuration is yours to fill, and one entry truncates silently

Under a named provider Cline knows the model's limits. Under a generic one it cannot, so the Model Configuration section — max output tokens, context window, image support, computer use, input price, output price — is empty and manual.

Two of these cause real damage when wrong:

If your endpoint publishes these per model, GET /v1/models returns them. Use those values rather than round numbers.

Failure modes

SymptomWhat is actually wrongFix
401 invalid_api_key immediatelyBearer typed into the key field, or a trailing newline from a manual selectionRe-paste with the copy button; the field wants the raw key only
401 but curl with the same key worksWorkspace settings overriding global — a stale key from another projectOpen Cline settings, check whether it is reading Global or Workspace, clear the old value, reload the window
404 on every request, and your error output shows two /v1 segmentsCline appended a version path you already suppliedDrop to https://aicomp.ai — the bisection script below confirms which shape this build produces
404 on every request, and your error output shows /chat/completions/chat/completionsFull resource path pasted into the base URLBase URL ends at /v1, nothing after it
model_not_foundDisplay name or remembered ID rather than the exact catalogue stringCopy the ID from GET /v1/models; case and punctuation both matter
Model dropdown empty or missing your modelStatic list shipped with the extension, not a live fetchType the ID by hand — the field accepts free text
Long edits arrive cut offMax output tokens set below what the diff needsRaise it in Model Configuration to the published max_output_tokens
Tasks succeed but your gateway log is emptyThe override never applied — settings read at startup, or an empty base URL falling back to OpenAIRestart the editor, then confirm the request appears in the usage log

What one agent day actually costs

Cline does not send diffs. When it rewrites a file it returns the whole file, so a single edit on a 400-line source file emits several thousand tokens in one response — before any retry is counted. Ten substantial edits in a day, plus the reads and command output around them, lands around 220k input tokens and 75k output tokens. Across 20 working days that is 4.4M input and 1.5M output a month.

That shape — output arriving in one burst per edit rather than trickling out — is why the output rate decides the bill here while the input rate everyone quotes barely registers.

Per 1M input / output tokens,
ModelGateway rate
in / out per 1M tokens
One day20 days
claude-sonnet-5$1.00 / $5.00$0.59$11.90
gpt-5.6-luna$0.10 / $0.60$0.07$1.34
deepseek-v4-flash$0.22 / $0.66$0.10$1.96
gemini-3.7-flash$0.375 / $1.875$0.22$4.46
MiniMax-M3$0.15 / $0.60$0.08$1.56

One day = 220k input + 75k output on this page's workload. 20 days = 4.4M input and 1.5M output. Rates checked 2026-09-26 — gateway rates move with upstream promotions, so verify the current number in your dashboard before committing to a budget.

The row that wins a chat workload does not automatically win this one. Input and output rates move independently, so the only row worth reading is the one matching your shape. For agent loops that means comparing output rates first.

Across 216 catalogue models that publish both rates, the median output rate is 4.0× the input rate, and 68% of them (147 models) charge at least 4× more for output than input. The other 623 raw catalogue entries are dropped by cleaning — test entries, dated snapshots and non-chat variants — not for a missing rate. This is why an agent workload is decided on the output column, not the input one everyone quotes.

FAQ

FAQ

Why does Cline say invalid API key when my key works in curl?

Because the key is not what is failing, or not the only thing. Cline adds the Authorization header itself, so a key field containing Bearer sk-... produces a doubled prefix and a 401 with a key that is perfectly valid. The other cause is scope: VS Code workspace settings override global ones, so a stale key saved in one project keeps 401ing in a window where the global key is correct. Check which scope Cline is reading before you regenerate anything.

Should the Cline base URL end in /v1?

It should end wherever your endpoint stops and the client's appended path begins — and Cline has not been consistent about what it appends. Some builds add /chat/completions to a /v1 base. Others have been seen adding the whole /v1/chat/completions, which doubles the version segment. Two ways to settle it for your build. Some builds print the request URL in the error output; if yours does, count the /v1 segments — one is right, two means drop it from the field, zero means add it. If yours does not, run the bisection script above: the one combination that returns a 200 is the pair your build actually produces.

Why is my model list empty on a custom endpoint?

Because it is not fetched. Cline's OpenAI Compatible provider ships a static model list, so it neither knows nor displays what your gateway serves. An empty dropdown tells you nothing about your connection. Type the model ID into the field — it accepts free text — and copy the string from GET /v1/models so you are not reconstructing it from memory.

Is a 401 different from a 404 here?

Yes, and the difference is the whole diagnosis. Authentication runs before routing. A 401 means the endpoint rejected the credential before it looked at the path, so your problem is in the key field. A 404 means the credential was accepted and the path was wrong, so your problem is in the base URL. Fixing the key when you have a 404 — or the URL when you have a 401 — means editing the field that was already correct.

Do I need to fill in Model Configuration?

For a generic endpoint, yes. A named provider lets Cline fill in context window, max output tokens, image support and pricing because it knows the model. A generic one could be serving anything, so those fields start empty. Two of them cause visible breakage when wrong: max output tokens set too low truncates long diffs mid-file, and a context window set too high produces requests the model rejects.

Can I use one key across Cline and other tools?

Yes. That is the practical reason to route through a gateway — one key, one bill, and spend visible per model instead of spread across vendor dashboards. Keep the key out of any file that gets committed; export it in the shell you launch your editor from, or use the extension's own credential store.

Related

Get API access

Get API access