Knowledge Base Sections ▾

Navigation

▸ Start here By roles

Categories

Tools 52
Glossary 12

Tools

Factory Droid + JoinGonka Gateway: BYOK on Gonka network models

Factory Droid (droid command) is a terminal code agent by Factory. It analyzes the project, edits files, runs commands and tests, and can break down large tasks into a plan. There are two modes: interactive droid in the terminal and one-off droid exec — a single task from a script or CI.

By default, Droid runs on models from the Factory catalog, but it supports BYOK: the customModels array in ~/.factory/settings.json accepts any endpoint that speaks OpenAI Chat Completions. JoinGonka Gateway is exactly that, so connection boils down to one installer command — and the agent runs on Gonka decentralized network models: DeepSeek V4 Flash, GLM-5.3 Flash, and MiniMax M2.7, all at the same price — $0.0069 per million input tokens.

One condition to keep in mind: the interactive Droid mode requires logging into a Factory account, and using your own models does not bypass this. The one-off droid exec with BYOK models worked in our test without a login — details in the BYOK section. Commands, files, and messages below were verified by a live run of Droid 0.225.1 through the gateway on September 23, 2026. After confirming your address, 3M free tokens will be credited to your account — enough to repeat all this yourself.

Quick start: installation and one command

Step 1: install Droid. The official methods from the Factory documentation:

# macOS and Linux
curl -fsSL https://app.factory.ai/cli | sh

# Homebrew
brew install --cask droid

# Windows (PowerShell)
irm https://app.factory.ai/cli/windows | iex

# via npm
npm install -g droid

The script drops the binary into ~/.local/bin and tells you how to add the directory to PATH; on Linux the documentation asks you to also install the xdg-utils package. To verify, run droid --version.

Step 2: get a key. Sign up at gate.joingonka.ai/register, confirm your address and create a key with the jg- prefix under the "API Keys" section. One key and one balance work for every model on the network.

Step 3: run the installer.

npx @joingonka/setup --tool droid

The installer will ask for your key — it is not passed in command-line arguments so it does not end up in your shell history — and then does four things:

  • adds an entry to the customModels array in ~/.factory/settings.json (on Windows, %USERPROFILE%\.factory\settings.json) for each model on the network: the gateway address, the provider type generic-chat-completion-api, the key as a literal, the real context window and response ceiling; the file gets 600 permissions;
  • sets the default model — sessionDefaultSettings.model — to DeepSeek V4 Flash, but only if none is selected or the current one points to a model that has left the network. It does not override a model from the Factory catalog or someone else's BYOK entry, and it tells you how to switch;
  • saves a copy of the previous file, leaving other entries in customModels, all other settings and comments as they were; a file it cannot parse is not overwritten — it tells you what to fix;
  • finally, sends a live request to the gateway and tells you plainly whether the key, address and model were accepted.

To set a different default model, use the --model flag with the shorthand deepseek, glm or minimax — an explicitly specified model is always written. For dotfiles and servers there is a non-interactive mode where the key comes from an environment variable:

JOINGONKA_API_KEY=jg-your-key npx @joingonka/setup --tool droid --model glm --non-interactive

No need to restart Droid: it picks up changes to settings.json on its own. The line ! Could not verify right now with a 429 response at the end means the model is busy, not a configuration error — the configuration has already been written.

Manual configuration: customModels in settings.json

Everything the installer does can be done by hand. Droid's user settings live in ~/.factory/settings.json; if the file doesn't exist, Droid creates it on first launch. For the Gonka network you need the customModels array and a default model:

{
  "customModels": [
    {
      "model": "deepseek-ai/DeepSeek-V4-Flash-0731",
      "id": "custom:deepseek-ai/DeepSeek-V4-Flash-0731",
      "displayName": "DeepSeek V4 Flash (Gonka)",
      "baseUrl": "https://gate.joingonka.ai/v1",
      "apiKey": "jg-your-key",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 32768,
      "maxContextLimit": 380000,
      "noImageSupport": true
    },
    {
      "model": "zai-org/GLM-5.3-Flash",
      "id": "custom:zai-org/GLM-5.3-Flash",
      "displayName": "GLM 5.3 Flash (Gonka)",
      "baseUrl": "https://gate.joingonka.ai/v1",
      "apiKey": "jg-your-key",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 8192,
      "maxContextLimit": 390000,
      "noImageSupport": true
    },
    {
      "model": "MiniMaxAI/MiniMax-M2.7",
      "id": "custom:MiniMaxAI/MiniMax-M2.7",
      "displayName": "MiniMax M2.7 (Gonka)",
      "baseUrl": "https://gate.joingonka.ai/v1",
      "apiKey": "jg-your-key",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 8192,
      "maxContextLimit": 200000,
      "noImageSupport": true
    }
  ],
  "sessionDefaultSettings": {
    "model": "custom:deepseek-ai/DeepSeek-V4-Flash-0731"
  }
}
FieldValueWhat matters
modelthe network model idSent in the request as-is, including the vendor prefix
idcustom: + model idA permanent entry name for the -m flag and the default model. Without this field Droid builds the name itself — from displayName and an ordinal number
displayNameany labelThis is how the model appears in the /model list
baseUrlhttps://gate.joingonka.ai/v1Must end with /v1: Droid appends the /chat/completions path itself
apiKeyyour jg-… keyA literal is the most reliable option. A reference like ${JOINGONKA_API_KEY} also works, but then the variable must be present in the environment Droid was launched from, otherwise the request won't go through
providergeneric-chat-completion-apiThe type for OpenAI Chat Completions — exactly like this, lowercase; that's what this whole guide was tested with
maxOutputTokens32768, 8192, 8192The response ceiling for each model on the network
maxContextLimit380000, 390000, 200000The model's context window; the field is described in the Factory settings schema
noImageSupporttrueThe network's models are text-only; this flag disables image attachments for the entry

The default model is stored in sessionDefaultSettings.model and references an entry by its id. Factory's documentation also mentions a model key at the root of the file, but in our run droid exec without the -m flag took the model from sessionDefaultSettings — and did so after the value was changed too.

The key sits in the file in plain text: lock the file down with chmod 600 ~/.factory/settings.json and don't move entries containing the key into your project's .factory/settings.json — that file usually ends up in the repository. And if the file looks different after Droid launches, that's normal: whenever it saves any setting, Droid rewrites the whole file — reordering keys, adding an index field to entries, and dropping comments. The 600 permissions stay in place, and the installer updates such entries without any trouble.

BYOK in Droid: Model selection and Factory account requirements

Droid lists its own models separately from the catalog: according to the documentation, in interactive mode the /model command shows them under Custom models, and Ctrl+N cycles through models right in the input field. In one-shot mode, the model is set with the -m flag using a value from the id field, and the slashes are written as-is: droid exec -m custom:zai-org/GLM-5.3-Flash "…".

Get the name wrong and Droid responds with Invalid model and lists every model it can see, including its own in the form custom:… (display name): a handy confirmation that the models loaded. A name in Factory's documentation style, built from the display name and number (custom:DeepSeek-V4-Flash-(Gonka)-0), won't work when an explicit id is present — in our run it produced the same Invalid model.

What requires a Factory account. Your own models remove the question of paying for tokens, but not the question of logging into the product itself. Here's what our run of Droid 0.225.1 without an account showed:

ScenarioFactory login required?What happened in the run
Interactive droidYesRight after the splash screen — a "Please login with your Factory account to continue" screen with Login and Exit options; there's no getting past it without an account
droid exec on BYOK modelsPer the docs — yes, via the FACTORY_API_KEY keyAll three network models responded; the JSON output showed factory_credits: 0, and the log had warnings about unavailable cloud features
Cloud features: session sync with the web version, connectors, plan limitsYesRequests to the Factory API got 401 and were skipped — this didn't affect the agent's work

