When you configure custom models in Continue, the key is both a pass and the boundary of cost and security. If keys are created casually, the common consequences are unexpected quota consumption, unclear per-member usage, and old keys still in use after someone has left.

In 2026, Continue was acquired by Cursor, the official repository is no longer actively maintained, and the hosted Hub and login service are offline. Key management therefore returns to local: one config.yaml, one .env, and several gateway keys split by person and purpose. This article covers creation, storage, multi-model use, rotation, policy, and troubleshooting.

Status note: In June 2026, Continue was acquired by Cursor. The official repository has been set to read-only and is no longer actively maintained; the hosted Hub and login service are offline. The extension and CLI still work, but there is no active maintenance, so security fixes need to be assessed on your own.

Trademark note: Continue is a trademark of Continue Dev, Inc.; Cursor is a trademark of Anysphere, Inc. This article is for technical explanation only, and we have no affiliation with or agency relationship with those companies. Product status and configuration fields are subject to the official pages and the currently installed version.

1. First, distinguish the kinds of keys in Continue

The phrase "Continue API Key" is often used loosely. In practice, there are at least three kinds of credentials, with completely different sources and purposes:

Type Issued by Purpose Still applicable
Gateway key Compatible services such as ZSQH AI Gateway Call multiple models through the OpenAI-compatible protocol Yes, the focus of this article
Vendor key OpenAI, Anthropic, Google, and others Connect directly to the corresponding vendor's official API Yes, with different fields and addresses
Local model No key, e.g. Ollama, LM Studio Inference on the local machine or intranet Yes, no secret involved
Continue account or Hub credential The former Continue platform Login, shared assistants, team configuration sync Offline with the Hub, no longer applicable

So "Continue API Key" usually means the model-side credential you put in the apiKey field, not a universal key issued by the editor. This article discusses gateway keys; they commonly start with sk-, but they cannot log in to Continue or call the original platform's APIs.

2. Create a gateway key: define boundaries before copying

Before creating one, be clear about who will use it, which project it belongs to, and how much it may consume at most.

  1. Open the ZSQH AI Gateway sign-up page, register, and sign in to the console.
  2. Go to "API Keys" and create a new key.
  3. Include the user and device in the name, for example continue-zhang-macbook; do not just write test.
  4. Set a spending cap and expiration time; if the console supports model scopes, limit the models available per project.
  5. Confirm the balance or top-up status, so you do not discover only after configuration that calls fail.
  6. Copy the key into a password manager; do not send it first through chat tools, tickets, or group chats.

One key per person and one key per device is recommended. A shared key looks convenient, but when unexpected consumption occurs you cannot trace it to a person, and after someone leaves it is hard to decide whether to disable it entirely. Models and prices change; use the model pricing page as the reference.

3. Put the key in .env, not config.yaml

Continue supports referencing secrets in config.yaml with Mustache syntax:

apiKey: ${{ secrets.ZSQH_API_KEY }}

Then define the variable value in a .env file:

# ~/.continue/.env
ZSQH_API_KEY=sk-your-gateway-key

A few details to note:

  • Do not wrap the value in the .env file in quotes; follow the official FAQ format of KEY=value.
  • Do not commit .env to Git; add it to .gitignore.
  • On macOS/Linux, you can run chmod 600 ~/.continue/.env to restrict file permissions.
  • Restart the IDE after changing .env, so the extension reads it again.
  • If config.yaml is committed to a repository, keep only the ${{ secrets.NAME }} placeholder and never write a plaintext key.

Writing the key into YAML also works, but once the configuration file is copied, screenshotted, or committed, the key spreads with it. With .env plus a placeholder, the configuration can be shared while the secret stays in the individual environment.

4. Multi-model configuration: one key for several roles

Continue's models is a list that can hold multiple model entries. Each entry has its own name, model, and roles, and they can reuse the same key:

name: zsqh-continue
version: 0.0.1
schema: v1

models:
  - name: Primary chat and edit
    provider: openai
    model: YOUR_MODEL_ID
    apiBase: https://ai.zhongshangqihang.com/v1
    apiKey: ${{ secrets.ZSQH_API_KEY }}
    roles: [chat, edit, apply]
    capabilities: [tool_use]

  - name: Autocomplete
    provider: openai
    model: YOUR_FIM_MODEL_ID
    apiBase: https://ai.zhongshangqihang.com/v1
    apiKey: ${{ secrets.ZSQH_AUTOCOMPLETE_KEY }}
    roles: [autocomplete]

The two ways of splitting keys serve different purposes:

  • One key for multiple models: suitable for individual developers, simple to manage, and keeps billing centralized.
  • Keys split by role: suitable for teams. Chat, autocomplete, and embeddings each use one key, so when quota looks abnormal you can quickly identify which kind of request caused it.

Splitting keys is not a hard requirement; it is a means of attributing cost. Small teams can start by splitting per person, then separate autocomplete once completion usage grows.

The autocomplete model must be one that supports FIM. Do not use a chat model for completion just because "it can also write code." If the gateway has no suitable FIM model, keep the gateway for chat, edit, and apply, and switch completion to a small local model.

5. Environment variables and secret resolution order

