Custom Models (BYOK)

Connect your own API keys, use open source models, or run local models

The Droid CLI supports custom model configurations through BYOK (Bring Your Own Key). Use your own OpenAI or Anthropic keys, connect to any open source model providers, or run models locally on your hardware.

For Factory-managed models and multipliers, see Available Models. For org-level restrictions on custom models, base URLs, and provider access, see Enterprise Controls.

Note

Your API keys remain local and are not uploaded to Factory servers. Custom models are only available in the CLI and won't appear in Factory's web or mobile platforms.

Install the CLI with the 5-minute quickstart →

Configuration reference

Add custom models to ~/.factory/settings.json under the customModels array:

JSON
{
  "customModels": [
    {
      "model": "your-model-id",
      "displayName": "My Custom Model",
      "baseUrl": "https://api.provider.com/v1",
      "apiKey": "${PROVIDER_API_KEY}",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 16384
    }
  ]
}
Tip

In settings.json (and settings.local.json), apiKey supports environment variable references using ${VAR_NAME} syntax. For example, "apiKey": "${PROVIDER_API_KEY}" reads from the environment variable named PROVIDER_API_KEY (for example: export PROVIDER_API_KEY=your_key_here).

Note

Legacy support: Custom models in ~/.factory/config.json using snake_case field names (custom_models, base_url, etc.) are still supported for backwards compatibility. Both files are loaded and merged, with settings.json taking priority. Environment variable expansion for apiKey does not apply to legacy config.json.

Supported fields

modelstringrequired

Model identifier sent via API (e.g., claude-sonnet-4-5-20250929, gpt-5.3-codex, qwen3:4b).

displayNamestring

Human-friendly name shown in model selector.

baseUrlstringrequired

API endpoint base URL.

apiKeystringrequired

Your API key for the provider. Can't be empty. Supports environment variable references; see the Tip above.

providerstringrequired

Provider type that determines API compatibility. See the Understanding Providers section below.

maxOutputTokensnumber

Maximum output tokens for model responses.

noImageSupportboolean

Set to true to disable image inputs for this model.

extraArgsobject

Additional provider-specific arguments to include in API requests.

extraHeadersobject

Additional HTTP headers to send with requests.

bedrockobject

AWS Bedrock routing options (awsRegion, awsProfile, bedrockBaseUrl, awsAuthRefresh, awsCredentialExport). See AWS Bedrock.

Using extraArgs

Pass provider-specific parameters like temperature or top_p by adding an extraArgs object:

JSON
{
  "extraArgs": {
    "temperature": 0.7,
    "top_p": 0.9
  }
}

Using extraHeaders

Add custom HTTP headers to API requests by adding an extraHeaders object:

JSON
{
  "extraHeaders": {
    "X-Custom-Header": "value",
    "Authorization": "Bearer YOUR_TOKEN"
  }
}

AWS Bedrock

To route an Anthropic or OpenAI custom model through AWS Bedrock, add a bedrock object to the model config. Credentials are resolved through the standard AWS SDK provider chain (environment variables, shared config/credentials files, or an SSO/IAM profile).

JSON
{
  "customModels": [
    {
      "model": "anthropic.claude-sonnet-4-5-20250929-v1:0",
      "displayName": "Sonnet 4.5 [Bedrock]",
      "provider": "anthropic",
      "apiKey": "not-used-for-bedrock",
      "bedrock": {
        "awsRegion": "${AWS_REGION}",
        "awsProfile": "${AWS_PROFILE}"
      }
    }
  ]
}

Bedrock fields

FieldTypeDescription
awsRegionstringAWS region for Bedrock requests. Optional; when omitted, Droid falls back to the AWS default region chain. Supports ${VAR_NAME} interpolation.
awsProfilestringAWS profile name to resolve credentials and (as a last resort) a region. Supports ${VAR_NAME} interpolation.
bedrockBaseUrlstringExplicit Bedrock endpoint override. Accepts a full URL or a ${VAR_NAME} reference that expands to one.
awsAuthRefreshstringShell command run to refresh AWS credentials before requests.
awsCredentialExportstringShell command whose output exports AWS credentials into the request environment.

Environment variable interpolation

Like apiKey, the awsRegion, awsProfile, and bedrockBaseUrl fields support ${VAR_NAME} references in settings.json/settings.local.json, expanded per workspace at parse time. This lets a single centrally-distributed customModels config resolve to the correct value in each environment:

JSON
{
  "bedrock": {
    "awsRegion": "${AWS_REGION}"
  }
}

