Bring your own endpoint: custom providers

In short

A custom provider connects Granular to an AI endpoint you choose, using a base URL and your own API key. Stack up to 20 models behind one connection and switch between them per message. It is part of the app on every plan — you pay your provider directly, and nothing is added to your Granular bill.

Updated 2026-08-24

What a custom provider is

Granular has three ways to put a model behind your sessions. You can sign in with an account you already pay for (Claude, Codex, Gemini). You can subscribe to Granular Hosted and let Granular run the model connection for you. Or you can go fully manual: bring your own endpoint.

A custom provider is exactly that third lane. You tell Granular where your provider lives (a base URL), prove you are allowed to use it (an API key), and name the model or models you want. From then on those models appear in the model picker alongside everything else, selectable per message.

  • It is the maximum-control option. Your provider, your account, your rates, your data agreement.
  • It is direct. A custom-provider turn goes from your Mac straight to your endpoint. Granular's servers are not in the path.
  • It is free on every plan. Your provider bills you; Granular does not meter it and spends no credits on it.

What works today

The custom lane speaks Anthropic's Messages format. That means your endpoint must serve /v1/messages — Granular appends that path to your base URL itself.

In practice, three kinds of endpoint fit:

  • OpenRouter — the big aggregator serves the Messages format, so one OpenRouter key opens hundreds of models: GPT, Gemini, DeepSeek, Kimi, Qwen and more. This is the proven, recommended recipe — see below.
  • Any provider that offers an Anthropic-compatible API — a growing number do, precisely because so many tools speak it.
  • A local translator — if your provider (or your local model server) only speaks the OpenAI-style API, run a translator such as LiteLLM on your machine and point Granular at it. Connections require https, with one deliberate exception: localhost is allowed, exactly for setups like this.

One known trap, caught for you: Google's native Gemini endpoint does not serve the Messages format. If you try it, the form says so and names the two working routes — OpenRouter's google/… model ids, or Granular's built-in Gemini connection.

Adding one

Open the model picker under the prompt, choose Add your AI agent → Add custom provider, and fill in four things:

Granular's accounts menu listing Claude, Gemini, Codex, OpenRouter and a hosted account, with Add your AI agent open on Add custom provider asking for a base URL and API key

  • A name — whatever you want to see in the picker.
  • The base URL — as your provider documents it, minus any trailing /v1. Granular adds /v1/messages itself, and the form quietly strips a trailing /v1 so the two of you do not add it twice.
  • Your API key — stored encrypted on your Mac, never in a plain-text file, and sent only to this endpoint.
  • One or more model ids — exactly as your provider names them.

When you save, Granular does something most tools skip: it runs a real test turn — the cheapest one possible — against your endpoint. A wrong URL, a bad key or a mistyped model id fails right there, with the likely causes named, instead of twenty minutes into a task. A green check means the connection genuinely works.

Stacking several models on one connection

The model field takes more than one id — separate them with commas or spaces, up to 20. The whole stack then lives behind a single connection:

  • The first id is the default — it is what runs when you have not picked anything.
  • The composer shows the full stack, and you can switch the model per message, the same way you would with hosted models.
  • One key, one entry, many models. Editing the connection updates every session that uses it.

One honest caveat: the save-time test proves the first model in the stack. The others share the same URL and key, so they almost always work too — but a typo in a second id will only surface the first time you actually run it.

The OpenRouter recipe

The configuration that has been proven end to end, and the fastest way to get many models behind one key:

  • Base URL: https://openrouter.ai/api
  • API key: your OpenRouter key
  • Models: OpenRouter ids carry the author prefix — for example anthropic/claude-sonnet-4.5, google/gemini-2.5-pro, deepseek/deepseek-chat-v3.1

Save, watch the green check, and the whole stack appears in your picker. You pay OpenRouter at OpenRouter's rates, on your own account.

Custom provider or Granular Hosted?

They are the two ends of the same trade, and they coexist happily:

  • Custom provider is control. Your account, your rates, your provider relationship — and a little setup: getting a key, choosing model ids, topping up with your provider.
  • Granular Hosted is convenience. No keys, no accounts, 19 curated models on one bill — and Granular takes a margin for running it.

Nothing forces a choice. The model picker is per-message, so a hosted default with a custom endpoint for special jobs — or the reverse — is a perfectly normal setup. And if hosted credits ever run out, a custom provider is one of the doors that keeps you working.

Frequently asked questions

Does my provider need to support Anthropic's API format?
Yes. Today the custom lane speaks Anthropic's Messages format, so your endpoint must serve /v1/messages. OpenRouter does, and through it you can reach GPT, Gemini, DeepSeek and many more with one key. If your provider only offers an OpenAI-style API, run a local translator such as LiteLLM and connect Granular to it on localhost.
Does a custom provider cost anything on my Granular bill?
No. Custom providers are part of the app on every plan, including Free. Usage is billed by your provider on your own account — nothing is added to your Granular bill and no Granular credits are spent.
Where is my API key stored?
Encrypted on your Mac, never in a plain-text file. It is sent only to the endpoint you configured, as part of making your requests — Granular's servers are not involved in a custom-provider turn.
Can I use a local model like Ollama?
Not directly yet, because local servers speak the OpenAI chat-completions format. The working route today is a local translator such as LiteLLM: point it at your local model, then connect Granular to the translator on localhost, which is explicitly allowed.
What happens if I enter a wrong URL, key or model id?
Saving the connection runs a real, cheapest-possible test turn against your endpoint. A bad URL, key or model id fails right there, with the likely causes named — not twenty minutes into a task.

Related