Skip to content
Router One

Add Router One to Copilot for Obsidian as a custom OpenAI-compatible provider

Copilot for Obsidian (logancyang/obsidian-copilot, listed as Copilot in Community Plugins) connects to Router One through Settings → Copilot → BYOK (bring your own key) → Add a provider → Add a custom provider: Base URL https://api.router.one/v1, a Router One key, exact catalog model IDs such as anthropic/claude-sonnet-5, and Enable CORS turned on for Quick Chat. Router One then serves the model requests from Quick Chat, Quick Ask, Copilot Commands and opencode Agent Chat, while Copilot keeps your notes, context, agent tools, permissions and Miyo search. This guide targets Copilot 4.0.10, released 2026-09-22, and the opencode 1.18.31 build it downloads; the Claude and Codex backends never use BYOK keys.

Before you start: which Copilot features use the provider

Install or update Copilot from Community Plugins and check that the installed version is 4.0.10 or later; this guide was checked against 4.0.10. Copilot 4 requires Obsidian 1.11.4 or newer, its minimum app version, which is also what the Obsidian Keychain that holds BYOK keys needs. Only the first four rows below use the provider; the other features run on their own accounts or services and never use this key.

Copilot surfaceUses the Router One provider?Where the request comes from
Quick Chat (desktop and mobile)Yes, when a Router One model is selectedObsidian itself: POST /v1/chat/completions
Quick AskYes; it uses a Quick Chat modelObsidian itself: POST /v1/chat/completions
Copilot Commands and Trigger quick commandYes, when the model it inherits or names is a Router One modelObsidian itself: POST /v1/chat/completions
Agent Chat with opencode (desktop only)Yes, once opencode is installed and the model is enabled for itThe local opencode process: POST /v1/chat/completions
Agent Chat with Claude or CodexNo; they never use BYOK keysThe Claude Code or Codex CLI, with its own login and configuration, not this BYOK key
Copilot-hosted models, hosted Copilot Plus toolsNo; they need a Copilot license and run on Brevilabs servicesNot Router One
Miyo semantic search, Relevant NotesNo; Miyo keeps its own indexNot Router One

Configure Copilot for Obsidian to use the Router One base URL

Open Settings → Copilot → BYOK, select Add a provider, then select Add a custom provider at the bottom of the dialog. Use this entry instead of changing the URL of the OpenAI entry: the listed vendor entries stay tied to that vendor's model metadata and to opencode's built-in provider for it, while a custom provider reaches opencode as a generic OpenAI-compatible provider at your Base URL. In Configure Custom OpenAI-compatible, set Display name to Router One and paste a dedicated key into API key; the field is marked optional because some custom endpoints run without authentication, but Router One requires the key. Enter https://api.router.one/v1 as Base URL. Copilot appends /models for Test and model discovery, and its chat client appends /chat/completions, so a pasted full endpoint doubles the path. Turn Enable CORS on. Test works without it, but with it off Quick Chat, Quick Ask and Commands send their chat requests with the browser's native fetch, which a CORS preflight can block (see Why Quick Chat needs Enable CORS below); with it on, their replies arrive whole instead of streaming. Select Test: Verified means GET /v1/models accepted the key, and the returned IDs appear under Search available models. Check one or two chat models, or type an exact ID in Model ID and select Add. The placeholder shows a bare name, gpt-5.5, but copy the full catalog ID from /models, prefix included where it has one, as in anthropic/claude-sonnet-5 or openai/gpt-5.5. Select Save. New chat models are enabled for Quick Chat and opencode automatically; choose a Default model under Basic → Agents → Quick Chat (on mobile: Basic → Quick Chat models), and under Basic → Agents → opencode once opencode is installed:

