Models
Every run executes on a model. Set model on an agent (the default for all its runs) or on a single run. Omit it for the platform default: deepseek-v4-1-flash at high reasoning effort.
List models
client.models.list() returns every selectable model with USD prices per million tokens. It is the live source of truth: an id outside the list returns a 422 naming the valid choices, and new models become selectable with no SDK change (model is a plain string).
from m8tes import M8tes
client = M8tes()
for m in client.models.list().data:
print(m.id, m.name, m.pricing.input_per_mtok, m.pricing.output_per_mtok)Each entry:
Advanced: filters, aliases, and SDK field coverage
GET /api/v2/models accepts query filters:
?zdr=truefilters byzdr_supported?author=openaifilters by provider slug?curated=truereturns the short Platform list instead of the full catalog (100+ models)- On a Teams plan, runs use
deepseek-v4-1-flash, so the list shows only that model plus any your own connected provider serves. Setting another model returns403 TEAMS_MODEL_LOCKED. Enterprise accounts can use every model.
zdr in the response is a deprecated alias of zdr_supported (same value). The Python SDK's Model object exposes id, name, description, provider, default, max_effort, and pricing; read the ZDR fields from the raw API response.
Set the model
A per-run choice wins for that run only:
client.agents.create(name="support agent", instructions="...", model="sonnet")
client.agents.update(agent_id, model="opus") # change it later
client.agents.update(agent_id, model=None) # back to the platform default
# per-run override, agent default untouched
client.runs.create(agent_id=bot.id, message="draft the weekly report", model="opus")Resolution precedence, most specific first: per-run model, then the task's model, then the agent's, then the platform default.
A task can override its agent's model, which is the tool for a mixed workload: pin one high-stakes recurring task to a stronger model while the agent's routine work stays on the default.
task = client.tasks.create(
agent_id=bot.id,
instructions="review the contract and flag risk",
model="fable", # this task only; the agent is untouched
effort="max",
)
client.tasks.update(task.id, model=None) # clear the pin, inherit the agent's againeffort follows the same cascade and the same null-clears-the-pin rule.
Model examples
Use the live catalog for current models and prices.
Use your own provider subscription
Use your own model subscription for personal runs without user_id.
Provider terms and limits apply. Production runs with user_id use the prepaid balance.
How subscription requests are routed
Claude Code runs the agent and tools. For OpenAI, xAI, and Gemini, an isolated CLIProxyAPI process translates requests inside the sandbox. CLIProxyAPI is an independent third-party project.
1. Connect in the dashboard
Open Account → Model connections, choose Claude, OpenAI / Codex, Grok / xAI, or Gemini, and continue on the provider's own sign-in page. OpenAI and xAI show a one-time device code; Claude and Gemini ask you to paste the code from the provider page. m8tes saves the encrypted connection automatically. You never download or upload a token file.
After Connect succeeds, choosing Make default sets that provider as your account default. Platform mates still following the default then run on your plan; Keep as default leaves the current default unchanged. Disconnect clears a matching preference. To switch back to m8tes credits without disconnecting, call client.model_connections.clear_default() (DELETE /api/v2/model-connections/preferred-default).
Each connected provider also has its own Default model picker. Saving a model does not switch your preferred provider. Mates following Default use that provider's saved model when routed through the connection; an explicit Mate or run model keeps precedence. The setting applies to new runs, not an already-running turn. End-user-scoped API agents do not inherit these personal account defaults.
Use client.model_connections.set_default_model("claude", model="sonnet") to save a choice, or pass model=None to reset it. The corresponding endpoint is PATCH /api/v2/model-connections/{provider}/default-model with {"model": "sonnet"} or {"model": null}. Models must be known and belong to that connected provider. Connection responses include the saved default_model (null when following the platform's provider default) and the effective resolved_default_model.
OpenAI device authorization is a Codex beta feature. If the provider page says it is disabled, enable device-code authorization in your ChatGPT account or workspace settings and try again.
2. Connect through the API or SDK
OpenAI and xAI use device codes. Show the URL and code, then poll until connected. This example handles expiry and timeout:
import time
from m8tes import M8tes
client = M8tes()
auth = client.model_connections.authorize("xai")
print("Open:", auth.authorization_url)
print("Enter code:", auth.user_code)
deadline = time.monotonic() + 600
while auth.status == "pending":
if time.monotonic() >= deadline:
raise TimeoutError("Connection timed out. Run this script again.")
time.sleep(max(auth.interval_seconds, 1))
auth = client.model_connections.authorization_status("xai", auth.state)
if auth.status != "connected":
raise RuntimeError("Connection failed: " + auth.status)
print("Connected. Run the Grok example below.")For OpenAI, replace both "xai" values with "openai" and use a GPT/Codex model.
Claude and Gemini: exchange a pasted code
from m8tes import M8tes
client = M8tes()
auth = client.model_connections.authorize("gemini") # or client.model_connections.authorize("claude")
print("Open:", auth.authorization_url)
result = client.model_connections.complete_authorization(
auth.provider, auth.state, code=input("Paste the provider code: ")
)
print(result.status)Claude also accepts paste_claude(access_token=..., refresh_token=...) from a local Claude Code connection. Keep tokens out of source control.
Provider values are claude, openai, xai, and gemini. Pending sessions expire and are bound to the account that started them. List redacted connection status with GET /api/v2/model-connections; cancel a pending session with DELETE /api/v2/model-connections/{provider}/authorizations/{state}; disconnect with DELETE /api/v2/model-connections/{provider}.
3. Select a matching model
Set model="gpt-5.6-sol" for Codex, model="grok-4.6" for xAI, or model="gemini-3.6-flash" for Gemini. A run uses a subscription only when its model matches that provider; run.auth_method is "oauth_subscription" and run.auth_provider identifies "openai", "xai", "gemini", or "claude".
Credentials are account-level. They are never attached to a run carrying user_id, because that workload acts for an API end user rather than the credential owner. Disconnecting deletes m8tes' encrypted copy. Codex and Grok OAuth refreshes produced during a run are persisted back through an authenticated, run-scoped callback. Gemini tokens are refreshed at run start instead.
Reasoning effort
effort controls how hard the model reasons before acting: low | medium | high | xhigh | max. Higher effort means deeper reasoning and more tokens per run; lower is faster and cheaper. Omit it for the platform default: max on Claude models, high on all others.
Same shape as model: set it on the agent, override it per run, explicit null resets.
client.agents.create(name="intake bot", instructions="...", effort="low") # cheap, fast default
client.runs.create(agent_id=bot.id, message="untangle this billing bug", effort="max")
client.agents.update(agent_id, effort=None) # back to the platform defaultPrecedence mirrors model: per-run effort, then the task's effort, then the agent's, then the platform default. Resumes and replies inherit the run's effort, so a conversation keeps the depth it started with.
Ceilings, not errors. xhigh and max are Claude-only tiers. Other models clamp a higher request down to high, never reject it, so an agent set to max stays valid when a run overrides the model. Each model's ceiling is max_effort in the catalog. An invalid tier returns a 422 naming the valid choices.
Advanced: where effort takes effect
effort changes reasoning depth on Claude models and the GPT-5.6 family (gpt-5.6-sol / terra / luna). gpt-6-astra and grok-4.6 also honor effort via LiteLLM. The platform default (deepseek-v4-1-flash) pins high reasoning effort on its gateway route; other models (gpt-5.5, the Gemini Flash models, glm-5.2, minimax-m3, other DeepSeek models, kimi-k2-7-code, kimi-k3, qwen3.8-max, muse-spark-1.3 and grok-4.5) accept the field but currently run at their native depth.
Zero data retention (ZDR)
zdr_supported=true means at least one provider for that model supports zero data retention. It does not mean every route is ZDR, and it does not mean ZDR is enabled for your account. Retention protection applies only when routing lands on a ZDR-capable host and ZDR is enabled on the key. zdr_providers names the capable hosts.
zdr_supported=false means we have no confirmed zero-data-retention host for that model. Either none exists, or the model is not in the synced provider catalog. Either way treat it as may-retain: those models stay selectable on the API, so check the flag before sending customer data, or filter with GET /api/v2/models?zdr=true.
See Data Retention for the account-level picture.
Next: Agents · Data Retention