Skip to main content
Copilot API reads its settings from a single JSON file on startup. You can use this file to control authentication, model routing, upstream providers, and logging without touching command-line flags.

File location

PlatformDefault path
Linux / macOS~/.local/share/copilot-api/config.json
Windows%USERPROFILE%\.local\share\copilot-api\config.json
To use a different directory, set the COPILOT_API_HOME environment variable or pass --api-home=<path> before your subcommand:
npx @nick3/copilot-api@latest --api-home=/opt/copilot-data start

Default config shape

If the file does not exist, Copilot API creates it automatically with the following defaults:
{
  "auth": {
    "apiKeys": []
  },
  "providers": {},
  "extraPrompts": {
    "gpt-5-mini": "<built-in exploration prompt>",
    "gpt-5.3-codex": "<built-in commentary prompt>",
    "gpt-5.4-mini": "<built-in commentary prompt>",
    "gpt-5.4": "<built-in commentary prompt>"
  },
  "smallModel": "gpt-5-mini",
  "accountAffinity": true,
  "responsesApiContextManagementModels": [],
  "modelReasoningEfforts": {
    "gpt-5-mini": "low",
    "gpt-5.3-codex": "xhigh",
    "gpt-5.4-mini": "xhigh",
    "gpt-5.4": "xhigh"
  },
  "allowOriginalModelNamesForAliases": false,
  "useFunctionApplyPatch": true,
  "forceAgent": false,
  "compactUseSmallModel": true,
  "messageStartInputTokensFallback": false,
  "modelRefreshIntervalHours": 24,
  "sessionAffinityRetentionDays": 7,
  "useMessagesApi": true,
  "useResponsesApiWebSearch": true,
  "logLevel": "info"
}
Missing default entries (extra prompts, reasoning efforts) are merged back automatically each time the server starts, without overwriting values you have customized.

Configuration options

An array of strings. Requests to protected routes must include one of these keys as x-api-key: <key> or Authorization: Bearer <key>. Supports multiple keys so you can rotate credentials without downtime.
{
  "auth": {
    "apiKeys": ["key-abc123", "key-def456"]
  }
}
If the array is empty or the field is omitted, authentication is disabled and all requests are accepted.
The legacy apiKey top-level field and COPILOT_API_KEY environment variable are still accepted for migration but are deprecated. Prefer auth.apiKeys for new setups.
A map of model → prompt string. The prompt is appended to the first system message when the proxy translates an Anthropic-style request for Copilot. Use this to inject per-model guardrails, coding style rules, or behavioral guidance.
{
  "extraPrompts": {
    "gpt-5.4": "Always respond in English.",
    "gpt-5-mini": "Be concise."
  }
}
The built-in prompts for gpt-5.3-codex, gpt-5.4-mini, and gpt-5.4 enable phase-aware commentary (short progress updates before tools or deeper reasoning). If you supply your own entry for one of these models, it replaces the built-in prompt for that model only.
The model used for tool-less warmup probes, compact/background requests, and other housekeeping turns so they do not consume premium quota. Defaults to "gpt-5-mini".
{
  "smallModel": "gpt-5-mini"
}
If the value points to an aliased target and original names are blocked, the proxy resolves it to the preferred alias automatically.
When true (default), requests from the same session for the same model are routed back to the account that last handled them successfully. This applies to both free and premium models and helps preserve context continuity across turns.
{
  "accountAffinity": false
}
Set to false to use sequential routing for all models instead. See Manage multiple Copilot accounts for more detail.
A map of model → effort level. Controls the reasoning.effort parameter forwarded to the Copilot Responses API. Allowed values: "none", "minimal", "low", "medium", "high", "xhigh". Models not listed default to "high".
{
  "modelReasoningEfforts": {
    "gpt-5.4": "xhigh",
    "gpt-5-mini": "low"
  }
}
A map of alias → { target, allowOriginal? } that lets downstream clients use custom model names. Alias keys are normalized (trimmed, lowercased). The optional allowOriginal field overrides the global allowOriginalModelNamesForAliases default for that specific alias.
{
  "modelAliases": {
    "fast": { "target": "gpt-5-mini" },
    "smart": { "target": "gpt-5.4", "allowOriginal": true }
  }
}
  • Aliases cannot map to themselves (case-insensitive).
  • Conflicting normalized aliases are rejected.
  • Reserved keys (__proto__, constructor, prototype) are blocked by the Admin API.
