Connect NextChat to Router One with a host-root BASE_URL
NextChat (formerly ChatGPT-Next-Web) is an open-source ChatGPT-style chat app with one-click Vercel and Docker deployment and desktop clients. It calls OpenAI-format APIs through Chat Completions, so one Router One key can put GPT, Claude, Gemini, and Grok family models in its model picker. Two details decide whether that works: NextChat appends v1/chat/completions itself, so the base URL is the host root rather than /v1, and its model list is fixed by configuration, so catalog models appear only after you add them by exact ID.
Configure NextChat to use the Router One base URL
For a self-hosted deployment, set these as Docker -e flags or Vercel project environment variables, then redeploy. BASE_URL is the host root: NextChat's server route strips /api/openai/ from the incoming path and joins the remainder, v1/chat/completions, onto BASE_URL, so a value ending in /v1 would call /v1/v1/chat/completions. OPENAI_API_KEY is the server-side key every chat uses; CODE is the access password users type into the UI. CUSTOM_MODELS starts with -all to hide NextChat's built-in model names, then adds each catalog model by exact ID; the @OpenAI tag keeps the model on NextChat's OpenAI-format client, and =label sets the name shown in the picker. DEFAULT_MODEL chooses which of those a new chat starts with:
# NextChat self-hosted: Docker -e flags or Vercel project environment variables BASE_URL=https://api.router.one OPENAI_API_KEY=sk-your-router-one-key CODE=your-access-password CUSTOM_MODELS=-all,+<model-id-from-/models>@OpenAI=<label> DEFAULT_MODEL=<model-id-from-/models> # Example: docker run -d -p 3000:3000 --env-file nextchat.env yidadaa/chatgpt-next-web
Desktop app or hosted UI: enter the endpoint in Settings
When you cannot set server variables — the desktop client, or a hosted instance whose admin allows user keys — open Settings, turn on Custom Endpoint, keep Model Provider on OpenAI, and fill in the host-root URL, your key, and the model IDs. The host-root rule is the same: the client joins v1/chat/completions onto the endpoint field. In a browser deployment this setting makes the browser call the gateway directly instead of the instance's /api/openai route (the gateway accepts cross-origin requests, which is why that works), and a key entered here takes the place of the access password. If the admin set HIDE_USER_API_KEY=1, the whole section is hidden and every chat stays on the server key. The desktop client sends requests natively, so this form is the only setup it needs.
| Settings field | Value | Notes |
|---|---|---|
| Custom Endpoint | on | Reveals the provider fields; hidden when HIDE_USER_API_KEY=1 |
| Model Provider | OpenAI | Selects NextChat's OpenAI-format client (Chat Completions) |
| OpenAI Endpoint | https://api.router.one | Host root; NextChat appends v1/chat/completions |
| OpenAI API Key | sk-your-router-one-key | Replaces the access password for this browser or app |
| Custom Models | -all,+<model-id>@OpenAI=<label> | Same syntax as CUSTOM_MODELS; extends the picker for this browser or app |
What NextChat reads from the model ID
NextChat has no capability lookup for models it does not ship with. Several behaviours are keyed on the model name string, so an exact catalog ID such as openai/gpt-5.5 is handled differently from the bare names NextChat was written around:
| Behaviour | How NextChat decides | What to do with a catalog ID |
|---|---|---|
| Model picker | Built-in model names plus CUSTOM_MODELS; listing from the endpoint is disabled by default and, when enabled, keeps only gpt- and chatgpt- IDs | Add every model you want by exact ID; NextChat never reads the gateway's /models |
| Server allowlist | When CUSTOM_MODELS is set, a request for an ID it does not allow is refused by NextChat's own route with 403 “you are not allowed to use … model” | Look for that message before blaming the gateway; the request never left NextChat |
| Image upload | The VISION_MODELS variable first, then name patterns (gpt-5, claude with a 3 or 4, gemini-2.0 or 2.5, grok-4, o3, o4-mini, vision) | List IDs the patterns miss in VISION_MODELS after checking input modalities on the model page |
| Sampling parameters | Only bare names starting with gpt-5, o1, o3 or o4-mini are sent with NextChat's fixed sampling values instead of the chat's settings, plus max_completion_tokens | A prefixed ID sends the chat's own settings; if a 400 names a parameter, set that chat's Temperature and Top P to 1 |
Which model ID should NextChat send?
Copy the exact model ID from /models, preserving case, hyphens, and version suffixes; do not substitute a display name. Open its detail page and match the supported API endpoints, context window, and capabilities such as tool calling to the provider and features selected in NextChat. A catalog listing does not mean the client can use every feature of that model. Give each tool a dedicated API key with a maxSpend cap.
Which API protocol is NextChat using?
OpenAI-compatible describes an interface format; it does not make Chat Completions (/v1/chat/completions), Responses (/v1/responses), and Anthropic Messages (/v1/messages) interchangeable. Check the installed client version, provider configuration, and actual request path against the model detail page and API compatibility fact sheet. A successful plain-text chat does not establish support for hosted tools, conversation state, or file-editing features.
Verify the NextChat call in your request trace
Send a simple text request from NextChat, then match its trace in Dashboard → Logs by time, model, and request_id: tokens, cost, latency, and status. Next, test streaming, tool calls, and multi-turn history separately. For failures, retain the actual request path, full error message, and request_id. If there is no matching log, check client configuration and connectivity before attributing the error to the gateway or upstream.
FAQ
Should BASE_URL end with /v1?
No. NextChat's README documents BASE_URL as a host such as http://your-openai-proxy.com, and its server route joins v1/chat/completions onto it. Set BASE_URL=https://api.router.one; with https://api.router.one/v1 the request goes to /v1/v1/chat/completions and fails. The in-app OpenAI Endpoint field follows the same rule. This is the opposite of the SDK guides on this site, which take the /v1 base URL, so do not copy the value between tools.
Why do catalog models not appear in NextChat's model picker?
NextChat does not query the gateway's /models endpoint: its OpenAI client ships with model listing disabled, and even when enabled it keeps only IDs starting with gpt- or chatgpt-. The picker shows NextChat's built-in names plus whatever CUSTOM_MODELS (or the in-app Custom Models field) adds. Use -all to hide the built-in names, some of which the gateway may not serve, then add each catalog model by exact ID — for example -all,+openai/gpt-5.5@OpenAI=GPT-5.5,+anthropic/claude-sonnet-5@OpenAI=Claude Sonnet 5. The @OpenAI tag applies to every family: it selects NextChat's OpenAI-format client, which is the Chat Completions request the gateway serves for every chat model. Without a tag, NextChat files the model under a provider group named after the model itself.
Whose key does a shared NextChat instance spend?
With OPENAI_API_KEY set on the server, every user who enters the CODE password chats on that one Router One key, so the whole instance is one trace under one maxSpend cap. A user who enters their own key under Settings → Custom Endpoint bypasses the password and spends on that key instead; NextChat's server refuses user keys only when HIDE_USER_API_KEY=1. Give the instance a dedicated key with a maxSpend limit, and filter Dashboard → Logs by that key when reconciling a shared deployment.
Which models can NextChat use through the gateway?
Choose a current catalog model that supports both the endpoint and the features NextChat uses. Check /models and the model detail page for the exact ID, current rates, and capabilities; a family name such as GPT or Claude is not a compatibility guarantee. Seeing a model in the picker confirms discovery, so verify an actual request too.
Models are listed, but requests fail with 400 or 404. What should I check?
Record the actual request path and error message, then check the exact model ID. A 400 can indicate invalid parameters, unsupported tools, or a model/endpoint mismatch; a 404 can indicate an incorrect path or missing resource, so it does not by itself establish that a model was retired. If the error says must be called via, use the named endpoint or select a model supported on the current endpoint. Do not add or remove /v1 or /chat/completions across all clients indiscriminately.
Does this work from Mainland China?
Yes. The gateway is reachable from Mainland China without a VPN, and the configuration is identical to the global setup.
How do I debug a 401/402/403/429?
Match the request and error message in Dashboard → Logs. For 401, check whether the key was sent and is valid; for 402, check wallet balance and maxSpend; for 403, check key permissions and access restrictions. For 429, distinguish request/token limits from upstream throttling using the error details. Keep the request_id and follow the error-codes reference.