n8vDocs

Model access

Which models an account can run, why, and how to see and change it

n8v rolls new models out account by account. A model behind a rollout flag runs only for accounts that have the flag, and that holds however the work starts: the web and iOS apps, the CLI, the API, MCP, A2A, GitHub, Slack, Telegram and automations.

  • Web
  • iOS
  • CLI
  • API
  • MCP
  • A2A
  • GitHub
  • Slack
  • Telegram
  • Automations

The gate

Is every flag the model needs on for this account?

Yes: it runs

No: refused

answered where you asked, and recorded

Every way of starting work meets the same gate. A model behind two flags needs both; a model no flag controls passes; a name n8v does not know is refused.

How it works, layer by layer

  1. 1

    Rollout flags

    Each gated model sits behind one or more flags. An account has each flag on or off.

  2. 2

    The gate

    One rule, on the server: a model runs when every flag it needs is on. The pickers show what the gate allows.

  3. 3

    Where it holds

    Every run start and provider switch, and before the API, MCP, A2A and the CLI accept a request.

  4. 4

    The record

    Every change of access and every refusal, with who, where, when, before and after.

Four layers. The flags decide, the gate applies them, every way in checks the gate, and everything is recorded.

1. Rollout flags

Each gated model sits behind one or more flags, called its gates. Haiku 5.5 sits behind haiku55; Opus 5.5 High sits behind opus55 and opus47EffortLevels, and needs both. Models no flag controls, such as Sonnet 5, run for every account.

An account's value of a flag comes from the first of these that is set:

  1. 1Its own value

    On or off for this account, set by an admin

  2. 2The value for everyone

    On or off for all accounts

  3. 3The default

    From the code; early access turns on some flags

The first that is set decides. An admin's own value for an account outranks the value for everyone, which outranks the default.

Early access (Settings, General, "Enable early access features") turns on some flags by default for the account, such as the Gemini agent and effort levels. An admin's value for everyone, or for the account, still comes first.

2. The gate

One rule decides, on the server: a model runs when every flag it needs is on for the account. The pickers in the apps list what the same rule allows, so a model a picker offers is never refused.

  • A name n8v does not know is refused, including a provider's own id such as claude-opus-5-5. Use n8v's names, such as opus-5.5; the list has them all.
  • Preferences only shape the pickers. Hiding a model in Settings, Agent never refuses it.
  • The model a chat runs when none is named, your default, skips a model your account can no longer use, as the composer does. You can change it on the Subscription limits page. A default you chose in the Slack or Telegram settings is kept as you chose it.

3. Where it holds

Where work startsWhen it is checkedWhat you see when it is refused
Chats: web, iOS, GitHub, Slack, Telegram, automationsAt the start of every run, and on a switch to another providerThe chat ends with Model not available; one press sends the message again with another model
API, MCP, A2ABefore anything starts or is charged403 model_not_enabled, with a hint that points to the list
CLI (n8v create)Before the task is createdAn error that names the model, and points to n8v models

A refused run never reaches the agent. A message sent through the API without a model runs the chat's last model; if that model's flag was turned off since, the API accepts the message and the chat ends in the refusal.

4. The record

Every change of who may use what is recorded, with who made it, from where, when, the value before and after, and the reason given:

ChangeRecorded as
A value for everyoneWho set it on, off or back to the default
One account's own valueWho set or removed it, for which account
A default changed in codeOnce, by n8v, after the deploy that changed it
Early accessThe account itself, joining or leaving
A flag deletedWho deleted it, and every account's own value that went with it
A refused modelWhich account, model and surface, and whether it was a dry run

A change an admin makes over the API or MCP is recorded the same way, as API or MCP, with the request id of the call that made it, so it can be found in the key's own activity too. Asking for the value a gate already has changes nothing and records nothing.

Changes are kept. Refusals are kept for 90 days, at most one a minute for the same account, model and surface.

See the models you can use

Every model n8v runs, in the order the apps list them, with whether your account can use it.

GET /api/v1/models, with any valid key:

