Give every Dify app one model provider
Dify is an open-source platform for building LLM apps, agents and workflows, and every app you ship needs a model provider behind it. Registering Router One once through Dify's OpenAI-API-compatible provider plugin puts the GPT, Claude, Gemini, Grok and DeepSeek chat models in the catalog behind one credential, and every call an app makes that the gateway sends to a model becomes a request in Dashboard → Logs with its model, tokens, cost and status (a streamed call that failed before any output may have no record). The plugin's defaults were written for an unknown endpoint, though: a 4,096-token context size and tool calling switched off. Left as they are, chatbots forget earlier turns and agents fall back to prompt-based tool use. This guide walks through installing the plugin, the add-model form field by field, the settings that matter for real apps, which Dify features Router One cannot serve (Embedding and Rerank), and how to read Dify's first error message. Checked against Dify 1.17.1 and the OpenAI-API-compatible plugin 0.0.68 (its source on 2026-09-27), and re-checked on 2026-10-09, when both were still the latest releases.
Install the OpenAI-API-compatible provider plugin
Model providers in Dify are plugins. Open Integrations → Model Provider, find OpenAI-API-compatible by langgenius in the Marketplace list and install it; version 0.0.68 is the current Marketplace release (checked 2026-10-09). The URL field in its form was renamed on 2026-07-22 in 0.0.55: builds up to 0.0.53 call it API endpoint URL, later ones API Base URL, and it takes the same value either way. Before adding models, create a Router One key for this Dify workspace and set maxSpend on it. Every app, workflow and background task in the workspace will share it, and a key that reaches its cap gets HTTP 402 instead of spending more, while your other keys keep working.
Configure Dify to use the Router One base URL
On the OpenAI-API-compatible card, click Add Model and choose the LLM model type. Model Name is the exact catalog ID, sent unchanged as the model field, for example anthropic/claude-sonnet-5, openai/gpt-5.6-sol, google/gemini-3.7-flash, deepseek-v4.1-flash or grok-4.7. Model display name is optional and only changes what Dify shows. Leave model name for API endpoint empty so the Model Name is what gets sent. API Key is your Router One key (sk- followed by 64 hex characters). API Base URL is https://api.router.one/v1, with exactly one /v1; the plugin appends /chat/completions to it, so apps call POST /v1/chat/completions. Completion mode stays Chat. The remaining fields below are covered one by one in the next section. When you save, the plugin validates the credentials with one very small request, which appears in Dashboard → Logs, so a matching entry there confirms the key, URL and model ID before any app uses them. Add one entry per model you want to offer:
- API Base URL
- https://api.router.one/v1
# Dify → Integrations → Model Provider → OpenAI-API-compatible → Add Model Model type: LLM Model Name: anthropic/claude-sonnet-5 API Key: sk-your-router-one-key API Base URL: https://api.router.one/v1 Completion mode: Chat Model context size: 1048576 # context window from the model page Function Call Type: Tool Call Stream function calling: Support API Type: Chat Completions API (/chat/completions) Compatibility mode: OpenAI compatible (strict) # Plugin releases before 0.0.55 (2026-07-22) label the URL field API endpoint URL
The fields that decide whether Dify apps work
The add-model form has more than a dozen settings with defaults chosen for an unknown endpoint. These are the ones that change behavior with Router One; the rest (Video, Audio and Document Support, User Identity Support, Stream mode auth) can stay as they are.
| Field | Default | Set for Router One | Why |
|---|---|---|---|
| Model context size | 4096 | The model page's context window as a whole number: 1048576 for anthropic/claude-sonnet-5, 1050000 for openai/gpt-5.6-sol, 200000 for anthropic/claude-haiku-4.5 | Dify trims conversation history to fit this size minus the max-tokens setting and the prompt, so at 4096 a chatbot forgets earlier turns |
| Upper bound for max tokens | 4096 | The ceiling you want on the max tokens slider in your apps | It only bounds what apps can request; choose it for your use, not from a catalog figure |
| Function Call Type | Not Support | Tool Call, for IDs whose model page lists tool calling | With Not Support, Agent apps fall back to prompt-based ReAct tool use, which is less reliable than native tool calls |
| Stream function calling | Not Support | Support, together with Tool Call | Declares that the model can return tool calls in a streamed reply |
| Vision Support | Not Support | Support, for IDs whose model page lists image input | Declares that the model accepts image input |
| Structured Output | Not Support | Leave Not Support for Claude IDs | On /v1/chat/completions, response_format is not a reliable way to get JSON from Claude-family IDs |
| API Type | Chat Completions API (/chat/completions) | Keep it; choose Responses API only for GPT-family, DeepSeek or Grok chat IDs | Responses posts to {API Base URL}/responses, which serves only those families |
| Token parameter name | Auto (detect by model) | Keep Auto | Auto sends max_completion_tokens for names that start with o1, o3, gpt-5 or gpt-6; Router One's Chat Completions accepts max_completion_tokens as well as max_tokens as the output cap |
| Include Usage in Stream | Enabled | Keep Enabled | Dify records token usage for streamed replies |
| Thinking Mode Support | Only Non-Thinking Mode | Keep the default unless you have tried the model with thinking on | It changes the thinking controls Dify offers for the model |
| Compatibility mode | OpenAI compatible (strict) | Keep strict | The extended mode injects extra thinking parameters; do not turn it on for Claude or -thinking IDs without testing |
Default models, background requests and what stays off Router One
Under Integrations → Model Provider, Default Models sets the workspace defaults. The System Reasoning Model is used when you create apps and, per Dify's own tip, for conversation name generation and next-question suggestions, so each conversation can add small requests nobody typed; set it to a fast, low-cost chat ID such as anthropic/claude-haiku-4.5. Saving or re-validating a model sends one more small request. Embedding and Rerank are a different matter: Router One serves chat, image and video endpoints but has no /v1/embeddings or rerank endpoint, so knowledge bases need those two defaults from another provider. Choose them once; Dify warns that switching the embedding model later makes the vectors of existing knowledge incompatible with new queries, and retrieval fails until you re-index. Apps you publish still show their own logs in Dify; Dashboard → Logs is where the per-request charge is, and filtering by the workspace key shows the whole workspace's spend.
Read Dify's first error message
When saving fails, Dify shows Credentials validation failed with status code <n> and response body <…>, and the body is Router One's own JSON error, so it usually names the fix. A 404 whose message starts with no route matched means the path is wrong: POST /chat/completions says the /v1 is missing from API Base URL, and a path starting /v1/v1 says it was typed twice. A 401 with AUTH_INVALID_API_KEY means the key was not accepted; check for spaces and that it starts with sk-. A 400 that says model '<id>' must be called via … means the model and API Type do not match, typically a Claude-family ID with API Type set to Responses. A 402 is billing: the wallet balance, or the key's maxSpend cap, which topping up the wallet does not lift. For anything else, keep the request ID from the response and match the entry in Dashboard → Logs.
Which model ID should Dify 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 Dify. A catalog listing does not mean the client can use every feature of that model. Give each client or application a dedicated API key with a maxSpend cap.
Which API protocol is Dify 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 Dify call in your request trace
Send a simple text request from Dify, 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, either the request never reached the gateway (client configuration or connectivity) or the gateway refused it before calling a model — a 401 for the key, a 402 for funds, a 429 from your key's or account's limits, or a 400 or 404 for the model ID or endpoint; a streamed request that failed before any output may have no log either. The status and error message the client received tell which, so check them before attributing the error to the gateway or upstream.
FAQ
Which provider type do I pick in Dify?
Install and use OpenAI-API-compatible by langgenius from Integrations → Model Provider. The provider plugins named after individual vendors expect those vendors' own endpoints and keys, while the OpenAI-API-compatible plugin takes any base URL, which is what Router One needs. Add one entry per model you want to expose, with the exact model ID from /models as Model Name; each becomes selectable in your apps under the display name you give it.
Saving fails with Credentials validation failed with status code 404. What is wrong?
The API Base URL. The plugin appends /chat/completions to whatever you enter, so it must be exactly https://api.router.one/v1. Without /v1 the request goes to /chat/completions, and Router One answers 404 with a message saying OpenAI-compatible clients need a base URL ending in /v1; with /v1 twice it goes to /v1/v1/chat/completions and the message says to remove the extra /v1. Pasting the full endpoint doubles the path the same way. Fix the field and save again; nothing is billed for a 404.
My Dify chatbot forgets what was said a few messages ago.
Check Model context size on the model entry. It defaults to 4096, and Dify keeps only as much conversation history as fits into that number minus the max-tokens setting and the prompt, so older turns are dropped long before the model's real limit. Set it to the context window on the model page, for example 1048576 for anthropic/claude-sonnet-5, and save. Longer history means more input tokens per request, which Dashboard → Logs shows per call.
My Dify agent does not call tools natively.
Function Call Type defaults to Not Support. With that setting Dify's Agent apps fall back to prompt-based ReAct tool use, where the model is asked to write the tool call as text, which is less reliable than native tool calls. Set Function Call Type to Tool Call and Stream function calling to Support, and pick an ID whose model page lists tool calling; for other IDs, test one tool call first.
Should I set API Type to Responses API?
Only for GPT-family models, DeepSeek IDs and Grok chat models, and only if you need something Responses offers that Chat Completions does not. The plugin then posts to {API Base URL}/responses. Claude-family IDs sent there fail with HTTP 400 must be called via …, and Gemini IDs are not served there either, so keep both on Chat Completions, which serves every chat model. The default is the safe choice for a mixed model list.
Dashboard → Logs shows requests no user triggered. Where do they come from?
Usually from the System Reasoning Model, which Dify uses for conversation names and next-question suggestions, and from the small validation request sent each time you save a model. Workflow nodes and agent iterations are also separate calls. Point the System Reasoning Model at a low-cost ID and switch off suggested questions in apps that do not need them. A dedicated key for the workspace makes all of this visible in one filter.
Can Router One serve Dify's Embedding or Rerank models?
No. Router One has no /v1/embeddings or rerank endpoint, so adding an Embedding or Rerank model with the Router One base URL fails. Keep those workspace defaults on another provider and use Router One for the LLM entries. Decide on the embedding model before building knowledge bases, because Dify warns that switching it later breaks retrieval for knowledge already imported.
What is the difference between Model Name and Model display name?
Model Name is sent to Router One as the model field and must match a catalog ID exactly, including the vendor prefix and version. Model display name is only the label your team sees in Dify, so you can name an entry Claude Sonnet 5 while Model Name stays anthropic/claude-sonnet-5. The field called model name for API endpoint, when filled in, is sent instead of Model Name; leave it empty to avoid two different IDs for one entry.
Which models can Dify use through the gateway?
Choose a current catalog model that supports both the endpoint and the features Dify 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. A client that lists a model has only read the ID, from its own configuration or from GET /v1/models; 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?
Start from what your client received: the status, the error body and the X-Request-ID header. A 401 (missing, unknown, revoked or expired key), a 402 (wallet balance, or the key's maxSpend cap) and a 429 from your key's or account's rate limits are refused before any model is called, so they never appear in Dashboard → Logs — nor does a 400 or 404 for a wrong model ID or endpoint. For 401, check that the full key is sent and still active in Dashboard → API Keys; for 402, top up or raise the key's maxSpend; for a 403, keep the full error body. For 429, back off and retry later; a 429 that does show up in Logs came back from upstream after the gateway's retries. Keep the request_id and follow the error-codes reference.