Factory Droid Custom Models: Use Claude and GPT With Your Own API Key
One settings.json gave Droid 1.0.0 Claude Sonnet 5.5, GPT-6.1 Terra and MiniMax M3.1 Flash on one key. Here is the file, the provider for each, and the four errors we hit.
On this page
- Short answer
- Which provider value should you use?
- The settings.json we used
- How do you pick a custom model in Droid?
- Three models on the same bug
- Do you need a Factory account or plan?
- Which errors will you hit, and what fixes them?
- FAQ
- Where is the Droid settings file on Windows?
- Why doesn't my custom model show up in /model?
- Can custom models read images?
- Can I set reasoning effort for a custom model?
- Do custom models work in the Droid desktop app?
- Sources checked
Add each model to customModels in ~/.factory/settings.json with model, baseUrl, apiKey and provider: use anthropic for Claude with a bare host, openai for GPT, and generic-chat-completion-api for everything else. On Droid 1.0.0, Claude Sonnet 5.5, GPT-6.1 Terra and MiniMax M3.1 Flash each fixed the same bug in 33.7, 77.4 and 30.7 seconds.
All three runs went through OmniaKey on one key, which is how we reached Claude Sonnet 5.5, GPT-6.1 Terra and MiniMax M3.1 Flash. Each got the same broken median() function and fixed it.
Short answer
- Where it goes.
customModelsin~/.factory/settings.json(Factory's settings docs, checked October 30, 2026), withmodel,baseUrl,apiKeyandprovider. - Which provider.
anthropicfor Claude,openaifor GPT models,generic-chat-completion-apifor everything else that speaks Chat Completions. - Where
/v1goes.anthropictakes the bare host, because Droid adds/v1/messages;openaiandgeneric-chat-completion-apitake a URL ending in/v1. - The id for
droid exec.custom:, the display name with spaces as dashes, then the 0-based position:custom:Claude-Sonnet-5.5-[OmniaKey]-0. - What our runs showed. All three fixed the bug; 30.7 s for Flash, 33.7 s for Claude, 77.4 s for GPT-6.1 Terra.
Which provider value should you use?
Pick the provider by the API your endpoint speaks, not by the model name.
anthropicsends Anthropic Messages API requests. Use it for Claude; Anthropic's base URL ishttps://api.anthropic.com.openaisends OpenAI Responses API requests. Use it for GPT models; OpenAI's base URL ishttps://api.openai.com/v1.generic-chat-completion-apisends OpenAI Chat Completions requests. Use it for most other models, gateways and local servers, with the provider's own/v1URL.
Factory lists generic-chat-completion-api for OpenRouter, Fireworks, Together AI, Ollama, vLLM and most open-source providers, and advises it unless you are calling OpenAI's or Anthropic's official API (Factory's BYOK docs, checked October 30, 2026).
A gateway that also speaks the Messages API or the Responses API can use anthropic or openai. Our Claude and GPT-6.1 Terra entries did, through OmniaKey, and both ran; OmniaKey serves GPT models on POST /v1/responses (OmniaKey's OpenAI-compatible docs, checked October 30, 2026).
A fourth value, bedrock-converse, is for models on AWS Bedrock's Converse API. Factory warns that only Anthropic and OpenAI models on their official APIs are fully tested and benchmarked, and that models below 30 billion parameters do significantly worse on agentic coding (Factory's BYOK docs, checked October 30, 2026).
The settings.json we used
Droid creates ~/.factory/settings.json on first run, so add customModels to the file already there (Factory's settings docs, checked October 30, 2026). Here is ours:
{
"customModels": [
{
"model": "claude-sonnet-5-5",
"displayName": "Claude Sonnet 5.5 [OmniaKey]",
"baseUrl": "https://api.omniakey.com",
"apiKey": "${OMNIAKEY_API_KEY}",
"provider": "anthropic",
"maxOutputTokens": 16000
},
{
"model": "gpt-6.1-terra",
"displayName": "GPT-6.1 Terra [OmniaKey]",
"baseUrl": "https://api.omniakey.com/v1",
"apiKey": "${OMNIAKEY_API_KEY}",
"provider": "openai",
"maxOutputTokens": 16000
},
{
"model": "minimax-m3.1-flash",
"displayName": "MiniMax M3.1 Flash [OmniaKey]",
"baseUrl": "https://api.omniakey.com/v1",
"apiKey": "${OMNIAKEY_API_KEY}",
"provider": "generic-chat-completion-api",
"maxOutputTokens": 16000
}
]
}
modelis the id sent to the API; copy it from the provider's model list.displayNameis your own label: it shows in/modeland builds thecustom:id.baseUrlis the bare host foranthropic, and ends in/v1for the other two.apiKey: "${OMNIAKEY_API_KEY}"reads the key from an environment variable, so it stays out of the file (Factory's BYOK docs, checked October 30, 2026).providerpicks the API; a typo here gives the "Invalid provider" error below.maxOutputTokens: 16000caps the length of each answer.
One key and two base URLs cover all three models: OmniaKey's bare host for Claude, its /v1 host for the other two. If you followed OmniaKey's coding-agent setup docs, the same key works here.
Factory says keys remain local and are not uploaded to Factory servers (Factory's BYOK docs, checked October 30, 2026). Older guides put models in ~/.factory/config.json. Factory's BYOK docs still say Droid copies them into settings.json at startup. A pull request in Factory's GitHub repository (#76) says a code change merged on October 15, 2026 removed that copy, so put new models straight into settings.json.
How do you pick a custom model in Droid?
In the app, open /model and look under Custom Models; on the command line, pass a custom: id to droid exec.
Factory's docs say saved models appear there labeled with their displayName, and you can also add one from /settings > Custom models or /model > Manage custom models (checked October 30, 2026).
The droid exec id is custom:, then the display name with spaces turned into dashes, then a dash and the model's 0-based position in customModels (Factory's droid exec docs, checked October 30, 2026). Ours came out as custom:Claude-Sonnet-5.5-[OmniaKey]-0, custom:GPT-6.1-Terra-[OmniaKey]-1 and custom:MiniMax-M3.1-Flash-[OmniaKey]-2.
The index follows the array order, so inserting a model above another shifts every id below it; copy the id again after you edit the file.
-r / --reasoning-effort in droid exec does not apply to custom models (Factory's droid exec docs, checked October 30, 2026). Set reasoningEffort in the entry instead.
Three models on the same bug
Same two files, same command, one run per model. stats.py:
def median(values):
"""Return the median of a non-empty list of numbers."""
ordered = sorted(values)
mid = len(ordered) // 2
return ordered[mid]
test_stats.py:
from stats import median
assert median([3, 1, 2]) == 2
assert median([4, 1, 3, 2]) == 2.5
assert median([5]) == 5
assert median([1.5, 2.5]) == 2.0
print("all tests passed")
The command, with only the --model value changing between runs:
droid exec --auto medium -o json --model "custom:Claude-Sonnet-5.5-[OmniaKey]-0" "python3 test_stats.py fails. Fix the bug in stats.py without changing the tests, run python3 test_stats.py again, and tell me in one sentence what you changed."
| Model | Time | Turns | Output tokens |
|---|---|---|---|
| Claude Sonnet 5.5 | 33.7 s | 3 | 702 |
| GPT-6.1 Terra | 77.4 s | 4 | 451 |
| MiniMax M3.1 Flash | 30.7 s | 4 | 525 |
These are Droid's own numbers (duration_ms, num_turns, output_tokens). Flash finished fastest at 30.7 s, Claude used the fewest turns, and GPT-6.1 Terra took the longest at 77.4 s. Droid reported the first token after 8.7 s for Claude, 17.8 s for Terra and 7.0 s for Flash. All three fixed the bug without touching test_stats.py, and the tests printed all tests passed.
Claude's change:
- return ordered[mid]
+ if len(ordered) % 2:
+ return ordered[mid]
+ return (ordered[mid - 1] + ordered[mid]) / 2
GPT-6.1 Terra added the same branch above the old return line, and MiniMax M3.1 Flash wrote it with % 2 == 1. All three answers described that fix: average the two middle values for an even-length list. The MiniMax M3.1 Flash review covers that model in more detail.
Droid's JSON result also printed factory_credits on every run, although we were never signed in: 31,534 for Claude Sonnet 5.5, 4,830 for GPT-6.1 Terra and 835 for MiniMax M3.1 Flash. Factory's docs do not explain what the number measures or how it relates to the BYOK allowance (checked October 30, 2026).
Do you need a Factory account or plan?
On our runs, droid exec with a custom: model needed no Factory account. Factory's own models and the interactive app asked for one.
Droid CLI 1.0.0 shipped on October 29, 2026 (Factory's changelog, checked October 30, 2026). In a clean home folder with no Factory sign-in, every droid exec call with a custom: model ran on our own key. The same command without --model stopped at once with "Authentication failed. Please log in using /login or set a valid FACTORY_API_KEY environment variable." Factory's v0.236.0 changelog entry (October 8, 2026) covers resumed sessions: "Droid exec now resumes a session on your own model credentials without a Factory sign-in."
Starting droid with no arguments in the same folder stopped at "Please login with your Factory account to continue." Without a sign-in we could not try custom models in the interactive or desktop app, and we did not test image input, Bedrock, apiKeyHelper, reasoningEffort or thinking settings, Windows, sessions longer than one task, or the old config.json file.
Factory's Individual plans cost $20 (Pro), $100 (Plus) and $200 (Max) per month; the pricing page adds Teams at $60 per month per team plus $40 per seat, and no free individual plan (Factory's pricing docs and pricing page, checked October 30, 2026).
The Individual pricing docs say: "BYOK is free up to an allowance on all Individual plans. After that, usage is charged according to your specific plan." Factory does not say how large that allowance is or what the charge looks like afterwards.
Personal custom models work in the CLI and the desktop app, and don't appear in Factory's hosted web or mobile apps (Factory's BYOK docs, checked October 30, 2026).
Which errors will you hit, and what fixes them?
Each came from one wrong value in a setup that otherwise worked, on Droid 1.0.0.
-
anthropicwith/v1on the base URL. Droid printed "Requested model was not found on the API provider" after 0.9 s, and its log showed404onInvalid URL (POST /v1/v1/messages). Droid adds/v1/messagesitself, so our/v1doubled it. Fix: the bare host,https://api.anthropic.comorhttps://api.omniakey.com. -
openaiwith the bare host. Droid printed404and an nginx "404 Not Found" page after 1.4 s; the Responses API lives under/v1. Fix:https://api.openai.com/v1orhttps://api.omniakey.com/v1. -
A model id with dots,
claude-sonnet-5.5, instead ofclaude-sonnet-5-5. The endpoint answered503with codemodel_not_foundand the message "No available channel for model claude-sonnet-5.5". Droid's log labeled each failure "overloaded" and made 10 attempts over 259.7 seconds (about 4 minutes 20 seconds) before exiting with that message. The wording is the gateway's; the retrying is Droid's. Fix: copy the exact id from your provider's model list. -
OMNIAKEY_API_KEYempty in the shell that started Droid. Droid got401with "Invalid token" after 2.8 s. Fix: export the key in the shell you launchdroidfrom, then start a new session.
Factory's troubleshooting list adds two. "Invalid provider" means the value is misspelled or capitalized differently, and it has to be exactly anthropic, openai, generic-chat-completion-api or bedrock-converse. For a model missing from the selector, the docs say to check the JSON syntax in ~/.factory/settings.json and that each entry has its required fields (checked October 30, 2026).
FAQ
Where is the Droid settings file on Windows?
%USERPROFILE%\.factory\settings.json, the same file as ~/.factory/settings.json on macOS and Linux (Factory's settings docs, checked October 30, 2026). Put customModels there.
Why doesn't my custom model show up in /model?
Check the JSON syntax in ~/.factory/settings.json first, then the model, baseUrl and provider fields. Droid detects saved changes through file watching (Factory's BYOK docs, checked October 30, 2026). One report on Desktop 0.184.0 with CLI 0.227.0 saw custom models show up briefly in the desktop picker and then disappear, while droid exec --help still listed all 14; that issue is now closed (Factory-AI issue #40, checked October 30, 2026).
Can custom models read images?
Images are on by default for anthropic and openai and off for generic-chat-completion-api, where noImageSupport defaults to true (Factory's BYOK docs, checked October 30, 2026). Set noImageSupport: false on a generic entry to allow them. One user reported images stripped anyway on CLI v0.205.1 with that value set (Factory-AI issue #24, checked October 30, 2026).
Can I set reasoning effort for a custom model?
-r / --reasoning-effort in droid exec does not apply to custom models. Set reasoningEffort in the entry instead: it sets the default effort for a model Droid does not recognize and adds off, low, medium and high to the selector (Factory's BYOK docs, checked October 30, 2026).
Do custom models work in the Droid desktop app?
Yes: personal custom models are available in the CLI and the desktop app, and stay out of the hosted web and mobile apps. The model editors in the CLI and the desktop app both save to ~/.factory/settings.json (Factory's BYOK docs, checked October 30, 2026).
Sources checked
- Factory BYOK docs, checked October 30, 2026
- Factory settings docs, checked October 30, 2026
- Factory droid exec docs, checked October 30, 2026
- Factory release notes, checked October 30, 2026
- Factory Individual plans, checked October 30, 2026
- Factory pricing, checked October 30, 2026
- Factory-AI issue #40: custom models vanish from the desktop picker, checked October 30, 2026
- Factory-AI issue #24: images stripped, checked October 30, 2026
- Factory-AI pull request #76: config.json migration, checked October 30, 2026
OmniaKey's own documentation, checked October 30, 2026: API overview and OpenAI-compatible API.
Models in this article
Related articles
How to Use Claude and GPT APIs in DeepSeek Harness
One custom provider on the OpenAI protocol runs Claude Opus 5.5, Claude Sonnet 5.5 and GPT-6.1 in DeepSeek Harness, once each model has reasoning levels and a 128K output limit. The built-in DeepSeek provider sends a thinking setting Claude rejects.
Use Claude Code with OmniaKey
Point Claude Code at OmniaKey's Anthropic-native endpoint — two environment variables, Claude models that are never silently swapped, billing per token with no monthly plan.
Best model for Claude Code
Start daily coding with Sonnet 5.5 at $2 per million input tokens, move complex multi-file work to Opus 5.5 at $4, keep Fable 5.1 for the hardest long sessions, and hand quick edits and subagents to Haiku 5.5.