When Continue encounters ${{ secrets.X }}, it looks in the following order:

  1. The .env in the workspace root.
  2. The workspace .continue/.env.
  3. The global ~/.continue/.env.
  4. Process environment variables.

There are two pitfalls here.

First, IDE extensions usually cannot read variables you export in a terminal. The official FAQ states clearly that running export OPENAI_API_KEY=... in a shell does not make it visible to Continue in VS Code or JetBrains; process environment variables mainly work for Continue CLI. So "I already set it in the terminal" cannot be the conclusion of your troubleshooting; you still need to write .env.

Second, a workspace .env takes precedence over the global .env. When opening an untrusted repository, watch for a .env included in it; teams should add .env to ignore rules.

6. Rotation, revocation, and offboarding

A key should not be "created once and used forever." Rotate quarterly, and rotate immediately when a member changes role, a device is lost, or a leak is suspected:

  1. Create a new key in the gateway console with the same permissions and the same spending cap.
  2. Write the new key into the appropriate .env, and keep the old key for a while.
  3. Restart the IDE and verify Chat, Edit, and autocomplete separately.
  4. Confirm in the gateway log that the new key is producing normal requests.
  5. Observe for one to two days to confirm that no client was missed.
  6. Disable or delete the old key in the console.
  7. Record the rotation date, owner, and scope of impact.

If a key leak is suspected, reverse the order: disable first, investigate second. Do not keep using it while observing; unexpected consumption will not wait for your confirmation. After disabling, check request logs, usage curves, and model call records to confirm whether there were unexpected calls, then decide whether to adjust caps or alert rules.

When a member leaves, changes machines, or a project ends, disable the corresponding key the same day and remind the person to delete the local .env. Keys on shared devices should not be retained long term.

7. Key storage and team policy

  • Keep keys only in a password manager and .env; never in code, screenshots, tickets, chat history, or screen recordings.
  • One key per person, with spending caps and expiration set per project; create separate keys for shared service accounts and limit distribution.
  • Configuration templates can go into the repository, but keep only ${{ secrets.NAME }}; each member fills in values in their own .env.
  • Reconcile monthly: review consumption by key, model, and member; when something looks abnormal, disable first and investigate second.
  • Maintain a model and key mapping table for the team, stating the purpose, owner, cap, and rotation date.
  • Continue is no longer maintained, so do not rely on the plugin's own team features for key management; permissions, audit, and revocation all happen on the gateway side.
  • Gateway logs may contain request metadata. When sensitive code is involved, confirm the gateway's data retention and logging policy before deciding which projects may connect.

The key to a security policy is answering three questions: whose key is this, how much can it use, and how do we stop it if something goes wrong.

8. Troubleshooting: 401 and configuration not taking effect

When you hit a 401, check in this order:

  1. Does .env exist, and is the path ~/.continue/.env or a workspace .env?
  2. Does the variable name exactly match the ${{ secrets.NAME }} in config.yaml, including case?
  3. Are there spaces, quotes, or line breaks around the value? Copying from a chat window is the most likely way to bring hidden characters.
  4. Did you restart the IDE after changing .env?
  5. Is the key disabled or expired, and does the account have an available balance?
  6. Is config.yaml actually loaded, or is the older config.json still in effect?
  7. Does apiBase point to the environment the key belongs to? A test key configured against a production address can also return 401.

Other common symptoms:

  • 404: apiBase has an extra or missing /v1, or the model ID does not exist.
  • 429: quota, rate, or concurrency limit exceeded; read the error body and usage first, and do not retry blindly.
  • Autocomplete fails on its own: check whether the autocomplete model is an FIM model, and whether it uses a different key.
  • uses: fails to resolve: the Hub is offline; change remote references to inline provider, model, and apiKey.
  • The new model is not visible in the model selector: check YAML indentation, roles, and the reload state after saving.

Change only one variable at a time while troubleshooting. If you change the key, address, and model at the same time, you cannot tell what caused the recovery.

9. FAQ

Is Continue's API Key issued by a Continue account?

No. Continue itself does not issue universal model keys; what you enter is a credential issued by a model vendor or gateway. The former Continue platform's login and hosting services are offline, so it cannot serve as a key source either.

Why do I still get 401 in the IDE after exporting the key in a terminal?

Continue in VS Code and JetBrains usually cannot read shell environment variables. Put the key in ~/.continue/.env or a workspace .env, then restart the IDE. Process environment variables mainly work for the CLI.

Can the key be written directly in config.yaml?

It will run, but it is not recommended. Configuration files easily end up in repositories, copies, or screenshots. Prefer the ${{ secrets.NAME }} placeholder and keep the plaintext value in .env and a password manager.

Must different models use different keys?

Not necessarily. One key can call multiple models. The purpose of splitting keys is to separate ownership, quotas, and billing; it suits teams splitting by person, role, or project.

What is the first step after a key leak?

Disable the key in the gateway console first, then create a new key to replace it. After that, check usage and request logs to confirm the scope of unexpected calls, then decide whether to adjust caps, alert rules, or other credentials.

Next steps

First create a test key at the ZSQH AI Gateway, run through the sequence of "store in .env, reference from configuration, restart and verify", and then copy it into a team template. Model availability and current prices are subject to model pricing.

Related reading: