One API Key Across Every Coding Tool You Use
Guides

One API Key Across Every Coding Tool You Use

Editor extension, terminal agent, CI job and a script all pointing at the same endpoint. The env var conventions, the per-tool quirks, and key hygiene that scales.

A realistic setup involves four or five tools that all talk to models: an editor extension, a terminal agent, something in CI, a scratch script, maybe a code review bot. Configured badly, that is five credentials in five formats, and nobody can answer the question "what is using our quota?"

Configured well, it is one key and one base URL, set once, read by everything. The reason this works is that nearly every tool in this space speaks the OpenAI chat-completions shape and reads the same two environment variables.

The two variables that do most of the work

The convention almost everything honours:

export OPENAI_API_KEY=cozy_your_key_here
export OPENAI_BASE_URL=https://api.cozyapi.com/v1

Any tool built on an official OpenAI SDK picks these up with no code change. That covers a large share of internal scripts and a surprising number of shipped products.

There is a second, older variable name — OPENAI_API_BASE — which some tools read instead. Aider is one, because it routes through LiteLLM. Setting both costs nothing:

export OPENAI_API_KEY=cozy_your_key_here
export OPENAI_BASE_URL=https://api.cozyapi.com/v1
export OPENAI_API_BASE=https://api.cozyapi.com/v1

A third family exists for tools that speak the Anthropic message shape rather than the OpenAI one. Those read ANTHROPIC_BASE_URL for the endpoint, and take credentials either through ANTHROPIC_API_KEY or through ANTHROPIC_AUTH_TOKEN, which sets the literal bearer token in the Authorization header. Which of the two your endpoint wants depends on whether it validates an x-api-key header or a bearer token — check the gateway documentation rather than guessing, since a wrong choice looks exactly like an invalid key.

The path rule that causes most 404s

The base URL should end at /v1, once. Nearly every SDK and tool appends /chat/completions itself. A base URL of https://api.example.com/v1/chat/completions produces a request to /v1/chat/completions/chat/completions, and the resulting 404 reads as "the endpoint is broken" rather than "the path is doubled".

The inverse also happens: a handful of tools want the host with no path at all and add /v1 themselves. If a correct-looking configuration 404s, try the URL with and without the suffix before investigating anything else.

Where each tool actually wants it

Environment variables cover terminal tools cleanly. GUI tools generally do not read your shell environment, because a desktop application launched from a dock icon inherits a different environment than your terminal does. Those need configuring in their own file or settings panel.

Roughly, the landscape splits three ways:

  • Environment only — scripts, SDK code, most CI jobs. Set the variables and you are done.
  • Config file — Aider reads .aider.conf.yml and a .env file from your home directory, git root or current directory. Continue reads ~/.continue/config.yaml or a workspace file under .continue/assistants/, where the model entry carries apiBase and apiKey directly.
  • Settings panel — editor extensions such as Cline and Roo Code, where you select an OpenAI-compatible provider and paste the base URL, key and model name into fields.

The middle category is the one worth investing in, because a config file can be committed, reviewed and shared. Keep credentials out of the committed file and in the per-developer one.

Model names are the part that does not transfer

A single endpoint gives you one credential, one URL and one place to look at usage. It does not give you a single model name that works everywhere, because each tool holds the model string separately — in a flag, a YAML key, or a text field.

Keep a short list somewhere your team can find it — a section in your README is enough — naming the aliases you use and what each is for. Something like: kimi-k3 and glm-5.2 for the main agent loop, deepseek-v4-pro for algorithmic work, qwen-3.5-coder or minimax-m2.7 for the cheap high-volume slots such as commit messages and autocomplete. Then a model change is a find-and-replace across four config files rather than an archaeology exercise.

Verify the alias against the endpoint before wiring it in. A single call to the models endpoint answers it:

curl https://api.cozyapi.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

Key hygiene when one key does everything

Consolidation has an obvious downside: one credential now unlocks every tool. Three habits contain that.

Keep it out of files that get committed. Put it in your shell profile or a .env that is in .gitignore — and confirm the ignore rule actually matches before you write the file, not after. A committed key is a rotated key.

Never paste it into a repository config that ships. The pattern that works is a committed workspace configuration carrying models, roles and rules, with the credential supplied per-developer from the global config or environment.

Rotate on a schedule you can actually keep. With one key and one URL, rotation is editing one line in a shell profile and one field per GUI tool. That is a five-minute job, which means it will happen. Five separate provider credentials means it will not.

For CI, use the platform's secret store and inject the variables at run time. Never bake a key into an image; images get pushed to registries with wider access than you think.

The debugging order

When one tool stops working and the others are fine, work in this order. It is quicker than reading the tool's issue tracker.

  1. Curl the endpoint with the same key and model string. If that fails, the problem is not the tool.
  2. Check for a doubled or missing /v1.
  3. Check the model string against the models endpoint. A 404 on an unknown alias is easy to mistake for a routing failure.
  4. Check whether the tool reads your environment at all. GUI applications usually do not. A variable set in your terminal is invisible to an editor launched from the dock.
  5. Check for a stale config file shadowing the new one. Several tools search multiple locations and take the last one found.

The payoff is that switching stays cheap

The real argument for this discipline is not tidiness. It is that model releases are frequent and providers change terms, and the cost of moving should be a config edit rather than a project.

If every tool you use points at one OpenAI-compatible base URL and holds its model name in a file rather than in someone's memory, then evaluating a new model is an afternoon: change the alias in four places, run your eval set, decide. That optionality is worth more over a year than any individual model choice you make today.

Common questions

Which environment variables should I set for maximum compatibility?

Set OPENAI_API_KEY plus both OPENAI_BASE_URL and OPENAI_API_BASE — different tools read different names and setting both is harmless. Add ANTHROPIC_BASE_URL and a matching credential variable if you also use tools that speak the Anthropic shape.

Why does my editor extension ignore the environment variable I set?

Desktop applications launched from a dock or start menu do not inherit your shell environment. Editor extensions generally need the base URL and key entered in their own settings panel or config file instead.

Is one key across every tool a security risk?

It concentrates exposure, but it also makes rotation cheap enough that it actually happens. Keep the key out of committed files, inject it from a secret store in CI, and rotate on a schedule — one key and one URL makes that a five-minute task.

Similar articles

Aider Setup Guide: Any OpenAI-Compatible Endpoint
Guides
Guides·8 min read

Aider Setup Guide: Any OpenAI-Compatible Endpoint

Configure Aider against a custom base URL — the openai/ prefix, .aider.conf.yml, model metadata for unknown models, and picking the right edit format.

Read
Cline Setup Guide: Pointing It at a Custom Endpoint
Guides
Guides·8 min read

Cline Setup Guide: Pointing It at a Custom Endpoint

Configure Cline against any OpenAI-compatible base URL — the provider fields, the model configuration block that people skip, and separate Plan and Act models.

Read
Continue.dev Setup: config.yaml for a Custom Endpoint
Guides
Guides·8 min read

Continue.dev Setup: config.yaml for a Custom Endpoint

Point Continue at any OpenAI-compatible base URL using config.yaml — model roles, apiBase, request options, and why the autocomplete slot needs its own model.

Read