If a referenced variable is not set, Droid fails fast with a clear error naming the missing variable instead of sending the literal ${VAR_NAME} to AWS.

Note

awsAuthRefresh and awsCredentialExport are not expanded by the settings parser. They run through a shell, so ${VAR} in those commands is substituted by the shell at run time against the child process environment.

Region resolution

When awsRegion is omitted, Droid resolves the region using the AWS default chain, in order:

  1. 1
    AWS_REGION
  2. 2
    AWS_DEFAULT_REGION
  3. 3
    The region set on the resolved AWS profile in ~/.aws/config

If none of these supply a region, Droid fails fast with a clear error rather than silently defaulting, so requests never target a region the workspace did not choose (important for VPC-endpoint region affinity).

Understanding providers

Factory supports three provider types that determine API compatibility:

ProviderAPI FormatUse ForDocumentation
anthropicAnthropic Messages API (v1/messages)Anthropic models on their official API or compatible proxiesAnthropic Messages API
openaiOpenAI Responses APIOpenAI models on their official API or compatible proxies. Required for the newest models like GPT-5 and GPT-5-Codex.OpenAI Responses API
generic-chat-completion-apiOpenAI Chat Completions APIOpenRouter, Fireworks, Together AI, Ollama, vLLM, and most open-source providersOpenAI Chat Completions API
Warning

Factory is actively verifying Droid's performance on popular models, but we cannot guarantee that all custom models will work out of the box. Only Anthropic and OpenAI models accessed via their official APIs are fully tested and benchmarked.

Note

Model Size Consideration: Models below 30 billion parameters have shown significantly lower performance on agentic coding tasks. While these smaller models can be useful for experimentation and learning, they are generally not recommended for production coding work or complex software engineering tasks.

Provider reference

Every provider below works through the configuration above. Use provider: "generic-chat-completion-api" unless you are calling OpenAI's or Anthropic's official API.

ProviderbaseUrlExample model
OpenAI (official)https://api.openai.com/v1gpt-5.3-codex (set provider: "openai")
Anthropic (official)https://api.anthropic.comclaude-sonnet-4-5-20250929 (set provider: "anthropic")
OpenRouterhttps://openrouter.ai/api/v1openai/gpt-oss-20b
Fireworks AIhttps://api.fireworks.ai/inference/v1accounts/fireworks/models/deepseek-v3p1-terminus
DeepInfrahttps://api.deepinfra.com/v1/openaiQwen/Qwen3-Coder-480B-A35B-Instruct-Turbo
Groqhttps://api.groq.com/openai/v1moonshotai/kimi-k2-instruct-0905
Basetenhttps://inference.baseten.co/v1your deployed model ID
Hugging Facehttps://router.huggingface.co/v1openai/gpt-oss-120b:fireworks-ai
Google Geminihttps://generativelanguage.googleapis.com/v1beta/gemini-2.5-pro

Local models

Run models on your own hardware with an OpenAI-compatible server, then point baseUrl at it:

  • Ollama: set baseUrl to http://localhost:11434/v1 with any non-empty apiKey, and raise the context window to at least 32k (for example OLLAMA_CONTEXT_LENGTH=32000 ollama serve). Models with 30B+ parameters are recommended for agentic coding, and Ollama Cloud models work through the same endpoint.
  • LM Studio: set baseUrl to http://localhost:1234/v1, load an OpenAI-compatible model, and start its local server.

Prompt caching

The Droid CLI automatically uses prompt caching when available to reduce API costs:

  • Official providers (anthropic, openai): Factory attempts to use prompt caching via the official APIs. Caching behavior follows each provider's implementation and requirements.
  • Generic providers (generic-chat-completion-api): Prompt caching support varies by provider and cannot be guaranteed. Some providers may support caching, while others may not.

Verifying prompt caching

To check if prompt caching is working correctly with your custom model:

  1. 1
    Run a conversation with your custom model
  2. 2
    Use the /cost command in the Droid CLI to view cost breakdowns
  3. 3
    Look for cache hit rates and savings in the output

If you're not seeing expected caching savings, consult your provider's documentation about their prompt caching support and requirements.

Using custom models

Once configured, access your custom models in the CLI:

  1. 1
    Use the /model command
  2. 2
    Your custom models appear in a separate "Custom models" section below Factory-provided models
  3. 3
    Select any model to start using it

Custom models display with the name you set in displayName, making it easy to identify different providers and configurations.

Troubleshooting