Providers & BYOK
The five built-in providers, custom OpenAI-compatible endpoints, the priced model catalog, and how your API keys are stored.
Cordy for Mobile never proxies your traffic. You bring an API key, Cordy talks directly to that provider from your device, and your key is stored in secure device storage — never in the conversation database or logs. This page covers every provider option and how the model catalog and key storage work.
The BYOK principle
- You own the account. Keys come from the provider's console; you pay the provider directly.
- One key per provider. Each provider stores its own independent key. Switching providers switches keys.
- Direct requests. Prompts go to the selected provider as an HTTPS call carrying your key as the
Authorizationheader. Nothing is routed through Cordy.
Built-in providers
Cordy ships with five built-in provider presets. OpenRouter is selected by default.
| Provider | API family | Base URL | Notes |
|---|---|---|---|
| OpenRouter (default) | OpenAI-compatible | https://openrouter.ai/api/v1 | One key, 100+ models; catalog includes live pricing |
| OpenAI | OpenAI-compatible | https://api.openai.com/v1 | First-party OpenAI models |
| Anthropic | Anthropic (native) | https://api.anthropic.com | Native API with extended thinking |
| Vercel AI Gateway | OpenAI-compatible | https://ai-gateway.vercel.sh/v1 | Routes to models behind your Vercel gateway |
| Volcengine Ark (火山方舟) | OpenAI-compatible | https://ark.cn-beijing.volces.com/api/v3 | Volcengine's model service |
OpenRouter
The default and the easiest first key. OpenRouter is an OpenAI-compatible aggregator: a single key reaches models from many vendors. Its /models response includes pricing, so Cordy shows real per-model costs. Model IDs use a vendor/model form, for example anthropic/claude-sonnet-4-5.
OpenAI
First-party access to OpenAI's models via api.openai.com/v1. Model IDs are plain names (for example gpt-4o). Pricing for OpenAI models is resolved from the bundled LiteLLM snapshot when the /models response doesn't include it.
Anthropic (native)
Anthropic uses Cordy's native Anthropic client rather than the OpenAI-compatible path. This is what enables extended thinking with a configurable thinking budget. Because it's the native API (not an OpenAI-style /models endpoint), Anthropic's model entry is built in rather than fetched live.
Vercel AI Gateway
An OpenAI-compatible gateway; point Cordy at it with a Vercel AI Gateway key and reach whatever models your gateway exposes.
Volcengine Ark (火山方舟)
Volcengine's OpenAI-compatible model service (ark.cn-beijing.volces.com/api/v3). Use an Ark API key.
Enabling and disabling providers
Under Settings → Availability, you can toggle any provider on or off. A disabled provider is hidden from the chat model picker until you re-enable it. This is handy for keeping the picker focused on the providers you actually use.
Custom OpenAI-compatible endpoints
Beyond the built-ins, you can add your own OpenAI-compatible endpoint — a self-hosted model server, an in-house gateway, or another vendor that speaks the OpenAI API.
To add one: Settings → Custom provider → enter a Name and a Base URL (the field hints "Base URL (ends with /v1)") → Add provider. It then behaves like any built-in: save a key, load its catalog, and select its models. Custom providers carry a Custom badge and are the only providers you can delete.
Base-URL rules
The URL is parsed and validated before the endpoint is saved, so a malformed or plaintext URL can't quietly send your key to the wrong host:
- It must be a valid
http(s)URL with a host. - HTTPS is required for public hosts — your key is never sent in the clear.
- Plain
http://is allowed only for loopback / private-LAN development hosts. - Embedded credentials (
user:secret@host) are rejected. - A trailing slash is trimmed; the normalized URL is what's stored.
Allowed plaintext (http://) hosts, for local development:
| Host pattern | Example |
|---|---|
localhost | http://localhost:11434/v1 |
127.0.0.1 / 0.0.0.0 | http://127.0.0.1:1234/v1 |
10.x.x.x | http://10.0.0.5:8000/v1 |
192.168.x.x | http://192.168.1.20:8080/v1 |
172.16.x.x–172.31.x.x | http://172.16.0.10:8000/v1 |
*.local | http://my-box.local:8000/v1 |
Any other host must use https://. This lets you point Cordy at a model server on your own machine or LAN while keeping every cloud endpoint encrypted.
The model catalog
When a provider has a saved key, Cordy fetches and caches its model list:
- Fetch. For OpenAI-compatible providers, Cordy calls
GET {baseUrl}/modelswith your key and maps each model's context window, capabilities, and pricing. Anthropic (native) uses its built-in entry instead. - Capabilities. Each model is tagged from the response (and a bundled LiteLLM snapshot when the response is sparse) with Vision, Thinking / reasoning, Tool use, and Long context (context window ≥ 100k). These tags drive the UI — for example, image send is only allowed on Vision models, and the thinking-budget control only appears on Thinking models.
- Caching. The fetched catalog is cached on device, so the list is instant next launch and available offline. Use Refresh models to re-fetch.
- No key yet. Before you save a key, Cordy shows whatever is cached (or a small bootstrap list) without hitting the network.
Pricing
Prices are normalized to USD per 1,000,000 tokens and resolved in this order:
- Provider-native — pricing carried in the provider's
/modelsresponse (OpenRouter provides this). - LiteLLM snapshot — a bundled price table, looked up by normalized model-ID variants (tolerating vendor prefixes and OpenRouter suffixes).
- Unknown — the model shows
—/ "Price unknown".
Cordy displays these as "In $… / Out $… per 1M" in the model list, and records cost per response on the usage page. Treat in-app costs as estimates and reconcile against your provider's own billing.
Model ID formats
- OpenRouter:
vendor/model(for exampleanthropic/claude-sonnet-4-5). - OpenAI / Vercel / Ark / custom: the provider's own model names.
- Anthropic native: Anthropic model IDs (for example
claude-sonnet-4-5-20251022).
How your keys are stored
API keys are held only in platform secure storage, scoped per provider:
- Android — a Keystore-held AES-256-GCM key encrypts each value, stored as Base64(IV ‖ ciphertext ‖ GCM tag) in a private preferences file. Values written by the older
EncryptedSharedPreferencesare transparently migrated to the new scheme on first read, so no key is lost across an app upgrade. - iOS — the Keychain, with
AfterFirstUnlockThisDeviceOnlyaccessibility: device-bound and excluded from iCloud Keychain and encrypted backups.
Keys are never written to the conversation database, never logged, and never leave the device except as the Authorization header on the request to the provider you chose. Saving a blank key is treated as deleting it. For the complete data-handling story, see Privacy & security.
Not yet available
- Tool / function calling is modeled in the message format (the app can render tool-use and tool-result blocks) but is not executed in this release.
- Automatic multi-provider gateway / fallback routing is future work.
Today, each conversation talks to exactly one provider and one model.