oxagenDocs
Governance

Model governance

Which models each plan offers, how workspace model defaults work, and who pays for tokens.

Model availability

Use the configured model catalog and your organization's plan to determine available text models. Model IDs and plan entitlements change with the deployed registry. Oxagen no longer exposes image or video generation capabilities.

The organization can fund model calls with Oxagen's key or a stored provider credential. See Bring your own key.

Workspace model defaults

A workspace Owner or Admin sets the workspace's default text tier and default text model with update_model_settings. Image and video defaults no longer exist, because ADR-043 removed media generation. A person can also set their own defaults.

To configure workspace model defaults:

Call update_model_settings with the default text tier, default text model, or both. Read the current values with get_model_settings.

Tier and model resolve on two separate chains, workspace first, then person. A chat turn then prefers a model over a tier:

model = workspace model ?? user model
tier  = workspace tier  ?? user tier
turn uses model if set, otherwise tier

So a workspace that sets only a tier does not override a person who picked a specific model. To pin a workspace to one model, set the default model, not only the tier.

The in-app agent runs on Stella

The in-app agent is a turn on Stella's headless engine, running as a container beside the platform. The engine holds no model key and runs no tool. Every completion it needs comes back to Oxagen, which answers it on the key your funding source names. Every tool call comes back through the same gates as any other governed action. If the engine is down, the agent says so rather than answering from a fallback.

Bring your own key (BYOK)

An organisation can pay its model vendor directly instead of buying tokens through Oxagen. You store your own model key once, at the organisation level, and the in-app agent runs on it from the next turn on. The key stays in Oxagen, and the agent never sees it.

Who pays for tokens:

Funding sourceWho pays the vendorWhat Oxagen bills for tokens
Your own keyYou, on your own vendor accountNothing. Tokens are reported in full and billed at zero.
Oxagen's key (the default)OxagenAssistant usage, at exactly the vendor rate, as its own line. Oxagen adds no margin here.

Governed actions are billed the same way either way. The key only changes who pays for tokens.

The key Oxagen uses when you do not bring one

Oxagen does not run every customer on one shared key. When your organisation is created, Oxagen mints an OpenRouter key on its own account for your organisation alone, and every assistant turn that Oxagen pays for runs on that key.

This changes nothing about your bill. Oxagen still pays the vendor, still reports your tokens in full, and still charges them at the vendor rate as assistant usage, with no margin. What it adds is a second record: OpenRouter reports usage per key, so the figure on your invoice can be checked against the vendor's own figure for the key that serves you.

Three things are worth knowing about it:

  • The key is named for your organisation and the person who created it, in the form oxagen/<your-slug>/<creator-email>. The name is fixed when the key is minted. Renaming your organisation later does not rewrite it, because the name is a label an operator reads, and the key's identity is the record behind it.
  • The key carries a daily spend ceiling, $25 by default. It bounds one organisation's bad day. It is not what bounds an ordinary account: the monthly assistant spend cap below is reached first.
  • You never see the key and never hold it. It is Oxagen's key on Oxagen's vendor account. Bringing your own key, above, is the arrangement where you hold the key and pay the vendor.

If Oxagen cannot mint the key, your organisation runs on Oxagen's shared key instead. The assistant works, the bill is the same, and what is missing is the per-key vendor figure until Oxagen fills it in.

Oxagen decides who pays once per turn, before any model call. The same answer picks the key the call is made on and whether the tokens are billed:

Loading diagram

Two branches are easy to miss:

  • A stored key that cannot be used falls back to Oxagen's key. If an operator has disabled the key, or the server cannot decrypt it, the turn runs on Oxagen's key and is billed as assistant usage rather than failing on your key. A failure to read the credential is the opposite case. The turn fails, so an outage never quietly moves you onto Oxagen's billed key.
  • Your own key still needs a positive credit balance. Tool calls and other governed actions consume credits whoever pays for tokens, so the credit check runs on every turn.

Which keys you can bring:

  • OpenRouter. One key reaches every model in the catalog. OpenRouter does not serve embeddings, so under an OpenRouter key, embeddings stay on Oxagen's key and are billed as assistant usage.
  • Vercel AI Gateway. One key reaches every model and serves embeddings too.
  • OpenAI. Your own OpenAI key. Tell Oxagen which of your models to use for the balanced tier, which is the one the assistant runs on.
  • Anthropic. Your own Anthropic key, with the same balanced model setting. Oxagen reaches Anthropic through its OpenAI-compatible endpoint, which does not offer prompt caching. If you want caching on Claude models, use an OpenRouter or Vercel AI Gateway key.
  • Any other OpenAI-compatible server. Together, Fireworks, Groq, Azure, or your own vLLM. Give its baseUrl and your balanced model. The URL must use https and must be reachable on the public internet; Oxagen refuses internal addresses.

