GPT-6 Sol & Claude Opus 5.5 are liveGPT-6 Sol at half the price of 5.6 Sol

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.

Kiki, OmniaKey COO9 min read
On this page

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. customModels in ~/.factory/settings.json (Factory's settings docs, checked October 30, 2026), with model, baseUrl, apiKey and provider.
  • Which provider. anthropic for Claude, openai for GPT models, generic-chat-completion-api for everything else that speaks Chat Completions.
  • Where /v1 goes. anthropic takes the bare host, because Droid adds /v1/messages; openai and generic-chat-completion-api take 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.

  • anthropic sends Anthropic Messages API requests. Use it for Claude; Anthropic's base URL is https://api.anthropic.com.
  • openai sends OpenAI Responses API requests. Use it for GPT models; OpenAI's base URL is https://api.openai.com/v1.
  • generic-chat-completion-api sends OpenAI Chat Completions requests. Use it for most other models, gateways and local servers, with the provider's own /v1 URL.

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:

json
{
  "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
    }
  ]
}
  • model is the id sent to the API; copy it from the provider's model list. displayName is your own label: it shows in /model and builds the custom: id.
  • baseUrl is the bare host for anthropic, and ends in /v1 for 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).
  • provider picks the API; a typo here gives the "Invalid provider" error below.
  • maxOutputTokens: 16000 caps 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:

python
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:

python
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:

bash
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."
ModelTimeTurnsOutput tokens
Claude Sonnet 5.533.7 s3702
GPT-6.1 Terra77.4 s4451
MiniMax M3.1 Flash30.7 s4525

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:

diff
-    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.

  1. anthropic with /v1 on the base URL. Droid printed "Requested model was not found on the API provider" after 0.9 s, and its log showed 404 on Invalid URL (POST /v1/v1/messages). Droid adds /v1/messages itself, so our /v1 doubled it. Fix: the bare host, https://api.anthropic.com or https://api.omniakey.com.

  2. openai with the bare host. Droid printed 404 and an nginx "404 Not Found" page after 1.4 s; the Responses API lives under /v1. Fix: https://api.openai.com/v1 or https://api.omniakey.com/v1.

  3. A model id with dots, claude-sonnet-5.5, instead of claude-sonnet-5-5. The endpoint answered 503 with code model_not_found and 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.

  4. OMNIAKEY_API_KEY empty in the shell that started Droid. Droid got 401 with "Invalid token" after 2.8 s. Fix: export the key in the shell you launch droid from, 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

OmniaKey's own documentation, checked October 30, 2026: API overview and OpenAI-compatible API.

Models in this article

Factory DroidBYOKcustom modelsClaude Sonnet 5.5GPT-6.1 TerraAPI setup

Related articles

Recent posts