To work in the interface, create a Factory account and log in through the browser — the Login item or the /login command; on a machine without a browser, the documentation suggests a key from your account settings in the FACTORY_API_KEY variable. Running droid exec without logging in is handy for testing, but it isn't officially documented — don't rely on it in CI. According to Factory's pricing page, BYOK is included in all individual plans with a free limit, and beyond that limit BYOK usage is billed under the plan's terms; current terms are at factory.ai/pricing. Tokens for the network's models are paid separately — from your JoinGonka balance.

Which model to choose. All of the network's models cost the same, so the choice comes down to behavior. Here's how they performed in our run of droid exec on a single task — read a file and find the bug:

ModelContext / responseHow it behaves in Droid
DeepSeek V4 Flash380K / 32768Correct answer in two turns. The largest response ceiling on the network, which is why the installer sets it as the default. With --auto low, it also fixed the file and ran it itself to verify
GLM-5.3 Flash390K / 8192Correct answer in two turns, about 20 seconds. A reasoning model: part of the response ceiling goes to reasoning
MiniMax M2.7200K / 8192Correct answer in two turns, 10-20 seconds. The model's reasoning arrives separately from the answer, and only the answer itself remains in the droid exec output

According to Factory's documentation, the -r flag (reasoning level) doesn't apply to BYOK models. Why DeepSeek V4 Flash is the default choice is covered in the model review.

Verification: what should happen

Put a file calc.py into an empty directory with an obvious bug in it — say, a rectangle area function where the sides get added instead of multiplied — and ask Droid to find it:

droid exec "Read the file calc.py in the current project directory and tell me in one sentence whether it has a bug."

Without any flags, droid exec runs in read-only mode: it can look at files but not change them. The agent will call the read tool on its own and give you a straight answer, pointing to the faulty expression. With the -o json flag, the reply arrives as a single object that's easy to parse with a script (output trimmed):

{"type":"result","subtype":"success","is_error":false,"duration_ms":2239,"num_turns":2,
 "result":"Yes, the file has a bug: the rectangle area is computed as the sum of the side lengths, but it should be their product (width * height). …",
 "usage":{"input_tokens":19016,"output_tokens":146,"factory_credits":0,"ttft_ms":747}}

The factory_credits: 0 field confirms the work ran on your own model rather than burning Factory credits. To let the agent edit files, raise the autonomy level: droid exec --auto low "Fix the bug in calc.py and change nothing else." — in our run, DeepSeek V4 Flash read the file, swapped the addition for multiplication, and ran the script itself to confirm it prints 12.

The third check happens on the gateway side: in the dashboard under "Usage", the request will show up in the "By model" breakdown, and the "By key" block will update the last-request timestamp.

If something goes wrong, keep a Droid quirk in mind: in the console, droid exec only prints Error during droid execution: Exec failed (in JSON, "result":"Exec failed"), while the real cause stays in the log. You can pull it out with a single command:

grep agent_error_count ~/.factory/logs/droid-log-single.log | grep -o '"errorMessage":"[^,]*' | tail -1
What you seeWhat it meansWhat to do
401 Invalid API keyThe gateway rejected the keyCheck the apiKey in your model entry: the whole key, no spaces. If it's a ${…} reference, the variable must be present in the environment Droid runs from
405 <html>…405 Not Allowed…baseUrl is missing the /v1 suffixThe address must be exactly https://gate.joingonka.ai/v1
400 Model "…" not found. Available: …Typo in the model field, most often a missing vendor prefixCopy the id from the list the gateway includes in the message itself
Invalid model: custom:… plus a model listThe -m flag or the default model points to an entry that doesn't existTake a name from the Available custom models section. Network models aren't there — Droid didn't load the entries: check your JSON syntax
429 Model "…" is currently overloaded in the Gonka network (rate limit)The model has no free capacity on the network right nowDroid retries on its own — we saw five attempts in about two minutes. Still no luck? Switch models with the -m flag; network status is on the status page
402Out of funds on your balanceTop up in the "Billing" section; the key itself is still valid
"Please login with your Factory account to continue"Interactive mode requires a Factory accountLog in via Login, or work through droid exec
Long pause before the first replyQueueing for the model at peak hoursWait, or switch models with the -m flag

How much does it cost

Agentic tools consume tokens differently than chat: for every phrase you send, Droid adds a system prompt, tool definitions, and a snapshot of the working directory, and the task spans multiple turns. In our run, each turn carried about 9.5 thousand input tokens before you even asked a question: the task "read a file and find an error" took two turns and about 19 thousand tokens, while "fix and verify" took four turns and about 44 thousand. Therefore, price per token is the deciding factor here.

Via JoinGonka Gateway, tokens cost $0.0069 per million for input and $0.021 per million for output — the price is the same for all network models and is pulled onto this page from a live source.

ScenarioConsumptionVia Gateway
One-time task: read, fix, verify19-44K tokenshundredths of a cent
Day of active work3-7M tokenssingle-digit cents
Month of active development~150M tokensabout a dollar

Estimates in the right column are based on September 2026 prices. For comparison — how you can pay for models in Droid in general:

MethodPayment ModelLimitations
Models from Factory catalogPro, Plus, or Max plan subscriptionrolling limits for 5 hours, 7 and 30 days; beyond that — Droid Core pool or extra top-up via Extra Usage
BYOK with vendor keypay-per-token at vendor ratesbill grows with session length; price depends on the selected model
JoinGonka Gateway (BYOK)pay-per-token, prepaid balanceusage visible in dashboard, no subscriptions or quotas at the gateway; BYOK terms on the Factory side are the same as for any of your own keys

The /cost command in the Droid interface shows session statistics, while exact usage and balance for BYOK models are available in the gateway dashboard under "Usage" and "Billing" sections. Create a separate key for Droid — its traffic will be shown as a separate line.

Things to consider

Autonomy. In one-shot mode, Droid only reads by default; autonomy levels grant more: --auto low — file edits, --auto medium — plus dependency installs, builds, tests and local commits, --auto high — all the way up to push and deploy. The --skip-permissions-unsafe flag removes all checks — disposable containers only. In interactive mode, Ctrl+L cycles the level, and the starting level is set by sessionDefaultSettings.autonomyLevel; by default it's off — everything requires confirmation.

Commit signature. The includeCoAuthoredByDroid setting is on by default: Droid adds a co-authorship line to commit messages. If you don't want it, put "includeCoAuthoredByDroid": false in settings.json.

Where sessions are stored. After you log into your account, Droid mirrors CLI sessions to the Factory web version by default — that's what cloudSessionSync controls. BYOK keys stay local per the docs; if you also want the conversation to stay on your machine, set "cloudSessionSync": false. The gateway, for its part, doesn't store the contents of prompts or responses — only usage aggregates remain in the stats.

Updates. Script-based installs update themselves; you can pin the version with the FACTORY_DROID_AUTO_UPDATE_ENABLED=false variable or the droid update --version <version> command; npm builds don't self-update. After an update, verify with a single droid exec that the network models are still there.

Images. Network models are text-only; for screenshots, keep an entry for a vision-capable model from another provider close at hand.

If working without a vendor account is a hard requirement. The same network models plug into open terminal agents that need no login — for example, OpenCode with the same installer, using the --tool opencode flag.

Factory Droid connects to the JoinGonka Gateway via BYOK: the command npx @joingonka/setup --tool droid appends entries for DeepSeek V4 Flash, GLM-5.3 Flash, and MiniMax M2.7 to customModels in ~/.factory/settings.json (provider: generic-chat-completion-api, a baseUrl with /v1, a jg-… key, an explicit id in the form custom:<model>) and sets DeepSeek V4 Flash as sessionDefaultSettings.model. Interactive mode requires a Factory account; droid exec on BYOK models in run 0.225.1 worked without one, with factory_credits: 0. To verify, use droid exec -o json and the “Usage” section in your dashboard — and note that Droid writes the reason for a failure not to the console but to ~/.factory/logs/droid-log-single.log.

Want to learn more?

Explore other sections or start earning GNK right now.

Get key and free tokens →