# Factory Droid Custom Models: Use Claude and GPT With Your Own API Key

> Add Claude, GPT and other models to Factory Droid with customModels in settings.json: which provider to pick, a config we ran, and the errors we hit.

- Canonical HTML: https://omniakey.com/blog/factory-droid-custom-models
- Markdown: https://omniakey.com/blog/factory-droid-custom-models.md
- Published: 2026-10-30 (updated 2026-10-30)
- Author: Kiki, COO at OmniaKey
- Language: en
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

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](https://omniakey.com/claude-sonnet-5-5), [GPT-6.1 Terra](https://omniakey.com/gpt-6-1-terra) and [MiniMax M3.1 Flash](https://omniakey.com/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](https://docs.omniakey.com/en/api/overview) 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](https://docs.omniakey.com/en/coding), 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."
```

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

```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](https://omniakey.com/blog/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

- [Factory BYOK docs](https://docs.factory.com/model-independence/byok.md), checked October 30, 2026
- [Factory settings docs](https://docs.factory.com/droid-cli/settings.md), checked October 30, 2026
- [Factory droid exec docs](https://docs.factory.com/droid-exec/overview.md), checked October 30, 2026
- [Factory release notes](https://docs.factory.com/changelog/release-notes.md), checked October 30, 2026
- [Factory Individual plans](https://docs.factory.com/pricing/individuals.md), checked October 30, 2026
- [Factory pricing](https://factory.com/pricing), checked October 30, 2026
- [Factory-AI issue #40: custom models vanish from the desktop picker](https://github.com/Factory-AI/factory/issues/40), checked October 30, 2026
- [Factory-AI issue #24: images stripped](https://github.com/Factory-AI/factory/issues/24), checked October 30, 2026
- [Factory-AI pull request #76: config.json migration](https://github.com/Factory-AI/factory/pull/76), checked October 30, 2026

OmniaKey's own documentation, checked October 30, 2026: [API overview](https://docs.omniakey.com/en/api/overview) and [OpenAI-compatible API](https://docs.omniakey.com/en/api/openai-compatible).