For OpenAI, Anthropic, and custom servers, any tier you leave unmapped uses your balanced model, so the assistant never asks your vendor for a model it does not have.

The model must be able to use tools. The assistant answers questions by calling tools, so a model that cannot call them cannot answer anything about your workspace. When you test a custom server's key, Oxagen asks your balanced model for one tool call (at most 16 tokens) and tells you whether it worked. Keys for the four named providers are not asked, because they all support tools.

To set your key, you need the org Owner or Admin role. In the app, open Organization › Model funding at /{org}/model-funding, choose the vendor, paste the key, and for OpenAI, Anthropic, or a custom server name the balanced model (and the server's URL). The same two steps are available from the API and the MCP tools below:

  1. Test the key. In the app, Test key; from the API, POST .../verify. Oxagen asks the vendor whether it accepts the key, and for a custom server whether the model can call tools.
  2. Store it. In the app, Save key; from the API, PUT. Oxagen encrypts the key before storing it. Nobody can read it back, not even an Owner. Reads return only its last four characters, the endpoint and model settings, when it was last tested, and when it was last changed.

Setting a new key replaces the old one. Clearing the key returns your organisation to Oxagen's key.

The monthly spend cap. While your organisation is on Oxagen's key, its assistant usage is capped each month. The default cap is 2000 credits ($20). Once the month's platform-paid usage reaches the cap, Oxagen refuses the next turn before it starts, and the message names the cap. The check runs when a turn starts, so the turn that crosses the cap is allowed to finish. The cap cannot be changed from the app yet. The cap does not apply while your own key is stored, because Oxagen is not paying for those tokens.

From the API. The same settings are available at /v1/:org/:workspace/org/model-credential:

  • PUT /v1/:org/:workspace/org/model-credential stores or replaces the key. The body is { "provider", "apiKey" }, plus "modelMap": { "balanced": "..." } for openai, anthropic and openai_compatible, plus "baseUrl" for openai_compatible.
  • GET returns the redacted view. DELETE clears the key. POST .../verify tests a key before you store it, or tests the stored key when the body is {}.

Test a key, then store it:

bash
BASE="https://api.oxagen.sh/v1/$ORG_SLUG/$WORKSPACE_SLUG/org/model-credential"

# Ask the vendor whether it accepts the key. Spends no tokens.
curl -X POST "$BASE/verify" \
  -H "Authorization: Bearer $OXAGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"provider\": \"openrouter\", \"apiKey\": \"$OPENROUTER_API_KEY\"}"

# Store it. Replaces any key already stored.
curl -X PUT "$BASE" \
  -H "Authorization: Bearer $OXAGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"provider\": \"openrouter\", \"apiKey\": \"$OPENROUTER_API_KEY\"}"

The verify call returns ok, provider, latencyMs, error, and toolCalling. error is the vendor's own reason when it refuses the key, or when a custom server refuses the tool call. toolCalling is false when the key works but the model cannot use tools. The store call returns the redacted view above. lastVerifiedAt is null on a freshly stored key, because storing does not verify. Send POST .../verify with {} afterwards to verify the stored key and record the time.

The audit log records every set and clear. The key itself never appears there.

Restricting model access per workspace

There is no per-workspace model allowlist yet, and no setting blocks a model the subscription tier allows. The closest control is the workspace default. A workspace Owner or Admin sets the default text tier and model through update_model_settings. The default chooses a model but does not forbid others.

Model governance and org-enforced policies

Org-enforced policies on model access are not available. The IAM resolver has no live policy tier, and role editing does not add that policy tier, so an org cannot pin a capability to a particular model or stop a workspace from choosing a different one. What an org controls today is the subscription tier, which decides the models on offer, and who pays for tokens (see Bring your own key).

Model handle stability

Oxagen uses model handles (for example, claude-sonnet-5) rather than hard-coded model slugs. modelIdOf() resolves a handle to the current gateway slug at request time, so a provider renaming a model does not break your agents.

If a gateway model slug changes, Oxagen updates handle resolution in one place, and your agents keep working without changes.

On this page