Point Roo Code at an OpenAI-compatible endpoint
Roo Code is a VS Code agent that reads your repository, so every request carries the in-scope files plus history. Three fields change, and the one that trips people up is not the URL — it is the model ID.
/v1 and a key from that endpoint. The setting below is the only thing that changes — request and response handling stay identical. Rates checked 2026-09-26.The setting
In the extension settings, choose OpenAI Compatible as the API provider. Three fields appear: Base URL, API Key and Model ID. The base URL needs the version segment and no trailing slash:
API Provider : OpenAI Compatible
Base URL : https://aicomp.ai/v1
API Key : sk-...
Model ID : claude-sonnet-5
Take the model ID from the endpoint's own listing rather than typing it from memory — most "model not found" and "invalid model format" errors are a character-level mismatch, not a configuration problem:
curl -s https://aicomp.ai/v1/models -H "Authorization: Bearer $KEY" \
| python3 -c "import sys,json;print('\n'.join(m['id'] for m in json.load(sys.stdin)['data']))"
One more requirement that is easy to overlook: Roo Code drives file reads, edits and commands through native OpenAI tool calling. A model that cannot do tool calls will hold a perfectly normal conversation and fail at every action that touches your project. That failure looks like a permissions issue and is not one.
What Roo Code costs
Each request carries the in-scope repository context plus conversation history, and produces relatively little back. Twenty-five requests a day on a mid-sized repository is roughly 2M input against 75k output — about 27:1.
| Model | Vendor | Rate in / out per 1M | Per day | Input share of the bill | Per month |
|---|---|---|---|---|---|
| gpt-5.6-luna | OpenAI | $0.1 / $0.6 | $0.24 | 82% | $5 |
| MiniMax-M3 | MiniMax | $0.15 / $0.6 | $0.34 | 87% | $7 |
| deepseek-v4-flash | DeepSeek | $0.22 / $0.66 | $0.49 | 90% | $10 |
| gemini-3.7-flash | $0.375 / $1.875 | $0.89 | 84% | $18 | |
| claude-haiku-4-5-20251001 | Anthropic | $0.5 / $2.5 | $1.19 | 84% | $24 |
| deepseek-v4-pro | DeepSeek | $0.66 / $1.98 | $1.47 | 90% | $29 |
| glm-5.3 | Zhipu | $0.7 / $2.2 | $1.56 | 89% | $31 |
| qwen3.8-max | Alibaba | $1 / $3 | $2.23 | 90% | $44 |
| claude-sonnet-5 | Anthropic | $1 / $5 | $2.38 | 84% | $48 |
| gpt-5.6-terra | OpenAI | $1 / $6 | $2.45 | 82% | $49 |
| kimi-k3 | Moonshot | $1.5 / $7.5 | $3.56 | 84% | $71 |
| claude-opus-5 | Anthropic | $2.5 / $12.5 | $5.94 | 84% | $119 |
Input is between 82% and 90% of that. The variable that moves this page more than the model choice is how much of your repository is in scope. Taking the cheapest input rate in the table ($0.1 per million), the same twenty-five requests cost $0.10 a day when a turn carries 20k of context, $0.24 at 80k, and $0.55 at 200k — a tenfold difference driven entirely by scope, with the model held constant. Narrowing what Roo reads will usually beat switching models.
Measure it once rather than estimating. One real request against your own project tells you the ratio you are actually paying:
import os
from openai import OpenAI
# One real request tells you what a Roo Code turn actually costs.
# Roo sends the whole in-scope context every turn, so watch prompt_tokens.
client = OpenAI(base_url="https://aicomp.ai/v1", api_key=os.environ["KEY"])
r = client.chat.completions.create(
model="claude-sonnet-5",
messages=[{"role": "user", "content": "Summarise this repo's entry point."}],
max_tokens=512,
)
u = r.usage
print(f"in={u.prompt_tokens:,} out={u.completion_tokens:,} "
f"ratio={u.prompt_tokens / max(1, u.completion_tokens):.0f}:1")
If that prints a ratio far above 27:1, your workspace is putting more into scope than you assumed, and a smaller scope will save more than switching models.
How this fails in practice
| What you see | What it usually is | Fix |
|---|---|---|
| 400 invalid model format | Model ID entered without its provider prefix | Copy the ID from /v1/models exactly as listed |
| Chat works, file edits and commands fail | Model does not support OpenAI tool calling | Pick a model that does; the URL and key are not the problem |
| 404 on every request | Base URL missing /v1 or carrying a trailing slash | Root ending in /v1, nothing after it |
| Context limit hit part-way through a task | Repository puts more in scope than the window allows | Narrow the workspace scope, or use a larger-window model |
| New setting seems ignored | Provider configured but not selected as active | Confirm the provider is the active one, then send a fresh message |
| Costs far above the estimate | More of the repository in scope than assumed | Measure prompt_tokens on a real request |
https://aicomp.ai/v1).
Create one free →
Confirming it took effect
Send one message and read the usage log on the endpoint. A request recorded there is the only reliable proof — an answer in the editor can come from a provider configured earlier, and nothing in the UI distinguishes them. If the log is empty, the request never left the editor: check the model ID first, then the URL, then the key.
FAQ
Where do I enter a custom endpoint in Roo Code?
In the extension's settings, by selecting OpenAI Compatible as the API provider. That reveals three fields — Base URL, API Key and Model ID — and they are the whole configuration. There is no file to edit and nothing to restart, which makes it quick to set up and equally quick to get subtly wrong, because a wrong value fails silently until the first request goes out.
Why do I get a 400 invalid model format error?
Because the model identifier was entered without its provider prefix. Many OpenAI-compatible deployments expect the form provider/model-id, and a bare identifier that works against the endpoint with curl can be rejected here. Take the identifier straight from the endpoint's /v1/models listing rather than retyping it, and check for trailing characters or line breaks if you pasted it.
Chat works but Roo cannot edit files or run commands. Why?
Roo Code drives file operations and command execution through the native OpenAI tool-calling format. If the model does not support tool calls, ordinary conversation still works perfectly while every action that touches your repository fails — which reads as a permissions problem but is not one. Confirm the model supports OpenAI-compatible tool calling before investigating anything else; changing the base URL or regenerating the key will not fix it.
What does a Roo Code turn actually cost?
Mostly input. Each request carries the in-scope repository context plus the conversation history, and typically runs tens of thousands of prompt tokens against a few thousand completion tokens. The exact number depends on how much of the repository is in scope, which is worth measuring once on your own project rather than estimating — the difference between a focused workspace and a large one is large enough to change which model is cheapest.
Is output pricing irrelevant for Roo Code?
Not irrelevant, but close to it. The ratio lands near 27:1 in favour of input on a typical day, so the input rate drives the bill and the output rate is a minor correction. The practical consequence is that a model with a low input rate and a high output rate is genuinely the cheaper choice here, even though the same model would be a poor pick for a chat-heavy tool where the ratio is far closer to even.
Do I need to restart VS Code after changing the endpoint?
Usually not — the setting applies to subsequent requests. If a change appears to have no effect, send a fresh message rather than reusing a conversation started under the previous configuration, since the earlier turn may still be holding the old context. If it still does not take, confirm the provider is actually selected: having configured a custom endpoint and not chosen it as the active provider is a common and entirely invisible mistake.
How do I check the endpoint is really being used?
Send a message and then read the usage log on the endpoint. A request recorded there is the only reliable confirmation — a plausible answer in the editor can come from a provider configured earlier, and the extension does not tell you which one replied. If the log stays empty, the request never went out; check the model identifier first, then the URL, then the key.