DurinDoor
Providers

Free and local

Connect local models, anonymous providers, and free tiers with their limits and verification steps.

Some providers never take a paid API key. They are local processes, anonymous public endpoints, OAuth free tiers, or browser cookies. Rate limits and terms still belong to the upstream.

KindWhat you saveExamples
Local model serviceOptional key, optional baseUrlollama-local, lm-studio, vLLM
No-auth registryNothing, or a toggleAI Horde and supported anonymous services
OAuth free tierOAuth connectionProvider-specific free allowance
Browser cookieCookie valueChatGPT Web, other webCookie ids (Web cookie providers)
Local device mediaNothinglocal-device TTS on the host

Ollama and LM Studio

ollama-local talks to http://localhost:11434 unless the connection sets providerSpecificData.baseUrl. The add-key dialog shows an Ollama Host URL field. Local Ollama does not validate keys; DurinDoor still sends Bearer when a key is present.

Discovery reads native /api/tags, /api/show, and /api/ps data per saved host/account. Completion and embedding capabilities remain distinct. An observed served context_length or explicit connection model limit is used when available; a trained maximum, a cloud model with the same name, and the gateway's own localhost port do not establish the local served window. Unknown limits stay unknown.

LM Studio is registry id lm-studio (alias lmstudio). Its key is optional and its default base URL is http://localhost:1234/v1. API key is optional. Models are passthrough: DurinDoor forwards whatever LM Studio currently serves.

Start Ollama or LM Studio on the host and confirm it answers locally (curl against /api/tags or /v1/models).

Open Dashboard, then Providers, then the card. For Ollama, set the host if it is not localhost:11434. For LM Studio, override baseUrl only if you changed the listen port.

Save. Send ollama-local/<model> or lmstudio/<model> (or the alias the catalog shows).

If DurinDoor is in Docker, localhost is the container. Point baseUrl at host.docker.internal or a compose service name.

Other self-hosted OpenAI-compatible ids (vllm, llama-cpp, docker-model-runner, and the rest) are listed on Local router providers. Those executors omit Authorization when no API key or access token is saved.

No-auth providers

Some registry providers accept requests without an upstream credential. Only eligible free chat providers join auto combos. Disable a free provider on Providers if you do not want it in that pool. DurinDoor client authentication still applies.

Only use a no-auth upstream that is already locked down by the network or that runs on the same machine. Do not publish a no-auth local server through DurinDoor to the public internet without an outer access-control layer. DurinDoor client keys still apply; they do not make the upstream private.

AI Horde is the public anonymous exception. Registry id aihorde, alias horde. With no saved key, DurinDoor sends AI Horde's documented sentinel 0000000000 against https://oai.aihorde.net/v1. A saved Horde API key replaces that sentinel and can receive better queue priority. Model ids come from the live /v1/models facade and can contain /. Treat Horde as a low-priority fallback: volunteer workers join and leave, queues move, and prompts are processed on community machines. Do not send secrets. The facade rejects max_tokens below 16.

Same paste flow as Connecting accounts: Dashboard, Providers, cookie card, cookie value. These sessions die when the browser session dies. Fine for a personal box; a poor fit for a shared team gateway.

ChatGPT Web has its own page, ChatGPT Web, covering the cookie formats, the browser and HTTP transports, and the Chromium requirement.

Local device media