copilot-byok-custom-provider
# Settings → Copilot → BYOK → Add a provider → Add a custom provider
Display name:  Router One
API key:       sk-your-router-one-key       # saved in this device's Obsidian Keychain
Base URL:      https://api.router.one/v1    # not .../chat/completions
Enable CORS:   On                           # Quick Chat, Quick Ask, Commands; replies arrive whole
Model ID:      anthropic/claude-sonnet-5    # full catalog ID, then Add
               openai/gpt-5.5
# Test → check chat models only → Save

# Basic → Agents → Quick Chat → Default model   (mobile: Basic → Quick Chat models)
# Basic → Agents → opencode → Default model   (desktop; install opencode first)
# Each chat turn: POST https://api.router.one/v1/chat/completions

Why Quick Chat needs Enable CORS

Copilot uses two transports. Test, model discovery and the provider checks that run whenever you open BYOK go through Obsidian's requestUrl API, which browser CORS rules do not apply to. With Enable CORS off, Quick Chat, Quick Ask and Copilot Commands send from the Obsidian window with native fetch, and the OpenAI SDK inside Copilot adds its own X-Stainless-* request headers. The browser checks those headers with a CORS preflight first, and as of 2026-09-23 api.router.one does not allow them in its preflight response, so the chat request is never sent: that is why Test can pass while Quick Chat cannot connect. With Enable CORS on, those chat requests go through requestUrl. The reply appears only once it is complete, and the 4.0.10 source notes that this path cannot be aborted, so Stop does not cancel the request: it runs to the end and is billed like any completed request. The switch does not change opencode Agent Chat, which runs as a separate local process and still streams. It is saved per provider and changed under More actions → Edit key.

Count Quick Chat requests: messages, titles and retries

With a Router One model selected, each Quick Chat message is one POST /v1/chat/completions with stream set to true. A new chat includes the active note as context by default, so a long note adds input tokens to every turn. In a local reproduction of the 4.0.10 client settings the body carried only model, messages and stream: Copilot sends no temperature, top_p or output limit for custom-provider models, and it does not request stream usage, so Quick Chat's token counter usually stays hidden for these models; use Dashboard → Logs for tokens and cost. Autosave Chat as Markdown is on by default, and the first time it saves a conversation note Copilot asks the same model for a short title, which is at least one more small request. The client retries a failed request up to three more times, so one message can be sent up to four times. In the reproduction a 500 was sent four times and a 400 only once. A 429 is retried too, after its Retry-After delay, when that delay is 60 seconds or less; gateway rate-limit responses can carry that header. One naming rule also matters: Quick Chat switches model names that begin with gpt-5 to the Responses API. The catalog IDs for GPT models carry a prefix, as in openai/gpt-5.5, so they do not match this rule and stay on Chat Completions. A bare name typed from the placeholder, such as gpt-5.5, is sent to POST /v1/responses instead, which Router One serves natively for the GPT family, so its trace shows that path.

Agent Chat: opencode builds its own requests

Agent Chat on opencode does not reuse the Quick Chat client. When it starts opencode, Copilot passes a generated configuration that registers your custom provider as an @ai-sdk/openai-compatible provider with the same Base URL and key, listing each enabled model under its full catalog ID. A local run of opencode 1.18.31 with such a configuration kept the slash in the model field and sent every request, openai/gpt-5.5 included, to POST /v1/chat/completions. The first message of a session produced two requests, a title request and the main request; the opencode documentation says titles use a cheaper small_model when one is available and otherwise fall back to the main model. Both requests carried stream_options.include_usage and max_tokens 32000, because Copilot passes no output limit for custom models; the main request also added tools and tool_choice, and with openai/gpt-5.5 it carried reasoning_effort as well. Copilot declares no image input for custom-provider models, and its source notes that opencode strips images for models without that declaration. For images, use Quick Chat, which does not block them for these models and sends them as image_url content, with a model whose page lists image input. After you change the provider, key or enabled models, an open chat shows a config has changed notice; choose Reload to restart opencode with the new values.

Search and embeddings stay outside the gateway