curl -sS https://n8v.online/api/v1/models \
  -H "Authorization: Bearer $N8V_API_KEY"
{
  "default": "sonnet-5",
  "models": [
    {
      "id": "sonnet-5",
      "name": "Sonnet 5",
      "agent": "claudeCode",
      "provider": "Claude Code",
      "enabled": true,
      "needs": null
    },
    {
      "id": "haiku-5.5",
      "name": "Haiku 5.5",
      "agent": "claudeCode",
      "provider": "Claude Code",
      "enabled": false,
      "needs": null
    }
  ]
}
FieldMeaning
defaultThe model a chat runs when no model is sent
idWhat model takes in POST /chats and POST /chats/{id}/messages
nameThe model's name in the apps
agentThe agent that runs it, as a stable id: claudeCode, codex, gemini, opencode, amp, grok
providerThe agent's name in the apps, such as Claude Code or OpenAI Codex
enabledWhether your account's flags let it run
needsWhat to connect first, or null. "chatgpt": models only a ChatGPT sign-in, or a compatible provider, serves

The list_models tool, with the chats:read scope. It lists the models your account can use, grouped by agent, and how many more exist; include_disabled lists those too.

Pass an id as `model` to start_chat or send_message. Without one, chats use sonnet-5.
Claude Code: sonnet-5 (Sonnet 5, default), opus-5.5 (Opus 5.5)
OpenAI Codex: gpt-5.5 (GPT-5.5, needs a ChatGPT sign-in)
1 more model is not enabled for this account; include_disabled lists it.
n8v models          # the models you can use, by provider
n8v models --all    # every model, with the ones not enabled for you

n8v create --model takes any name the API takes. An unknown name is answered with the one it most likely means.

When a model is refused

The chat ends with a card: Model not available, the model's name, and the way on.

  • Send again with the model in your composer sends your message again, exactly as you wrote it. The chat keeps its branch, agent environment and history, and the agent receives the message as if you had sent it with that model. With the provider switch on, a model of another agent continues the chat there, once that agent is connected to your account.
  • Change model opens the task's model picker, and the button then names the model you chose. When the composer holds no model you may use, the card offers Choose a model first.
  • Details says what was asked for, why it was refused and what happens to your message, with links to this page and to the models you can use.

While it sends, the button reads Sending with the model, and a refusal shows under the buttons. The chat then shows a divider, Sent again with the model and the time; hover it for the model that was refused and, for the API or MCP, where it came from. Sending the refused model again would be refused again, so it is never offered. A name n8v does not know reads Unknown model. A model that a compatible provider does not serve gets the same card, Model not available on this provider, with the provider's own answer under Details.

An admin also gets Open in Model access, which opens the gate the account lacks.

{
  "error": {
    "code": "model_not_enabled",
    "message": "Model \"haiku-5.5\" is not enabled for this account",
    "param": "model",
    "hint": "GET /api/v1/models lists every model and whether this account can use it."
  }
}

An unknown name answers 400 invalid_model, with the model it most likely means:

{
  "error": {
    "code": "invalid_model",
    "message": "Unknown model \"claude-opus-5-5\". Did you mean \"opus-5.5\"?",
    "param": "model",
    "didYouMean": "opus-5.5",
    "hint": "GET /api/v1/models lists every model and whether this account can use it."
  }
}

Over MCP the same answers arrive as tool errors, with the hint naming list_models.

A chat whose model was refused at the start of a run says so in GET /api/v1/chats/{id} (lastError) and MCP's read_chat (last_error):

{
  "lastError": {
    "code": "model_not_enabled",
    "message": "Haiku 5.5 Low is not enabled for this account.",
    "model": "haiku-5.5-low",
    "retry": "with_another_model"
  }
}

Send the message again with another model with POST /api/v1/chats/{id}/retry and {"model": "sonnet-5"}, or MCP's retry_chat. See Retry a chat.

Error: Model "haiku-5.5" is not enabled for this account. `n8v models` lists the models you can use.
Error: Unknown model "claude-opus-5-5". Did you mean "opus-5.5"? `n8v models` lists the models you can use.

For admins: Model access