Global default for whether aliased target model names can be called directly. When false (default), a client requesting gpt-5.4 is rejected if that model is an alias target and no alias explicitly sets allowOriginal: true. When true, targets are reachable by their original names unless all their aliases explicitly block them.
{
  "allowOriginalModelNamesForAliases": false
}
A list of model IDs that should receive Responses API context_management compaction instructions. When a model in this list is used, the proxy keeps only the latest compaction carrier on follow-up turns, reducing unnecessary context re-sending.
{
  "responsesApiContextManagementModels": ["gpt-5.4", "gpt-5.4-mini"]
}
When true (default), POST /v1/responses automatically converts a tools entry with { "type": "custom", "name": "apply_patch" } into an OpenAI-style function tool with a parameter schema, for upstream compatibility. Set to false to leave custom tools unchanged.
{
  "useFunctionApplyPatch": false
}
When true (default), detected compact requests (from Claude Code or opencode compact mode) are routed to smallModel automatically, avoiding premium usage for short background tasks.
{
  "compactUseSmallModel": false
}
When true (default), Claude-family models that support Copilot’s native /v1/messages endpoint use the Messages API path. This preserves Anthropic-native behavior including interleaved-thinking, advanced-tool-use, and context-management betas. Set to false to skip the Messages API path and fall back to /responses or /chat/completions.
{
  "useMessagesApi": false
}
When true (default), POST /v1/responses keeps tools with type: "web_search" and forwards them upstream. Set to false to strip web search tools before the Copilot request is sent.
{
  "useResponsesApiWebSearch": false
}
Controls verbosity for handler file logs written to logs/*.log. Allowed values: "error", "warn", "info" (default), "debug". Use "debug" when you need payload-level or stream-level diagnostics.
{
  "logLevel": "debug"
}
--verbose no longer enables debug-level file logging. Set "logLevel": "debug" explicitly in config.json when you need detailed handler logs.
An optional Anthropic API key used to forward Claude token counting requests to Anthropic’s real /v1/messages/count_tokens endpoint instead of using GPT tokenizer estimation. This produces exact counts, which prevents tools like Claude Code from compacting too late.
{
  "anthropicApiKey": "sk-ant-..."
}
You can also set this via the ANTHROPIC_API_KEY environment variable. The token counting endpoint is free; the $5 minimum balance is only required to activate API access.
The interval, in hours, at which the proxy refreshes the model list for each account in the background. Set to 0 to disable refresh entirely. Defaults to 24.
{
  "modelRefreshIntervalHours": 12
}
Number of days to retain session affinity bindings before they are cleaned up. Defaults to 7.
{
  "sessionAffinityRetentionDays": 14
}
A map of named upstream providers. Each key becomes a route prefix. See Custom providers below for full details.

Custom providers

The providers field lets you proxy requests to external Anthropic-compatible APIs through Copilot API. Each key you define (for example "custom") becomes a URL prefix:
  • POST /custom/v1/messages
  • GET /custom/v1/models
  • POST /custom/v1/messages/count_tokens
Only type: "anthropic" is supported currently.

Provider fields

FieldRequiredDescription
typeNoProvider type. Only "anthropic" is supported. Defaults to "anthropic".
enabledNoSet to false to disable the provider without removing it. Defaults to true.
baseUrlYesBase URL of the upstream API, without a trailing /v1/messages.
apiKeyYesCredential forwarded upstream.
authTypeNoHow apiKey is sent. "x-api-key" (default) sends an x-api-key header; "authorization" sends Authorization: Bearer <apiKey>.
adjustInputTokensNoWhen true, subtracts cache_read_input_tokens and cache_creation_input_tokens from input_tokens in the usage response.
modelsNoPer-model defaults. Each key is a model ID; value supports temperature, topP, and topK. These are applied when the request does not specify them.

Example

{
  "providers": {
    "custom": {
      "type": "anthropic",
      "enabled": true,
      "baseUrl": "https://your-provider.example",
      "apiKey": "sk-your-provider-key",
      "authType": "x-api-key",
      "adjustInputTokens": false,
      "models": {
        "kimi-k2.5": {
          "temperature": 1,
          "topP": 0.95
        }
      }
    }
  }
}
With this config, you can call the provider at http://localhost:4141/custom/v1/messages.

Applying config changes

Changes you make through the Admin UI or Admin API are validated, written to disk, and applied immediately — no restart needed. If you edit config.json manually in a text editor, restart the server to pick up the changes. Alternatively, the Admin API’s GET /api/admin/config endpoint refreshes the cached config without a full restart:
curl http://localhost:4141/api/admin/config
Unknown keys in config.json are rejected by the Admin API. If you add a field through the UI, the change is validated before being written.