local-device provides text to speech without an upstream account. It synthesizes on the host (macOS or Windows) and returns mp3. Other local media ids include local Whisper (local-whisper, default http://127.0.0.1:11500) and optional local TTS/STT tools listed on the media-provider pages. Check those pages for voice, format, sample rate, and service URL fields.

Laya decision engine

laya is a self-hosted Laya server:

pip install "laya[serve]"
laya-serve        # http://127.0.0.1:8000; LAYA_PORT, LAYA_API_KEY, LAYA_DEVICE to change

Add the connection with the server URL: http(s)://host:port, or host:port for plain http. Other values, and URLs with a username or password, are refused. The API key is optional: the server URL stands in for it. Checking the connection calls GET /health, then sends an empty POST /v1/systemone. Laya answers 400 when the key is accepted and 401 when it is wrong or missing. Any other answer means the host isn't a Laya server. Laya is not a chat model. Its checkpoints (auto, english, multilingual, typed-decisions) are System One models: call them on POST /v1/systemone with model: "laya/english" (send x-connection-id to use one connection only; the request then never runs on another), or try them from Dashboard → Media Providers → System One → Laya (local). They appear in GET /v1/models/systemone, not the default chat catalog, and chat requests naming a Laya model get a 400. An active connection replaces Jev as the classifier for smart combos. A keyless laya-serve running on the default host is picked up without a connection. See Complexity-aware routing. Other Jev-compatible servers use Add Custom System One on the same page. Save the node, add a keyless or keyed connection, then open Edit to discover and register native model IDs, or add an ID manually under Models. A missing /models endpoint does not block setup. The node's saved URL determines routing; a request body cannot change the upstream. Outbound proxy pools are unsupported for guarded System One/Laya URLs.

OpenCode free

OpenCode Free uses provider ID opencode and alias oc. It needs no upstream key and can join eligible auto combos. The static catalog currently lists Ox Alpha Free as oc/x-preview-f-free over Chat Completions. OpenCode Go subscribers can use the same model as ocg/ox-alpha-free. Catalog rows can change; GET /v1/models is the live list.

OpenCode's free tier requires an official-client request shape. DurinDoor adds the required headers and unavailable tool definitions. Your exact lowercase bash, glob, grep, or read tool wins over a generated definition. Test tools before relying on this fallback; upstream requirements can change.

Muse Spark contributor models only accept tool_choice: "auto"; the gateway normalizes explicit choices for those IDs.

OpenRouter free models

OpenRouter (openrouter, category freeTier) needs an API key to route requests, but DurinDoor discovers its free models from the public catalog at GET https://openrouter.ai/api/v1/models. That request carries no API key.

A model counts as free when both hold:

  • its id ends in :free (for example openrouter/google/gemma-4-31b-it:free), and
  • every field in its pricing object is "0".

Zero pricing alone is not enough. OpenRouter's routers and some preview media models also publish "0" prices without a :free id, and variable-price routers publish "-1".

Discovery supplies context and output limits, supported inputs and outputs, tool support, and reasoning support when OpenRouter reports them.

Where it shows up:

  • GET /v1/models: with no model selection saved on the OpenRouter connection, the free models are listed next to the static embedding, TTS, image and rerank rows. With a saved selection, the list stays as selected and the catalog only fills in capabilities and limits.
  • Provider page: the suggested-models list shows the same free models with their context windows.
  • Model pickers: fetching models for an OpenRouter connection (provider page, model selector, playground) returns only the free models, so paid models such as Claude or GPT never show up there.
  • Routing: chat requests to an OpenRouter model use the discovered capabilities. Vision, routing, and context checks use discovered capabilities when available.

The catalog is cached in memory for 30 minutes. The fetch times out after 8 seconds, reads at most 8 MiB, and maps at most 2,000 entries. If a refresh fails, the last good catalog stays in use and the next attempt waits 5 minutes. With no good catalog yet, /v1/models falls back to the static list and requests use the static capability table. The first request after a restart may use static capabilities while the catalog loads in the background. A custom model row on the connection still overrides the discovered capabilities.

OpenRouter's documented free-model limits (rate limits):

AccountRequests per minuteRequests per day
Less than $10 in credits ever purchased2050
At least $10 in credits purchased201,000

Xiaomi token plan

xiaomi-tokenplan (aliases xmtp) is an API-key provider for SenseNova Token Plan keys (tp- prefix). Region is required: Singapore (sgp, default), China (cn), or Amsterdam (ams). The catalog is discovered at runtime. Use the dashboard or GET /v1/models instead of copying ids from this page.

Free tiers

OAuth free tiers still need an account. Quota rules change without a DurinDoor release. Keep a paid or local fallback for work that cannot wait on a free pool. Watch usage on the dashboard and reconnect if the upstream revokes the token.

After connecting, use the exact discovered ID in a chat or media request and check Usage. For local failures, verify the server from the gateway host first. Free-tier availability and billing rules belong to the upstream provider and can change independently of this build.

On this page

Edit on GitHub