Dify with a custom OpenAI-compatible model endpoint
Dify treats a custom endpoint as just another model provider, so one OpenAI-compatible URL can back every workflow node and every knowledge-base app you build. The setup is entirely in the console — no code — but three fields have to be exactly right or the failures are silent.
/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-20.Adding the provider
In the console, go to Settings, then Model Provider, and add a provider of the OpenAI-API-compatible type. That entry is separate from OpenAI itself and is the only one that accepts an arbitrary endpoint URL. Once saved, the model becomes selectable anywhere a model is used — LLM nodes in workflows, knowledge-base answering, and the rest of the app builder.
A provider can hold several models. Add each one you intend to use with its own name and, if your endpoint keys differ per model, its own key — workflows then pick between them per node rather than globally.
The three fields that have to be exact
| Field | What it does | What goes wrong |
|---|---|---|
| API endpoint URL | Root Dify appends resource paths to | Missing /v1 → 404 with no warning; trailing slash → malformed path |
| Model name | Sent verbatim as the model field | Abbreviation or wrong case → model does not exist |
| API key | Authorisation header | Field is mandatory even when the endpoint ignores it; leaving it empty can block saving |
The model name is the one that catches people out, because Dify has no discovery step and no fuzzy matching. Read the identifiers straight from the endpoint before you fill the field:
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']))"
If Dify runs in Docker, localhost is not your machine
This is the single most common reason a perfectly good endpoint will not connect: inside a container, localhost resolves to the container itself. A model server on the same host is unreachable at 127.0.0.1 no matter what port it listens on. Use host.docker.internal where Docker provides it, or the host's LAN address, and verify the container can actually route to that port before you debug anything else.
# Let the container resolve the host (usually needed explicitly on Linux)
services:
dify:
extra_hosts:
- "host.docker.internal:host-gateway"
Test before you build
Dify puts a test control on each saved model. Use it. Debugging a broken model inside an orchestration canvas means re-running whole workflows, and each attempt spends real requests — a single test call tells you the same thing for a fraction of the cost. When a node does fail, open the node log and read the JSON message field rather than the red banner; the banner is a summary, the message is the reason.
What Dify actually costs
Dify's unit of consumption is the run, not the user. A knowledge-base app answering two hundred questions a day makes two hundred runs whether those questions came from two people or two hundred, and a retrieval step inside each run means the input side carries retrieved chunks on top of the question. Cost therefore scales with executions and with how much you retrieve per execution.
| Model | Vendor | Rate in / out per 1M | Per run | Per month |
|---|---|---|---|---|
| gpt-5.6-luna | OpenAI | $0.1 / $0.6 | $0.0021 | $13 |
| MiniMax-M3 | MiniMax | $0.15 / $0.6 | $0.0027 | $16 |
| deepseek-v4-flash | DeepSeek | $0.22 / $0.66 | $0.0036 | $22 |
| gemini-3.7-flash | $0.375 / $1.875 | $0.0073 | $44 | |
| claude-haiku-4-5-20251001 | Anthropic | $0.5 / $2.5 | $0.0097 | $58 |
| deepseek-v4-pro | DeepSeek | $0.66 / $1.98 | $0.0109 | $65 |
| glm-5.3 | Zhipu | $0.7 / $2.2 | $0.0117 | $70 |
| qwen3.8-max | Alibaba | $1 / $3 | $0.0165 | $99 |
| claude-sonnet-5 | Anthropic | $1 / $5 | $0.0195 | $117 |
| gpt-5.6-terra | OpenAI | $1 / $6 | $0.0210 | $126 |
| kimi-k3 | Moonshot | $1.5 / $7.5 | $0.0293 | $176 |
| claude-opus-5 | Anthropic | $2.5 / $12.5 | $0.0488 | $292 |
How this fails in practice
| What you see | What it usually is | Fix |
|---|---|---|
| 404 from the endpoint | URL missing the /v1 segment, or a trailing slash | End with /v1, no trailing slash |
| Model does not exist | Name typed is not the identifier the endpoint serves | Copy the ID from the endpoint's model list |
| Cannot reach a local server | Dify in Docker; localhost is the container | Use host.docker.internal or the host LAN IP |
| Cannot save the provider | API key field left empty | Enter any non-empty placeholder if the endpoint needs none |
| Intermittent failures under load | Endpoint rate limit; workflow retries too fast | Add backoff or increase the interval between node calls |
| Cost grows faster than usage | Retrieval pulls in more chunks than needed | Cap retrieved chunks per run |
https://aicomp.ai/v1).
Create one free →
Confirming it took effect
Use the test control on the saved model and send a trivial prompt. A successful reply proves the URL, the name and the key all line up. Then check the gateway usage log for the request — if the test passes but nothing appears there, you are still talking to a different provider than the one you configured.
FAQ
Which provider type do I pick for a custom endpoint?
The OpenAI-API-compatible one. It is a distinct entry in Dify's provider list, separate from OpenAI itself, and it is the only one that lets you supply an arbitrary endpoint URL. Everything downstream — workflow nodes, knowledge-base answering — then treats it like any other model.
Why does my endpoint return 404 when the URL looks right?
Almost always a missing version segment. Dify appends the resource path to whatever you entered, and it does not warn when the result is wrong — the request just 404s. End the URL with /v1 and do not add a trailing slash.
Why does Dify say the model does not exist?
Because the name you typed is sent verbatim as the model field. Dify has no fuzzy matching: an abbreviated or differently-cased identifier is a model error. List the endpoint's models and copy the identifier character for character.
The key field is required but my endpoint does not need one
Fill it with any non-empty string. Dify treats the field as mandatory regardless of whether the endpoint validates it, so a local or unauthenticated server still needs a placeholder value there.
Why can't Dify reach a model server on the same machine?
If Dify runs in Docker, localhost inside the container is the container itself, not your host. Use the host's address — host.docker.internal on Docker Desktop, or the machine's LAN IP otherwise — and make sure the container can actually route to that port.
How does Dify's cost scale?
By execution, not by user. Each workflow run is one or more model calls, so a knowledge-base app that answers two hundred questions a day makes two hundred runs regardless of how many people are asking. That is why the table above prices a single run and multiplies by execution count.