Skip to content
Yoink

One API key in every coding agent

To use one API key in several coding agents, add it to yoink once with yoink add, then run yoink connect <name> --to pi,opencode,codex for the agents you use. yoink writes the key, base URL and models into each agent's own config file, and yoink edit re-syncs all of them when the key or the model list changes.

On this page

The short answer

echo "$OPENAI_API_KEY" | yoink add --external --name openai-api --preset openai \
  --models gpt-5.2,gpt-5.2-codex --connect pi,codex --default gpt-5.2-codex --token-stdin
yoink connect openai-api --to qwen,kilo,crush,continue
yoink status openai-api

The first command saves the provider and connects it to pi and codex in one go. The second adds four more agents. The profile id is openai-api rather than openai because Codex reserves openai for its built-in provider and ignores a config table with that id; the codex page explains the clash. yoink status openai-api prints one line per harness: connected (with its default model), available, incompatible, or not installed, plus the config path. In an interactive terminal, yoink add and a bare yoink connect openai-api show the same choices as a checklist.

Why each agent wants its own config

Every coding agent reads providers from its own file, in its own shape. pi wants ~/.pi/agent/models.json with a models array and context limits per model. opencode and Kilo Code want an @ai-sdk package name and an options.baseURL in JSON or JSONC. codex wants a [model_providers.<id>] TOML table with wire_api = "responses". omp and Continue use YAML, Qwen Code keeps the key in an env block, and Claude Code takes seven ANTHROPIC_* env keys. Pasting one key into 13 formats by hand works once; keeping them in step after a key rotation is the part that breaks. The harness table lists every path and format yoink writes, and each harness has its own page with the exact entry yoink adds:

Which provider reaches which agent

A key is only as portable as the protocols its provider speaks. Each harness takes the first protocol in its own preference order that the provider offers:

HarnessPreference orderPresets that reach it
pi, omp, Qwen Code, Zedopenai-chat, openai-responses, anthropic-messagesall 7
opencode, Kilo Codeopenai-chat, anthropic-messages, openai-responsesall 7
Droidanthropic-messages, openai-responses, openai-chatall 7
Crush, Goose, Continueopenai-chat, anthropic-messagesall 7
codexopenai-responses onlyopenai
Claude Code, Claude Desktopanthropic-messages onlykimi-code, moonshot, openrouter, deepseek, zai

Counted per preset, openai reaches 11 harnesses, the five dual-endpoint presets reach 12 (all but codex), and ollama reaches 10 (not codex, Claude Code or Claude Desktop). No preset reaches all 13. A custom endpoint can, but only if its probe finds both a /responses route and a /v1/messages route. The order matters in practice: Droid gets the Anthropic URL of a dual-endpoint preset, while pi and Crush get its Chat URL.

Rotate a key or change models once

echo "$NEW_OPENAI_API_KEY" | yoink edit openai-api --token-stdin
yoink models openai-api --set gpt-5.2,gpt-5.2-codex
yoink rename openai-api work-openai

Each of these saves the change and re-writes the provider into every harness it is connected to. A harness default model survives as long as that model is still selected. A rename removes the old entry from each harness before writing the new one, so you never end up with both. After a key rotation, yoink also scrubs the retired key out of any <file>.yoink.bak backup it touched during that re-sync, so the old key does not linger on disk next to the new one.

Each harness also keeps its own default. yoink connect openai-api --to codex --default gpt-5.2-codex and yoink connect openai-api --to pi --default gpt-5.2 can coexist; yoink records the default per harness and keeps it through every re-sync.

Native config, not a proxy

yoink runs only when you call it. It writes files and exits, so nothing sits between an agent and the provider: requests go straight from the agent to the provider's own URL, and an agent keeps working if yoink is uninstalled. That is the main difference from an AI gateway or a routing proxy, which give every agent one local endpoint and forward the traffic. A gateway can do things yoink cannot, such as routing rules or fallback between providers. yoink's trade is no extra process and no extra hop. The switcher comparison covers the account-switching side of this space.

Disconnect cleanly

yoink disconnect openai-api --from crush
yoink remove openai-api

yoink disconnect deletes yoink's entry from the named harnesses and clears any default that pointed at it. yoink remove disconnects the provider from every harness first and deletes the profile only when every one of those updates succeeds. If one fails, for example because a config no longer parses, yoink keeps the profile, names the failing harness and tells you to run yoink remove again once it is fixed. Nothing is left half-removed.

FAQ

Do I have to restart my agents after a change?

Yes, for any agent that is already running. yoink writes the config file, and most agents read it at start. A new session picks up the new key or model.

What happens if one harness fails during a connect?

The other harnesses still get the provider. yoink prints a line per harness, marks the one that failed with its reason, and exits non-zero so a script notices. A common case is a config file tracked by git, which yoink refuses to write a key into unless you pass --allow-tracked.

Can I bring in keys I already pasted into my agents?

Yes. yoink import reads the configs you set up by hand and turns each literal key into a provider yoink manages. See Import the providers you already configured.

  • Harnesses

    What yoink writes into pi, omp, opencode, codex, Claude Code, Qwen Code, Kilo, Droid, Crush, Continue, Goose, Zed and Claude Desktop: paths and keys.

  • Providers

    Add an API key once with yoink, from a preset (OpenAI, Kimi, OpenRouter, DeepSeek, z.ai, Ollama) or any compatible URL it probes, and pick its models.

  • Claude Code account switchers compared

    An honest comparison of claude-swap, clauth, swapdex, Claude Switcher, CCSwitcher and yoink: platforms, other tools, usage display, auto-switch, license.

  • Switch between Claude Code accounts

    Keep a work and a personal Claude Code account and switch in one command. yoink swaps the Keychain entry or .credentials.json and the oauthAccount block.

  • Switch between Codex (ChatGPT) accounts

    Save several ChatGPT logins for Codex and switch between them. yoink swaps auth.json or the Codex Auth Keychain entry and re-saves the live login first.

  • Switch between Gemini CLI accounts

    Save more than one Google login for Gemini CLI and switch between them. yoink swaps oauth_creds.json and google_accounts.json and refuses encrypted storage.