Copilot 4.0.6 and later have no embedding-model setting to point at Router One: that release retired Vault QA and removed the plugin's own index, and meaning-based search and Relevant Notes now come from Miyo, a separate local-first app connected under Settings → Copilot → Miyo, which keeps its own index. Router One serves no embeddings endpoint and takes no part in that indexing. Excerpts found by Miyo or by an agent's file tools become part of the prompt sent to your selected model, so they count as input tokens in Logs. Copilot-hosted models and hosted Copilot Plus tools run on Brevilabs services under a Copilot license; this guide covers Quick Chat's Chat mode, which needs no Copilot license (Router One still bills each request), and opencode Agent Chat.

Which model ID should Copilot for Obsidian 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 Copilot for Obsidian. 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 Copilot for Obsidian 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 Copilot for Obsidian call in your request trace

Send a simple text request from Copilot for Obsidian, 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

Test shows Verified, but Quick Chat cannot send a message. What should I change?

Test and its badge only prove that GET /v1/models accepted the key through Obsidian's requestUrl. With Enable CORS off, Quick Chat sends the chat request with the browser's native fetch, which a CORS preflight can block (see Why Quick Chat needs Enable CORS). So first open BYOK, choose More actions → Edit key on the Router One provider, check that Enable CORS is on and save; replies then arrive whole instead of streaming. That is also the fix Copilot documents for this symptom. If Quick Chat then returns an HTTP status with a message, the transport works: check the exact catalog model ID, the /v1 Base URL, and that you did not enable an image-generation ID from the discovered list. A Verified provider also does not prove that every model answers.

I set up Router One in Copilot 3 as a 3rd party (openai-format) model. Do I need to redo it?

Usually not. Copilot 4 has no Model tab. On first load it runs a one-time migration that copies each enabled 3rd party (openai-format) model with a base URL, together with its key and CORS choice, into a BYOK provider named OpenAI Format, one per distinct base URL, key and CORS setting, and enables it for Quick Chat and opencode. Disabled and embedding models are skipped, and the old settings are left in place. Open BYOK, confirm that the provider's Base URL is https://api.router.one/v1, that Enable CORS is on and that its models are exact catalog IDs, then rename it and remove any ID that is no longer in /models. If it shows No key, edit it and paste the key again.

Why is the Router One key missing on my phone or another computer?

Copilot stores BYOK keys in each device's Obsidian Keychain, not in the vault's data.json, so syncing the vault does not carry the key. On that device, open Settings → Copilot → BYOK and re-enter the key through More actions → Edit key, or add the provider there if it is not listed. The Keychain requires Obsidian 1.11.4 or newer; on older versions Advanced → API Key Storage shows Unavailable. On iOS and Android, Quick Chat, Quick Ask and Copilot Commands run (Agent Chat is desktop-only), and their model list is under Basic → Quick Chat models; those requests are sent from the device itself.

Quick Chat works with a model, but Agent Chat on opencode returns 400. Why?

They are different clients. Quick Chat sends model, messages and stream, while opencode adds tools, tool_choice, stream_options.include_usage and max_tokens 32000, plus reasoning_effort: medium for IDs that contain gpt-5, such as openai/gpt-5.5, as a local run of 1.18.31 showed. Read which parameter or feature the error names. For max_tokens, add OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX with a smaller value under Basic → Agents → opencode → Environment variables, then reload the chat; opencode documents this experimental variable as its maximum output tokens. Router One's per-minute token limit also counts max_tokens when a request starts, so a lower value helps too if Agent Chat bursts return 429 TOKEN_QUOTA_EXCEEDED. For tool errors, choose a model whose page on /models lists tool calling. A message saying must be called via means the ID is not a chat model, for example an image-generation ID from the discovered list: every chat model in the catalog is served on /v1/chat/completions, the only path opencode's generic provider uses.

Which models can Copilot for Obsidian use through the gateway?

Choose a current catalog model that supports both the endpoint and the features Copilot for Obsidian 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?

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.