Model catalogs
SubLane guide: model catalogs.
Use this when the model list is empty or you need to control available models. A model shown in your pool is enough for your first request.
SubLane discovers model IDs per subscription account and derives each pool's catalog from its enabled accounts. Pool allowlists remain administrator-owned policy; discovery never replaces them. A reported model describes upstream support, not remaining quota or a successful generation test.
Example model catalog with synthetic model IDs:

Model capabilities
Account, API-channel, resource-group and personal-key model dialogs show upstream-reported context windows, maximum output tokens, reasoning levels, image input and tool-call support. Unreported details remain Unknown; an explicit unsupported value remains distinct from missing data. GET /v1/models includes known capability fields for the key's permitted models.
For a shared model ID, resource-group and key catalogs report the lowest limits and common capabilities confirmed by every permitted callable resource. Missing observations remain unknown. Hidden but callable routes contribute to this conservative comparison without becoming visible in public discovery. Capability metadata does not grant access, change routing or prove successful generation. Old snapshots refresh through the existing discovery mechanism.
Synchronization and storage
Account import, OAuth completion and reauthorization start discovery after credentials have been saved. Reauthorization clears the old catalog even if the submitted token is unchanged. Existing accounts discover lazily when their catalog or pool is read, or before their first model request. Re-enabling an account checks whether its saved catalog needs refreshing. Verify connection and Refresh models share the same discovery operation.
The consolidated schema stores a bounded JSON model snapshot and lifecycle revision on each account. A snapshot contains sorted, deduplicated native model IDs, the last successful observation time and a discovery-source marker. The marker includes the Codex client version and an adapter revision; upgrading that contract refreshes older or unmarked snapshots regardless of their age. Each account is limited to 512 model IDs of at most 128 ASCII characters; no upstream instructions, manifests or credentials are stored. A null snapshot means unknown support. A successfully retrieved empty list is a known empty catalog.
Snapshots are fresh for 15 minutes. A stale read returns the saved value and starts a shared background refresh. There is no periodic upstream polling while idle. Cold requests also join a refresh when the discovery-source marker changes. A failed upgrade refresh may retain previously known capabilities, but an obsolete catalog cannot prove an unlisted model unsupported. Manual refresh has a five-second cooldown; failed refreshes retain the last successful snapshot and back off for 30 seconds. Failed observations never change its timestamp. After 24 hours, the old snapshot remains visible to administrators but is excluded from advertised and routable models until refreshed. Refresh state and backoff are process-local; successful snapshots survive restarts.
At most two model discoveries run concurrently within the workspace operation capacity, which defaults to 128 and is configured by SUBLANE_GATEWAY_CAPACITY. Concurrent readers of one account/revision share one discovery. Shared work uses the process context and a 45-second deadline; browser disconnection cancels only that browser's wait. Cold gateway discovery has an overall 45-second budget. Shutdown cancels and joins workers before SQLite closes; fresh catalogs require no upstream lookup.
Conditional writes reject results from an obsolete authorization, a disabled/deleted account or an earlier lifecycle revision. Discovery captures the runtime Codex version once; results from a version superseded during the network request are discarded, and snapshots retain the version actually sent upstream. Version policy and automatic stable-release synchronization are managed in system settings. Pool grants, membership, policy and persisted snapshots are read again in one SQLite transaction before publishing a pool result. Models removed from the pool cannot leak through a refresh started before the edit.
Pool catalogs and routing
The effective pool catalog is the deduplicated union of usable account snapshots, filtered by the pool's exact model allowlist. Disabled and reauthorization-required accounts are excluded. Cooldown, concurrency and remaining subscription quota remain separate runtime concerns; a listed model does not promise an immediately available request slot.
Account, resource-group and key catalogs use native model IDs without added provider prefixes. Eligible Codex, Claude, Antigravity, Grok Build and OpenAI-compatible API resources contribute according to the group's routing and fallback policy. Public catalogs omit hidden models. Identical visible IDs are merged; owned_by is sublane when several providers expose a visible route. Thinking variants retain their full requested ID for permission checks and use the discovered base model for capability selection. Aggregate catalogs are limited to 4,096 model IDs. Legacy provider-qualified requests remain compatible, and explicit provider prefixes narrow selection.
Before inference, discovery warms missing/stale catalogs for eligible providers in the pool; an explicit legacy prefix narrows discovery to that provider. Compaction warms and selects Codex accounts only. The scheduler rechecks pool policy and account snapshots in its selection transaction, filters out accounts that do not support the requested model, then applies existing concurrency, cooldown and rotation rules. A known unsupported model returns 404 model_not_available; unknown or over-age capabilities return 503 model_catalog_unavailable with a retry hint. Other eligible, known accounts may still serve a model when a peer's discovery fails.
Native requests select among permitted, available accounts reporting the model. Account selection and reservation share the existing transaction and process lock. Existing native conversations keep a single account binding across providers. When the client explicitly changes models and sends complete portable history, an account that does not support the new model can be replaced by an eligible account in the same pool. If the current account supports the new model, it remains selected. Saturation, cooldown, removal, disablement and lost support for an unchanged model never cause automatic failover.
Provider continuations retain their account: previous-response or stored-conversation references, item references, encrypted reasoning/compaction, signed Claude thinking and Gemini cached content/signatures cannot authorize a model switch. Incremental WebSocket turns cannot change the model; send an independent full-history response.create turn instead. HTTP previous_response_id remains rejected; send full input without that reference. Unsupported bound requests return conversation_account_unavailable.
The existing account_affinity table stores native routing under an auto scope and records the normalized model through an additive migration. Upgraded bindings with unknown model metadata remain pinned until a supported request records the model; start a new conversation if that is unavailable. A single legacy provider binding is adopted without changing the account or upstream session hash; multiple legacy bindings under the same session remain ambiguous. Explicit legacy-prefix requests retain their provider-specific bindings only when that provider is active. No permanent API-key/account binding is added.
UI and browser APIs
- Accounts → Models shows an account's last reported model IDs, observation time and synchronization state, with manual refresh.
- Resource groups → Models shows the automatically derived, policy-filtered pool catalog. The pool editor continues to manage the allowlist separately.
- API keys → Models shows the current key's authorized pool catalog. Import into CC Switch provides a searchable model picker using that same catalog.
| Endpoint | Access | Purpose |
|---|---|---|
GET /api/accounts/{id}/models | Administrator | Read account snapshot and trigger stale discovery |
GET /api/channels/{id}/models | Administrator | Read account snapshot and trigger stale discovery |
POST /api/accounts/{id}/models/refresh | Administrator, exact origin, empty JSON body | Refresh or join account discovery |
POST /api/channels/{id}/models/refresh | Administrator, exact origin, empty JSON body | Refresh or join account discovery |
GET /api/groups/{id}/models | Administrator | Read a derived pool catalog |
GET /api/keys/{id}/models | Enabled key owner | Read an active key's pool catalog without decrypting its secret |
GET /v1/models | Gateway bearer key | Return the standard model list for the key's pool |
Personal catalog access rechecks key enablement, expiry, revocation and pool access. Administrators cannot use the personal endpoint to inspect another owner's key. Responses contain model metadata and aggregate freshness counts, not subscription account IDs, names or credentials. A partial pool response exposes that some account catalogs remain unknown instead of treating them as supporting every model.
Verification boundary
Automated tests use synthetic accounts and local fake upstreams. They cover restart persistence, authoritative empty catalogs, failed-refresh retention/backoff, authorization and pool-revocation races, cancellation/shutdown, mixed-account routing, pool allowlists, thinking variants, conversation affinity, endpoint ownership, and fresh-schema persistence. Frontend tests cover catalog states, keyboard model selection and stale responses after identity changes. Discovery does not probe model generation, and upstream catalogs may change between synchronization and an actual request.
Model availability diagnostics
Pool and personal-key model dialogs let you inspect a native model ID. Results show local eligibility for a new request, exclusion reasons, observation time and known retry times. Administrators can inspect account-level details; personal keys receive aggregates without subscription identities. Checks do not execute inference, refresh metadata, reserve slots or create conversation bindings. Unknown/stale data stays unknown. Eligibility does not guarantee upstream success; key, member and allowance limits still apply and existing conversations keep their account.
Manual model tests
Administrators can open Accounts or API channels → Models and select Test beside a model. Each test sends a real generation request, consumes upstream quota and occupies capacity, with a 30-second timeout. The result shows success or a sanitized error and elapsed milliseconds for that resource at the time of testing. It does not validate a personal key's pool access or allowance. The local availability diagnostics above do not send generation requests.
Hidden capabilities appear in authenticated browser catalogs with a Hidden model label, while public client discovery and CC Switch suggestions remain filtered. Visibility does not change routing permissions, quota or capacity checks.
Internal model visibility
Antigravity models marked isInternal and Grok Build models marked hidden or _meta.hidden remain callable. Authenticated account, resource-group and personal-key dialogs show them after visible models, with a Hidden model label and alphabetical ordering within each group. GET /v1/models and CC Switch model pickers omit them. Explicit requests still enforce model policy, permissions, quota, allowances, capacity, cooldown and account lifecycle checks. Grok reads the authenticated subscription catalog and normalizes picker aliases to native routing IDs; older catalogs refresh automatically to acquire visibility metadata.