Admin, Model access shows every gate with what it opens, exactly who has it, and the week's refusals. A gate whose model sends prompts to an operator that keeps them is marked, with how many accounts could send it their code.

  • Open a gate for its value for everyone (default, on or off) and how many accounts that reaches, the models it decides (Show details for each model's id, the other gates it needs and its refusals), the accounts with their own value, and its own history.
  • Every change asks first, stating how many accounts have the gate now and after, and who will run each model: a model behind two gates opens only to accounts that have both. A change that takes access away is marked red. Give an optional reason; each change is recorded and can be undone from its notice, which puts back the value it replaced. Choosing the value a gate already has changes and records nothing, and says so.
  • Turn on for an account, or, when a gate reaches everyone, Turn off for an account: an account's own value, which wins over the value for everyone.
  • Check an account shows its value of every gate and where each comes from: its own value, the value for everyone, the default or early access.
  • Activity lists changes to model gates and early access, and every refusal, as they happen; it reads Live while it refreshes itself, and Paused while older entries are open. From a refusal, check the account or turn on the gate it lacked.

The headline numbers filter the list: Restricted shows only gates some accounts lack, Refused, 7 days opens the refusals. Links can open the page ready: ?gate=haiku55 opens a gate, ?account=<id> checks an account, ?q=Haiku searches.

A change applies to the next run at once. An account's open app picks up its own value immediately, and a value for everyone the next time it loads.

For admins: over the API and MCP

Everything on the page can be read and changed with an API key. Create it in Settings, API: admins see a group Model access, admins only with two scopes.

ScopeAllows
model-access:readEvery gate, one account's access, and the activity
model-access:writeA gate's value for everyone, and one account's own value. Each is recorded

Only an admin can create such a key, and it expires within 90 days. Every call checks that its owner is still an admin and not banned: until then the key reads and changes nothing. No connected app can hold these scopes, so Claude or ChatGPT connected through Settings never can; over MCP they come only with such a key. Only flags that gate a model can be changed this way.

The key's activity in Settings, API lists each call without its answer, since answers name other accounts.

CallDoes
GET /api/v1/model-accessEvery gate: what it opens, its value for everyone, who has it, last change
GET /api/v1/model-access/accounts/{account}One account, by id or email: each gate on or off, and why
GET /api/v1/model-access/activityChanges and refusals, newest first. kind, flag, account, scope=all, limit, cursor
PATCH /api/v1/model-access/gates/{flag}{"everyone": "on" | "off" | "default", "reason": "..."}
PATCH /api/v1/model-access/gates/{flag}/accounts/{account}{"value": "on" | "off" | "none", "reason": "..."}
curl -sS -X PATCH https://n8v.online/api/v1/model-access/gates/haiku55 \
  -H "Authorization: Bearer $N8V_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"everyone": "on", "reason": "Haiku 5.5 for everyone at launch"}'
{ "flag": "haiku55", "everyone": "on", "was": "default", "changed": true }

changed is false when the gate already had that value; nothing is recorded then. A key whose owner is not an admin, or is banned, gets 403 admin_only (listed in its activity once a minute), a flag that gates no model 404 unknown_gate, an account n8v does not have 404 account_not_found.

With such a key as the bearer token, n8v's MCP server also offers:

ToolDoes
model_accessEvery gate; with flag, one gate in full; or with account, its gates and why each is on or off
access_activityChanges and refusals, newest first, with the same filters as the API
set_model_accessflag with everyone, or flag with account and value; reason is recorded

set_model_access is marked as a change that needs confirming, so assistants ask before they call it. Names, email addresses, reasons and model ids appear in quotes, as people typed them, so an assistant reads them as data, never as instructions.

Questions

Why does the model picker not show a model? It is not open to your account. Settings, Agent says so under the list, and what early access would add, if anything. Otherwise an admin decides.

Why did the API accept a message that the chat then refused? The message named no model, so it runs the chat's last model, and that model's flag was turned off after the chat began.

Does sending a message again change it? No. The message stays as you wrote it. The chat adds a marker that names the model it was sent with, and the agent receives the message unchanged. It carries on the chat as after a typed message: in the same session for a model of the same family, with the history replayed for another family or agent.

Can a provider's own model id get around a gate? No. n8v runs only the models it knows by its own names; any other name is refused.