Skip to content

Models & provider keys

You choose which model each role uses, and you can bring your own key. Every model hlix offers is reached through one model gateway. When your Workspace stores its own OpenRouter key, hlix calls every model with your key. Otherwise hlix uses its own access, and the call counts toward your plan’s usage. Either way, the usage record attributes every call to the role and task that made it.

Two settings do the work. A provider key says which account pays for the models. A model preference says which model a role uses.

  • The owner or admin role in the Workspace. Storing, rotating or removing a key is Workspace administration; a member can see whether a key is configured but not change it, and a client collaborator cannot see it at all.
  • An OpenRouter key. One key covers every model hlix offers.

In the dashboard, Settings → AI models shows the model gateway row, with the key state and an enable switch. Over the API:

Terminal window
curl -sS -X POST "$HLIX_BASE_URL/v1/api/providers" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
-H 'content-type: application/json' \
-d '{"provider":"openrouter","apiKey":"sk-or-…","enabled":true}'

Expected result: 201 and the stored configuration, without the key. No endpoint ever returns key material.

The one accepted provider value is openrouter. A key stored for another provider before this changed is kept but never used.

Keys are stored encrypted. PATCH /v1/api/providers/{provider} rotates a key in place, and DELETE removes it.

Saving stores the key without checking it. An expired, revoked or mistyped key is stored like a working one, and you only find out when a task fails with the provider’s 401.

Test a key explicitly:

Terminal window
curl -sS -X POST "$HLIX_BASE_URL/v1/api/providers/openrouter/test" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
-H 'content-type: application/json' \
-d '{}'

Expected result for a working key: 200 and {"ok": true, "status": 200}. hlix asks the provider to list its models, using the stored key or an apiKey you pass in the body to check a key before saving it — which is what the dashboard does.

A key that does not work returns 502 with the provider’s answer:

{"ok": false, "status": 401, "detail": "…the provider's answer…"}

The 502 means the test reached a result, not that hlix failed — read ok. Test before you save, and test again after rotating a key.

Seven roles take a model preference:

Role What it does
classifier Sorts incoming work before anything acts on it
intake Decides whether a request becomes a cycle, and its risk lane — see Triage
planner Turns a brief into a roadmap and a cycle into tasks
orchestrator The project manager: decides what happens next in a project
worker Your Workspace’s coder model, used by every coder that reaches models through hlix, including the hlix coder
reviewer Reviews a cycle’s finished work
chat Answers you in the project conversation
Terminal window
curl -sS -X PUT "$HLIX_BASE_URL/v1/api/model-config/worker" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
-H 'content-type: application/json' \
-d '{"modelIdentifier":"anthropic:claude-opus-5","temperature":0.2}'

Expected result: 200 and the stored preference. temperature accepts 0–2 and maxTokens a positive whole number; both are optional. GET /v1/api/model-config lists every role’s preference, and DELETE /v1/api/model-config/{role} clears one so the role uses the default model.

The dashboard shows the same list under Settings → AI models, one row per role.

Coder How it reaches a model
hlix, claude-code, codex, opencode, goose, qwen-code, pi Through hlix, on a short-lived key created for the task. hlix calls the task’s model with your Workspace’s key, and meters every call to the task
cursor-agent With its own Cursor key, which is not your Workspace key

No provider key of yours enters a task’s sandbox.

The coder and the model are separate choices: any model runs in any coder. A task runs on its assigned agent’s model if it has one, else the worker model. When neither is set, Claude Code runs a Claude Sonnet model, Codex an OpenAI GPT model, and every other coder the default worker model.

  • Stored encrypted and never returned. The dashboard shows whether a key exists, never its value.
  • Tested on request against the provider. Saving alone accepts what you send.
  • Redacted from every record. Audit entries, run logs and coder output are redacted before they are stored, so a test that prints a key does not expose it.
  • Kept off command lines and out of sandboxes. Coders reach models through hlix on a task key, never with your provider key.
  • {"error":"admin only"} with 403. Storing, rotating, testing or deleting a key needs owner or admin.
  • {"error":"agency only"} with 403. A client collaborator called a provider route. Client access never includes Workspace credentials.
  • {"error":"Invalid provider"} with 400. The provider is not openrouter, the one accepted value.
  • {"error":"Provider not found"} with 404. No key is stored yet. Create it with POST before using PATCH.
  • {"error":"No stored credentials"} with 404 on a test. No key is stored and none was sent. Send apiKey in the body to test a key before saving it.
  • {"error":"Invalid agent role"} with 400. The role is not one of the seven above.
  • {"error":"Preference not found"} with 404. That role has no preference set and already uses the default.
  • A key saved but every task fails with a provider 401. Run the test call: it reports the same 401 without spending a task. If the test passes and tasks still fail, the key cannot use the model the role is set to — change the model, or the access at the provider.
If you want to… Read
Choose which coder runs a task Connect your agents
See the request and response shapes for model preferences Model configuration API
Understand what each role does Agents & orchestration
See what a run cost Delivery metrics