Most tools start setup with a question you shouldn't have to answer: which provider are you using? You already know. More importantly, your key already knows. API keys aren't random strings: nearly every provider prefixes them with an identifiable marker.
So Vexi's onboarding is one step. Paste the key. It figures out the rest.
Prefixes are a de facto standard
Providers adopted key prefixes for their own reasons, mostly so that secret scanners can catch a leaked key in a public repo before it gets abused. GitHub's secret scanning depends on exactly this. The useful side effect is that a prefix is a reliable provider fingerprint.
Vexi matches the key against a pattern table, resolves a provider id, and looks up the right base URL:
openai https://api.openai.com/v1
anthropic https://api.anthropic.com/v1
groq https://api.groq.com/openai/v1
openrouter https://openrouter.ai/api/v1
gemini https://generativelanguage.googleapis.com/v1beta/openai
mistral https://api.mistral.ai/v1
cerebras https://api.cerebras.ai/v1
deepseek https://api.deepseek.com/v1
glm https://open.bigmodel.cn/api/paas/v4
qwen https://dashscope-intl.aliyuncs.com/compatible-mode/v1
moonshot https://api.moonshot.cn/v1
minimax https://api.minimax.chat/v1
Anthropic gets its own client because its Messages API isn't OpenAI-shaped. Everything else runs through a shared OpenAI-compatible client, which is why adding a provider is usually a one-line change rather than a new integration.
Keys arrive dirtier than you'd think
A detector that only handles clean input fails constantly in practice, because of how keys actually reach the terminal. People copy them out of web consoles, PDFs, Slack messages, and password managers. What lands on the clipboard often includes:
- Leading or trailing whitespace, and sometimes a trailing newline
- Zero-width characters and non-breaking spaces from rich-text copy
- Smart quotes wrapped around the key by a document editor
Any of these produce the same useless outcome: a 401 that looks like a bad key when the key is fine. Vexi strips non-ASCII characters and trims the input before matching. That fix shipped in 0.9.1 specifically because invisible characters were the single most confusing failure mode people hit.
Detection is a guess until it's verified
Pattern matching is a heuristic, not proof. Prefixes get reused, providers change formats, and a key can be perfectly well-formed but revoked, out of credit, or scoped to the wrong project.
So since 0.9.2, setup doesn't trust its own detection. Before writing config to disk, Vexi sends a real inference request to the resolved endpoint. If that request fails, nothing is saved and you see the actual provider error.
This matters more than it sounds. The alternative, save now and fail later, means your first real prompt dies on an error that looks like a bug in the tool, and you have no idea whether the problem is the key, the endpoint, the model name, or your network. Verifying at setup time collapses four possible failures into one clear message, at the moment you can still do something about it.
When there's no pattern to match
Local models and proxies have no meaningful key format at all; Ollama will accept nearly anything. For those, detection is the wrong tool, so vexi setup takes the endpoint URL directly, queries its /models list, and lets you pick from what's actually available rather than typing a model name from memory and hoping.