Models
Every agent and smith runs on a model id —
its model field. Model ids are namespaced provider.model
(openai.gpt-5.6-sol, anthropic.claude-opus-5, google.gemini-3.6-flash); the
provider is the prefix. The id is not gated: any model string that provider
serves works once a key for it resolves. The catalog below is the curated set
the console offers in the per-agent picker — flagship first, one provider per
group.
Catalog
Each provider's current top models plus the previous-generation flagship:
| Provider | Model id | |
|---|---|---|
| OpenAI | openai.gpt-5.6-sol | GPT-5.6 Sol — flagship |
| OpenAI | openai.gpt-5.6-terra | GPT-5.6 Terra — balanced |
| OpenAI | openai.gpt-5.6-luna | GPT-5.6 Luna — fast, low-cost |
| OpenAI | openai.gpt-5.5 | GPT-5.5 — previous flagship |
| Anthropic | anthropic.claude-opus-5 | Claude Opus 5 — flagship |
| Anthropic | anthropic.claude-opus-4-8 | Claude Opus 4.8 — previous flagship |
| Anthropic | anthropic.claude-sonnet-5 | Claude Sonnet 5 — balanced |
| Anthropic | anthropic.claude-haiku-4-5 | Claude Haiku 4.5 — fastest |
google.gemini-3.6-flash | Gemini 3.6 Flash — flagship | |
google.gemini-3.5-flash | Gemini 3.5 Flash — previous flagship | |
google.gemini-3.5-flash-lite | Gemini 3.5 Flash-Lite — high-volume | |
google.gemini-2.5-pro | Gemini 2.5 Pro — complex tasks |
The catalog is a convenience, not a constraint — set any namespaced id your
provider serves via the API (e.g. anthropic.claude-fable-5). Use the flagship
a tier needs; don't pay for one it doesn't.
Reasoning effort
Reasoning depth is a per-request dial in the standard OpenAI place:
reasoning_effort on POST /v1/chat/completions, reasoning: { "effort": … }
on POST /v1/responses — one of none, minimal, low, medium, high,
xhigh. Any other value is 400 invalid_reasoning_effort; omit the field and
the provider's default applies.
The tier is honored whatever provider backs the turn's model, mapped server-side to each provider's native control:
| Provider | What the tier becomes |
|---|---|
| OpenAI | reasoning_effort, passed as-is. |
| Anthropic | Adaptive thinking at the matching effort tier (minimal maps to low; xhigh to the highest tier the model supports); none turns thinking off. Claude models without adaptive thinking get a thinking budget sized to the tier. |
The matching Gemini thinking level (xhigh caps at high). |
A tier the upstream model itself doesn't support (OpenAI gates none and
xhigh to specific models) is the provider's call — its rejection surfaces as
the request's error rather than being silently degraded. One such rule:
Anthropic rejects thinking combined with a forced tool_choice on Claude
models without adaptive thinking ("Thinking may not be enabled when
tool_choice forces tool use") — send "none", or drop one of the two fields.
Keys: hosted or bring-your-own
A model runs on a key for its provider, resolved most-specific first:
- Smith — the smith's own key for that provider (
PUT /v1/smiths/{id}/model_keys/{provider}), so an end-user's inference bills their own provider account. See End-user keys. - BYOK — the tenant's own key for that provider (
PUT /v1/tenant/model_keys/{provider}), so the inference bills your own provider account. - Ingram-hosted — the platform key, used when no BYOK key is set (unless hosted keys are disabled).
Either of your own keys (1 or 2) means the provider bills you directly and your wallet is charged the platform fee alone, never the tokens — see Your own keys.
If none resolves, a run on that model fails with 422 model_key_missing.
A key that is present wins outright: a present-but-invalid smith key surfaces the provider's auth error on the run — it does not silently fall through to the tenant key (which would bill the tenant, the thing end-user keys exist to avoid). Only an absent key falls through. A smith or tenant BYOK Anthropic key always runs against Anthropic directly, never rerouted.
Setting a smith key needs the smith to exist first — provision it idempotently by external id, then set the key on the returned id (both server-side, both safe to repeat). See End-user keys for the two-step flow.
Prompt caching
Claude models cache automatically. On every request — including each step of a
multi-step agent turn — the API places Anthropic cache_control breakpoints on
the stable prompt prefix: tool definitions, system instructions, and the
conversation so far. Nothing to configure, and it applies to hosted and BYOK
Anthropic keys alike. Keep your instructions and tool set byte-stable and put
per-request content (timestamps, injected context) in the user turn, and the
prefix is written once and read cheaply on every subsequent step and follow-up
turn inside the cache window (5 minutes, refreshed on use).
The cache slices are visible on every run's usage: cache_read_tokens (the
prefix served from cache, billed at the provider's discounted cache-read rate)
and cache_write_tokens (the slice written this step, billed at the provider's
cache-write premium). See Metering for how they price into
cost. They also aggregate into the usage breakdown — the
cache hit rate (cache_read_tokens / input_tokens) per day, model, or end-user,
and a per-model view in the console — so you can spot a design change that
broke caching.
OpenAI and Gemini models cache server-side on the provider's side; reads show
up in cache_read_tokens the same way.
List what you can run
GET /v1/tenant/models returns the catalog plus, per model, whether a key
resolves (available) and whose (source: "byok", "hosted", or null):
# Authorization: tenant token with runs:read (server-side only)
curl https://api.cloud.ingram.tech/v1/tenant/models \
-H "Authorization: Bearer $IC_TOKEN" \
-H "IC-Api-Version: 2026-05-01"
# → { "data": [ { "id": "anthropic.claude-opus-5", "provider": "anthropic",
# "label": "Claude Opus 5", "available": true,
# "source": "hosted" }, … ],
# "providers": [ { "id": "openai", "label": "OpenAI",
# "base_url": true, "hosted": true }, … ] }
A provider with base_url: true (OpenAI) accepts a custom endpoint on its BYOK
key, so any OpenAI-compatible backend can stand in.
An OpenAI client reads the same catalog from GET /v1/models in OpenAI's own
list shape — filtered to models a key resolves for, so a picker built from it
only offers models that run. See Listing
models.
Set or remove a BYOK key (tenant-admin token only; the key is never echoed):
# Authorization: tenant-admin token (server-side only)
curl -X PUT https://api.cloud.ingram.tech/v1/tenant/model_keys/openai \
-H "Authorization: Bearer $IC_ADMIN_TOKEN" \
-H "IC-Api-Version: 2026-05-01" \
-H "Content-Type: application/json" \
-d '{ "api_key": "sk-…" }'
# → { "provider": "openai", "configured": true, "base_url": null }
In the console
Settings → Models lists the providers and which hold a key, and is where you add or remove BYOK keys. The per-agent model picker (on an agent or smith) lists this catalog grouped by provider and flags any model whose provider has no key configured — still selectable, but runs on it fail until a key is set.