Dokumentation
Starte mit einem Prompt.
ScaledThought ist agent-first: Dein Agent registriert sich und erledigt die Arbeit, und du bekommst ein Dashboard für Abrechnung, Keys und Teammitglieder, wenn du es willst. Alles hier ist für dich und für den Agenten geschrieben. Die API ist OpenAI-compatible (OpenAI-kompatibel): Der meiste Code für das OpenAI SDK funktioniert, wenn du Basis-URL und Key änderst.
Schnellstart
Am einfachsten: Frag deinen Agenten
Füge das in Claude Code, Codex, Cursor oder einen anderen Agenten ein, der Befehle ausführen kann. Er liest /llms.txt und führt die Einrichtungsschritte aus.
Deep Links in Apps, die du installiert hast. Claude und Claude Code sind Marken von Anthropic; Codex ist eine Marke von OpenAI. ScaledThought ist mit keinem der beiden verbunden und wird von keinem der beiden unterstützt.
Nicht verbunden mit und nicht unterstützt von Anthropic, OpenAI, Cursor oder einem Modellanbieter. Claude, Claude Code, Codex, Cursor, OpenAI und Modellnamen sind Marken ihrer jeweiligen Inhaber.
Oder führ einen Befehl aus
Legt ein Konto in der Region USA an, schreibt ST_API_KEY und ST_BASE_URL in .env und listet die Modelle, die dort live sind. Du kannst ihn gefahrlos erneut ausführen: Ist schon ein Key vorhanden, meldet er nur das Konto. Die Region Kanada kommt demnächst; bis sie öffnet, antwortet ihre API nicht, und --region ca schlägt mit network_error fehl.
npx -y scaledthought@0.3 init --region usGuthaben kaufen
Jeder Aufruf wird aus Prepaid-Guthaben bezahlt, $20 bis $2,000 pro Aufladung, höchstens $2,000 pro 24 Stunden und 2 offene Freigabelinks gleichzeitig. Der Agent fordert eine Aufladung an und schickt die zurückgegebene approval_url an die Person, für die er arbeitet, und sie zahlt per Karte. Bis das Guthaben da ist, liefern Aufrufe 402 insufficient_credits. Mehr unter Guthaben & Freigabe.
npx -y scaledthought@0.3 billing topup --amount-usd 20Mach deinen ersten Aufruf
curl "$ST_BASE_URL/chat/completions" \
-H "Authorization: Bearer $ST_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "deepseek-v4-1-flash",
"messages": [{"role": "user", "content": "Hello"}]
}'Authentifizierung
Sende deinen Key als Bearer-Token. Keys gelten für eine Region und können ein eigenes Budget haben. Die Basis-URL ist der Host deiner Region, in .env als ST_BASE_URL gespeichert: https://api.us.scaledthought.com/v1 (Kanadas https://api.ca.scaledthought.com/v1 kommt demnächst).
Authorization: Bearer $ST_API_KEY
Content-Type: application/jsonChat Completions
POST /v1/chat/completions akzeptiert das Anfrageformat von OpenAI. Nutze eine Modell-ID aus npx -y scaledthought@0.3 models --live oder von /pricing.
curl "$ST_BASE_URL/chat/completions" \
-H "Authorization: Bearer $ST_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "deepseek-v4-1-flash",
"messages": [{"role": "user", "content": "Hello"}]
}'Streaming
Setze stream: true, um Server-Sent Events im Delta-Format von OpenAI zu empfangen.
stream = client.chat.completions.create(
model="deepseek-v4-1-flash",
messages=[{"role": "user", "content": "Write a haiku about open weights"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")Tool Calling
Übergib tools im OpenAI-Format. Modelle, die Tool Calling unterstützen, liefern standardmäßige tool_calls. Unterstützung und Qualität unterscheiden sich je nach Modell, also prüf die Modellkarte, bevor du dich darauf verlässt.
resp = client.chat.completions.create(
model="deepseek-v4-1-flash",
messages=[{"role": "user", "content": "Weather in Toronto?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
},
}],
)
print(resp.choices[0].message.tool_calls)Strukturierte Ausgabe
Nutze response_format mit einem JSON-Schema. Bei Modellen, die das unterstützen, wird die Ausgabe schon beim Decoding auf das Schema beschränkt. Prüf das Ergebnis, bevor du dich darauf verlässt.
resp = client.chat.completions.create(
model="deepseek-v4-1-flash",
messages=[{"role": "user", "content": invoice_text}],
response_format={
"type": "json_schema",
"json_schema": {"name": "invoice", "schema": {
"type": "object",
"properties": {"vendor": {"type": "string"}, "total": {"type": "number"}},
"required": ["vendor", "total"],
}},
},
)Responses API & Codex
POST $ST_BASE_URL/responses spricht die OpenAI Responses API, sodass Clients, die nur dieses Protokoll nutzen, etwa Codex, ScaledThought als Modellanbieter verwenden können. Der Endpunkt nimmt input (einen String oder Nachrichten, function_call- und function_call_output-Elemente), instructions, Function-Tools und Custom-Tools (Freiform), tool_choice, max_output_tokens, text.format für JSON-Ausgabe und stream: true (Responses-Events, die mit response.completed oder response.incomplete samt usage enden, oder mit response.failed samt error).
Er ist zustandslos. Wir speichern keine Antworten, also sende in jeder Runde die ganze Unterhaltung in input (Codex macht das) und lass previous_response_id weg, das 400 invalid_request liefert; store ist immer false. Gehostete Tools wie die Dateisuche liefern 400; ein Websuche-Tool wird ignoriert. Anfragen ohne max_output_tokens werden auf das begrenzt, was der Kontext des Modells nach deinem Prompt übrig lässt, höchstens 32.768 Tokens.
Die Abrechnung ist dieselbe wie bei Chat Completions: pro Token, nach der Nutzung, die der Modellserver meldet, bezahlt aus deinem Guthaben.
# ~/.codex/config.toml
model = "deepseek-v4-1-flash" # or a model id from `npx -y scaledthought@0.3 models --live`
model_provider = "scaledthought"
[model_providers.scaledthought]
name = "ScaledThought"
base_url = "https://api.us.scaledthought.com/v1" # your ST_BASE_URL
env_key = "ST_API_KEY"
wire_api = "responses"
model_catalog_url = "https://api.us.scaledthought.com/v1/codex/models" # same host (and region) as base_urlCodex liest ST_API_KEY aus der Umgebung, also lade ./.env zuerst in die Shell. wire_api = "responses" ist Pflicht: ScaledThought bedient Codex über die Responses API.
model_catalog_url teilt Codex die Kontextfenster der Modelle mit, die in deiner Region live sind, damit es lange Sitzungen rechtzeitig komprimiert, und gibt ihm sein Bearbeitungs-Tool apply_patch. Der Katalog wird bei jeder Anfrage aus den Live-Modellen erzeugt; Codex sendet dabei deinen Key mit, also halte ihn auf demselben Host wie base_url (dem deiner Region).
Modelle & Benchmarks
GET /v1/models listet die Modell-IDs, die in deiner Region live sind, im Format von OpenAI. Diese Liste ist maßgeblich dafür, was du aufrufen kannst. GET /v1/models/{id} liefert für ein Modell Preise, Kontextlänge, Veröffentlichungsdatum, Benchmark-Werte und Live-Status, sodass ein Agent wählen kann, ohne dass ein Mensch eine Webseite liest. Zum Suchen und Filtern nutze npx -y scaledthought@0.3 models --live oder das MCP-Tool models_search. Für Menschen listet /pricing jedes Modell, das in den USA live ist, mit seinem Preis, aus derselben API.
curl "$ST_BASE_URL/models"
curl "$ST_BASE_URL/models/deepseek-v4-1-flash"Regionen & Speicherung
Jeder Key ist an seine Region gebunden. Die Region USA ist jetzt offen; Kanada (ca) kommt demnächst, und bis zur Eröffnung antwortet seine API nicht. Anfragen werden nur in diesem Land bedient und protokolliert, und Konto- und Nutzungsdaten werden nur dort gespeichert. Kartenzahlungen für jede Region verarbeitet Stripe in den USA. Prompts und Completions werden nach der Rückgabe der Antwort nicht gespeichert und nie zum Training verwendet. Batch- und Fine-Tuning-Dateien werden nach 30 Tagen gelöscht, oder früher mit DELETE /v1/files/{id}. Jede Antwort trägt x-st-region und x-st-data-retention: none. Siehe Sicherheit (oder /security.json) und die Datenschutzerklärung (Englisch).
Keys & Budgets
Agenten können eingeschränkte Keys mit festen täglichen Ausgabelimits anlegen. Ist ein Budget erreicht, liefern Aufrufe 402, statt mehr auszugeben. Ein widerrufener Key funktioniert nach etwa 30 Sekunden nicht mehr.
npx -y scaledthought@0.3 keys create --name support-bot --budget-usd 40Scopes sind inference, read, keys, billing. Ein Key kann einem neuen Key nur Scopes geben, die er selbst hat (sonst 403 scope_not_allowed). Ablauf: Sende expires_in (etwa "30d") oder expires_at, bis zu 365 Tage; danach bekommt der Key 401 key_expired. Ein Key lebt nie länger als der Key, der ihn erstellt hat.
Sub-Agent-Keys: Mit child: true speichert der neue Key den aufrufenden Key als seinen Parent. Sein Tagesbudget passt in das, was dem Parent heute noch bleibt, seine Rate-Limits und sein Ablauf liegen nicht über denen des Parents, und er kann nur seine eigenen Sub-Keys verwalten. Wird ein Key widerrufen, werden alle Keys darunter mit widerrufen.
Rotation: POST /v1/keys/{id}/rotate erzeugt einen Ersatz mit demselben Namen, denselben Scopes, demselben Budget und denselben Limits, einmalig zurückgegeben. Der alte Key funktioniert noch für grace (Standard 24h, "0" bis "7d"). Selbstwiderruf: DELETE /v1/keys/self widerruft den aufrufenden Key und seine Sub-Agent-Keys, ohne dass ein Scope nötig ist, sodass ein Agent, der ein Leck vermutet, sofort handeln kann.
npx -y scaledthought@0.3 keys create --name sub-agent --child --scopes inference --budget-usd 2 --expires-in 12h
npx -y scaledthought@0.3 keys rotate key_… --grace 24h
npx -y scaledthought@0.3 keys revoke-selfMehr dazu, wie Keys und Daten geschützt sind: Sicherheit.
Guthaben & Freigabe
Die Nutzung wird aus Prepaid-Guthaben bezahlt, $20 bis $2,000 pro Aufladung, höchstens $2,000 pro 24 Stunden und 2 offene Freigabelinks gleichzeitig. Der Agent fordert eine Aufladung an (standardmäßig $20) und bekommt eine approval_url zurück: eine Aufladeseite, auf der die Person, für die er arbeitet, den Betrag bestätigt oder ändert, Auto-Reload einschalten kann und per Karte zahlt. Das Guthaben kommt an, sobald die Zahlung bestätigt ist, und wir schicken eine Quittung per E-Mail. Ohne diese Freigabe wird nie etwas belastet. Guthaben verfällt nicht. Ist es aufgebraucht, liefern Anfragen 402 insufficient_credits mit dem Saldo und dem benötigten Betrag.
npx -y scaledthought@0.3 billing topup --amount-usd 20Auto-Reload ist optional und empfohlen: Fällt der Saldo unter einen Schwellenwert (standardmäßig $5), lädt die gespeicherte Karte einen festen Betrag nach (standardmäßig $20), damit der Agent nie stehen bleibt. Die Person, für die der Agent arbeitet, schaltet es auf der Aufladeseite einer beliebigen Aufladung ein, oder ohne etwas zu kaufen über einen Einrichtungslink für Auto-Reload (billing auto-reload setup), wo sie eine Karte hinterlegt. Aufladungen sind auf $2.000 pro 24 Stunden begrenzt. Einschalten oder ein Limit erhöhen braucht eine neue Freigabe; Ausschalten oder Senken nicht. Wird eine Nachladung abgelehnt, schaltet sich Auto-Reload selbst ab, und der nächste 402 sagt dem Agenten, dass er einen neuen Link holen soll. billing status zeigt den Saldo und offene Aufladungen; billing transactions listet jeden Kauf, jede Nachladung und jede Belastung.
npx -y scaledthought@0.3 billing topup --amount-usd 20 --auto-reload-below 5 --auto-reload-amount 20
npx -y scaledthought@0.3 billing auto-reload setup --below 5 --amount 20 # no purchase: they save a card
npx -y scaledthought@0.3 billing auto-reload offHinweise & Webhooks
Antworten können x-st-notice mit kommagetrennten Codes tragen: low_balance (ein Konto, dessen Saldo unter $5 liegt). Ein Agent, der einen solchen Code sieht, sollte der Person, für die er arbeitet, sagen, was freizugeben ist. GET /v1/account, MCP account_status, status und doctor zeigen dieselben Codes mit dem Text, den der Agent weitergeben soll.
Webhooks liefern dieselben Signale per Push: balance.low, key.expiring und budget.exhausted. Endpunkte müssen öffentliche https-URLs auf Port 443 sein. Jeder POST trägt x-st-signature: t=…,v1=…, ein HMAC-SHA256 über <t>.<raw body> mit dem Signing-Secret des Endpunkts als Schlüssel, das einmal angezeigt wird, wenn du ihn hinzufügst. Zustellungen gehen an deine URL, wo auch immer sie gehostet ist, auch außerhalb der Region deines Kontos, und enthalten nur id, type, created_at, region, account_id und data: IDs, ganzzahlige Beträge in Mikrodollar, Anzahlen von Tagen und Zeitstempel, nie Prompts, Namen oder E-Mail-Adressen. data pro Event: balance.low {balance_micros, threshold_micros}, key.expiring {key_id, expires_at}, budget.exhausted {scope, key_id, budget_micros, spent_today_micros, resets_at}. Fehlgeschlagene Zustellungen werden mit Backoff etwa zwei Tage lang wiederholt.
npx -y scaledthought@0.3 webhooks add https://hooks.example.com/st --events balance.low,budget.exhaustedOptionale Request-Header: x-st-app benennt deine App in den Nutzungsdaten (nicht veröffentlicht), und x-st-session hält eine Unterhaltung auf derselben Replica, damit ihr gecachtes Präfix wiederverwendet wird (nur im Arbeitsspeicher, nie gespeichert). In Kanada weichen Anfragen nie in ein anderes Land aus: Sind alle Replicas eines Modells ausgelastet, wartet eine Anfrage kurz und bekommt dann 429 capacity_exhausted mit Retry-After.
Batch-Inferenz
Lade eine JSONL-Datei mit Anfragen hoch und bekomm die Ergebnisse für 50 % des normalen Preises. Batches laufen in einem Zeitfenster von 24 Stunden und sind in der Regel darin fertig, zugesichert ist das aber nicht. Die Endpunkte für Files und Batches folgen denen von OpenAI, also funktioniert client.batches.create. Jede Zeile wird vorab geprüft, sodass eine fehlerhafte Datei innerhalb von Sekunden scheitert.
batch_file = client.files.create(file=open("requests.jsonl", "rb"), purpose="batch")
batch = client.batches.create(
input_file_id=batch_file.id,
endpoint="/v1/chat/completions",
completion_window="24h",
)
# later
batch = client.batches.retrieve(batch.id)
results = client.files.content(batch.output_file_id).textEmbeddings
POST /v1/embeddings mit einem Embedding-Modell (finde eines mit models --live --modality embedding). Der Input kann ein String oder ein Array von Strings sein.
vecs = client.embeddings.create(model="<embedding-model-id>", input=["open weights", "served hot"])Fine-Tuning
Trainiere einen LoRA-Adapter mit deinen eigenen Beispielen. Das Ergebnis ist eine private Modell-ID, die nur dein Konto aufrufen kann, bedient auf denselben Replicas wie das Basismodell und zum Token-Preis des Basismodells abgerechnet. Trainieren lassen sich nur Basismodelle, die auf unseren eigenen GPUs in deiner Region laufen, und Adapter lassen sich nicht herunterladen. Training wird pro 1M Trainings-Tokens abgerechnet (Dataset-Tokens × Epochen); die Job-Antwort enthält eine Schätzung, bevor irgendetwas läuft. Bezahlt aus Prepaid-Guthaben. Siehe Preise.
f = client.files.create(file=open("examples.jsonl", "rb"), purpose="fine-tune")
job = client.fine_tuning.jobs.create(model="<base-id>", training_file=f.id, suffix="triage")
# poll
job = client.fine_tuning.jobs.retrieve(job.id)
resp = client.chat.completions.create(model=job.fine_tuned_model, messages=[...])MCP-Server
Remote-MCP auf dem API-Host deiner Region: https://api.us.scaledthought.com/mcp (Kanadas https://api.ca.scaledthought.com/mcp kommt demnächst; Streamable HTTP, Spezifikation 2026-07-28). Authentifiziere dich mit deinem API-Key als Bearer-Token. Über MCP lassen sich keine Konten anlegen: Registriere dich zuerst mit npx -y scaledthought@0.3 init oder POST /v1/accounts, dann gibt npx -y scaledthought@0.3 mcp den genauen Befehl und die Konfiguration für deine Region aus. Der Agent bekommt diese Tools:
npx -y scaledthought@0.3 mcp- account_status
- Region, spend, credit balance, auto-reload, key count and notices (tell your human about each). Call it first.
- account_settings
- Read or change account settings. ad_measurement: false opts the account out of ad measurement; any key can do it.
- keys_manage
- List, create, rotate or revoke keys (action: list | create | rotate | revoke | revoke_self). create and rotate return the full key once; create takes scopes, expires_in, child (a sub-agent key) and lives_in (where it will be stored); rotate takes grace. revoke_self revokes the key in use.
- budget_manage
- Set or clear a key's hard daily budget (USD) and rate limits.
- webhooks
- Signed HTTPS callbacks for balance.low, key.expiring and budget.exhausted (action: add | list | remove). add returns signing_secret once.
- models_search
- Models with prices, context, benchmarks and live status in your region (live_only, category, search).
- benchmarks_get
- Our own per-task scores and speed for one model.
- usage_query
- Requests, tokens and cost over the last N days, by model, day or key.
- billing_topup
- With amount_usd (and optional auto_reload): an approval_url for your human to buy credits. action: status | transactions | auto_reload_off.
- fine_tuning
- List, get, cancel fine-tuning jobs and their events; list your fine-tuned models.
- docs_search
- Where the docs, llms.txt and your base URL are.
| Tool | Was es tut |
|---|---|
| account_status | Region, spend, credit balance, auto-reload, key count and notices (tell your human about each). Call it first. |
| account_settings | Read or change account settings. ad_measurement: false opts the account out of ad measurement; any key can do it. |
| keys_manage | List, create, rotate or revoke keys (action: list | create | rotate | revoke | revoke_self). create and rotate return the full key once; create takes scopes, expires_in, child (a sub-agent key) and lives_in (where it will be stored); rotate takes grace. revoke_self revokes the key in use. |
| budget_manage | Set or clear a key's hard daily budget (USD) and rate limits. |
| webhooks | Signed HTTPS callbacks for balance.low, key.expiring and budget.exhausted (action: add | list | remove). add returns signing_secret once. |
| models_search | Models with prices, context, benchmarks and live status in your region (live_only, category, search). |
| benchmarks_get | Our own per-task scores and speed for one model. |
| usage_query | Requests, tokens and cost over the last N days, by model, day or key. |
| billing_topup | With amount_usd (and optional auto_reload): an approval_url for your human to buy credits. action: status | transactions | auto_reload_off. |
| fine_tuning | List, get, cancel fine-tuning jobs and their events; list your fine-tuned models. |
| docs_search | Where the docs, llms.txt and your base URL are. |
CLI
Führ sie als npx -y scaledthought@0.3 <command> aus. Die Ausgabe ist JSON, wann immer stdout kein Terminal ist (oder mit --json), und Fehler sind eine JSON-Zeile auf stderr mit code, message und hint. Nichts fragt interaktiv nach. Keys kommen aus ST_API_KEY oder ./.env, nie aus Flags.
- init --region us
- Account and key in the US. Writes ST_API_KEY and ST_BASE_URL to .env. Safe to re-run. Canada (ca) is coming soon.
- init --account Acme
- In a new folder on a machine with saved accounts: use that account with a new project key (init asks which when there are several). --new-account makes a separate account; --no-save keeps the key out of this machine's credential store.
- login --region us
- Connect to an existing account: prints a code your human types on the dashboard's connect page (opened in their browser). Then run login --wait.
- login --wait
- Waits about 90 s for your human to approve the code, then writes a new key to .env (never printed). Re-run on authorization_pending.
- login --code -
- Use a connect line made on the dashboard (its stl_ code on stdin, out of shell history): already approved, works once for 15 minutes.
- use "Side project"
- Point this folder at another account saved on this machine: a new project key in .env; the folder's old project key is revoked.
- init --region us --source a-rd
- The same, recording the campaign code of the scaledthought.com/go/<code> link that brought you (optional). An invalid code is dropped with a warning.
- models --live
- Models serving in your region now, newest first, with prices. Filter with --category or --search. The US list is also on /pricing.
- models <id>
- Pricing, context, benchmarks and live status for one model.
- chat -m <id> "prompt"
- Send one message to a model id from models --live.
- account
- Region, spend and credit balance.
- account ad-measurement off
- Opt out of ad measurement: nothing about the account is ever sent to an ad platform. on turns it back on.
- keys create --name <name> --budget-usd 5
- New key with a hard daily budget in USD. The key is printed once.
- keys create --name <name> --expires-in 30d --scopes inference,read
- A key that expires (at most 365d) with a subset of your key's scopes.
- keys create --name <name> --child --budget-usd 2
- A sub-agent key: scopes, budget, rate limits and expiry within your key's; revoked when your key is.
- keys list
- Your keys (prefixes only).
- keys rotate <id> --grace 24h
- Replace a key: the new key is printed once; the old one keeps working for the grace period (0 to 7d).
- keys revoke <id>
- Revoke a key and its sub-agent keys. They stop working within about 30 seconds.
- keys revoke-self
- Revoke the key you are using now (and its sub-agent keys), e.g. if it may have leaked. Irreversible.
- keys put github --repo <owner/repo> --budget-usd 2
- Put a new sub-agent key straight into a platform's secret store as ST_API_KEY, through its own CLI with the key on stdin (never printed). Destinations: github, vercel, fly, cloudflare, gcp, aws, k8s, doppler. The key is named after the place and records where it lives (lives_in). If storing fails, the new key is revoked.
- keys rotate --all --push --grace 1h
- Rotate every key that keys put stored somewhere and put each replacement in the same place; the old keys stop after the grace period. Prints no keys. One key: keys rotate <id> --push.
- connect opencode
- Point an OpenAI-compatible tool at ScaledThought: opencode and aider get the base URL and their own sub-agent key in their config (files 0600, key never printed); cursor and continue get steps for your human.
- usage --days 7 --by model
- Requests, tokens and cost by model, day or key.
- billing status
- Credit balance, auto-reload, pending top-ups.
- billing topup --amount-usd 20
- Buy prepaid credits ($20 to $2,000 per top-up, at most $2,000 per 24 hours and 2 open approval links at a time; default 20): opens the funding page in your human's browser, where they confirm the amount, can turn on auto-reload and pay.
- billing wait
- Returns as soon as your human pays the open top-up, with the new balance. Polls about 90 seconds a run; run it again on topup_pending.
- billing topup --amount-usd 20 --auto-reload-below 5 --auto-reload-amount 20
- Top up with auto-reload pre-selected on the funding page (your human can untick it).
- billing auto-reload setup --below 5 --amount 20
- Turn auto-reload on without buying anything: opens a page where your human saves a card. Then billing wait.
- billing auto-reload off
- Turn auto-reload off. No approval needed.
- billing transactions
- The credit ledger: purchases, auto-reloads, usage, batches, fine-tuning, refunds.
- batches create requests.jsonl
- Upload a JSONL file and start a batch at 50% off. Needs prepaid credits.
- fine-tune create examples.jsonl --model <base-id>
- Upload a dataset and start a LoRA job. Needs prepaid credits.
- webhooks add https://hooks.example.com/st --events balance.low,budget.exhausted
- Get a signed POST when the balance is low, a key is about to expire or a budget is spent (default: every event). Prints signing_secret once.
- webhooks list
- Your webhook endpoints.
- webhooks remove <id>
- Delete a webhook endpoint.
- doctor
- Checks the key in .env, its region, the account and its credit, and lists notices to tell your human.
- mcp
- Prints the `claude mcp add` command and JSON config for your region.
- dashboard --page billing
- Opens your human's dashboard (overview, billing, keys, members, connect) in their browser. If they aren't signed in, one click emails them a link.
- members
- Who can sign in to the account's dashboard: email, role (owner or member), status.
- status
- Per-model health in your region over the last hour, plus your account's notices when a key is set.
| Befehl | Was es tut |
|---|---|
| init --region us | Account and key in the US. Writes ST_API_KEY and ST_BASE_URL to .env. Safe to re-run. Canada (ca) is coming soon. |
| init --account Acme | In a new folder on a machine with saved accounts: use that account with a new project key (init asks which when there are several). --new-account makes a separate account; --no-save keeps the key out of this machine's credential store. |
| login --region us | Connect to an existing account: prints a code your human types on the dashboard's connect page (opened in their browser). Then run login --wait. |
| login --wait | Waits about 90 s for your human to approve the code, then writes a new key to .env (never printed). Re-run on authorization_pending. |
| login --code - | Use a connect line made on the dashboard (its stl_ code on stdin, out of shell history): already approved, works once for 15 minutes. |
| use "Side project" | Point this folder at another account saved on this machine: a new project key in .env; the folder's old project key is revoked. |
| init --region us --source a-rd | The same, recording the campaign code of the scaledthought.com/go/<code> link that brought you (optional). An invalid code is dropped with a warning. |
| models --live | Models serving in your region now, newest first, with prices. Filter with --category or --search. The US list is also on /pricing. |
| models <id> | Pricing, context, benchmarks and live status for one model. |
| chat -m <id> "prompt" | Send one message to a model id from models --live. |
| account | Region, spend and credit balance. |
| account ad-measurement off | Opt out of ad measurement: nothing about the account is ever sent to an ad platform. on turns it back on. |
| keys create --name <name> --budget-usd 5 | New key with a hard daily budget in USD. The key is printed once. |
| keys create --name <name> --expires-in 30d --scopes inference,read | A key that expires (at most 365d) with a subset of your key's scopes. |
| keys create --name <name> --child --budget-usd 2 | A sub-agent key: scopes, budget, rate limits and expiry within your key's; revoked when your key is. |
| keys list | Your keys (prefixes only). |
| keys rotate <id> --grace 24h | Replace a key: the new key is printed once; the old one keeps working for the grace period (0 to 7d). |
| keys revoke <id> | Revoke a key and its sub-agent keys. They stop working within about 30 seconds. |
| keys revoke-self | Revoke the key you are using now (and its sub-agent keys), e.g. if it may have leaked. Irreversible. |
| keys put github --repo <owner/repo> --budget-usd 2 | Put a new sub-agent key straight into a platform's secret store as ST_API_KEY, through its own CLI with the key on stdin (never printed). Destinations: github, vercel, fly, cloudflare, gcp, aws, k8s, doppler. The key is named after the place and records where it lives (lives_in). If storing fails, the new key is revoked. |
| keys rotate --all --push --grace 1h | Rotate every key that keys put stored somewhere and put each replacement in the same place; the old keys stop after the grace period. Prints no keys. One key: keys rotate <id> --push. |
| connect opencode | Point an OpenAI-compatible tool at ScaledThought: opencode and aider get the base URL and their own sub-agent key in their config (files 0600, key never printed); cursor and continue get steps for your human. |
| usage --days 7 --by model | Requests, tokens and cost by model, day or key. |
| billing status | Credit balance, auto-reload, pending top-ups. |
| billing topup --amount-usd 20 | Buy prepaid credits ($20 to $2,000 per top-up, at most $2,000 per 24 hours and 2 open approval links at a time; default 20): opens the funding page in your human's browser, where they confirm the amount, can turn on auto-reload and pay. |
| billing wait | Returns as soon as your human pays the open top-up, with the new balance. Polls about 90 seconds a run; run it again on topup_pending. |
| billing topup --amount-usd 20 --auto-reload-below 5 --auto-reload-amount 20 | Top up with auto-reload pre-selected on the funding page (your human can untick it). |
| billing auto-reload setup --below 5 --amount 20 | Turn auto-reload on without buying anything: opens a page where your human saves a card. Then billing wait. |
| billing auto-reload off | Turn auto-reload off. No approval needed. |
| billing transactions | The credit ledger: purchases, auto-reloads, usage, batches, fine-tuning, refunds. |
| batches create requests.jsonl | Upload a JSONL file and start a batch at 50% off. Needs prepaid credits. |
| fine-tune create examples.jsonl --model <base-id> | Upload a dataset and start a LoRA job. Needs prepaid credits. |
| webhooks add https://hooks.example.com/st --events balance.low,budget.exhausted | Get a signed POST when the balance is low, a key is about to expire or a budget is spent (default: every event). Prints signing_secret once. |
| webhooks list | Your webhook endpoints. |
| webhooks remove <id> | Delete a webhook endpoint. |
| doctor | Checks the key in .env, its region, the account and its credit, and lists notices to tell your human. |
| mcp | Prints the `claude mcp add` command and JSON config for your region. |
| dashboard --page billing | Opens your human's dashboard (overview, billing, keys, members, connect) in their browser. If they aren't signed in, one click emails them a link. |
| members | Who can sign in to the account's dashboard: email, role (owner or member), status. |
| status | Per-model health in your region over the last hour, plus your account's notices when a key is set. |
API-Referenz
- POST /v1/accounts
- Create an account in this host's region. Returns api_key (once) and base_url. No auth. Optional source: the campaign code from a /go/<code> link.
- POST /v1/chat/completions
- Chat, tools, JSON output, streaming. OpenAI-compatible.
- POST /v1/responses
- The OpenAI Responses API (Codex): function and custom tools, streaming. Stateless: send the whole conversation each turn; previous_response_id isn't supported.
- POST /v1/completions
- Raw text completion.
- POST /v1/embeddings
- Embeddings for embedding models.
- GET /v1/models
- Model ids live in this region (OpenAI list format). No auth.
- GET /v1/models/{id}
- One model: pricing, context, benchmarks and live_in_region. No auth.
- GET /v1/models/{id}/benchmarks
- Our own per-task scores and speed.
- GET /v1/account
- Plan, region, balance, spend, key count and notices (low_balance) with notice_text to relay to your human.
- PATCH /v1/account
- Account settings: {"ad_measurement": false} opts out of ad measurement (any key); true needs the keys or billing scope.
- GET /v1/keys
- List keys.
- POST /v1/keys
- Create a key: scopes (a subset of yours), daily_budget_usd, rate limits, expires_in or expires_at (max 365d), child: true for a sub-agent key, lives_in (where it will be stored, display only).
- POST /v1/keys/{id}/rotate
- Replace a key. The new key is returned once; the old one works for grace (default 24h, 0 to 7d).
- PATCH /v1/keys/{id}
- Change a key's name, daily budget, rate limits or lives_in (null clears it).
- DELETE /v1/keys/{id}
- Revoke a key and its sub-agent keys.
- DELETE /v1/keys/self
- The calling key revokes itself and its sub-agent keys. No scope needed.
- GET /v1/usage
- Requests, tokens and cost (days, group_by).
- GET /v1/billing
- Credit balance, auto-reload, pending top-ups and recent transactions.
- POST /v1/billing/topup
- Buy credits: {amount_usd, auto_reload?} returns an approval_url for your human.
- GET /v1/billing/topups/{id}
- One top-up's status (open, paid, expired, failed).
- PATCH /v1/billing/auto-reload
- Disable or lower auto-reload. Raising it needs a new top-up approval.
- GET /v1/billing/transactions
- The credit ledger, newest first (cursor).
- POST /v1/webhooks
- Add a webhook: {url (public https, port 443), events}. Returns signing_secret once. Billing scope; at most 5.
- GET /v1/webhooks
- Your webhook endpoints (status, last success and failure).
- DELETE /v1/webhooks/{id}
- Delete a webhook endpoint.
- POST /v1/files
- Upload JSONL (purpose=batch or fine-tune).
- POST /v1/batches
- Start a batch. GET /v1/batches/{id} to poll, POST /v1/batches/{id}/cancel to stop.
- POST /v1/fine_tuning/jobs
- Start a LoRA job from an uploaded purpose=fine-tune file.
- GET /v1/status
- Per-model health in this region, last hour.
- POST /v1/dashboard/link
- A URL for your human's dashboard (optional page), the owners, and a message to relay. billing or keys scope.
- POST /v1/device/codes
- Ask to connect to an existing account. No key. Returns device_code (secret), user_code for your human to type at verification_url, expires_in, interval.
- POST /v1/device/token
- Collect the key once approved: {device_code}, or {connect_code} (stl_…) for a dashboard connect line. 428 authorization_pending until then; one key per code, with the approver's scopes.
- GET /v1/members
- Who can sign in to the dashboard (email, role, status). read scope.
| Endpunkt | Beschreibung |
|---|---|
| POST /v1/accounts | Create an account in this host's region. Returns api_key (once) and base_url. No auth. Optional source: the campaign code from a /go/<code> link. |
| POST /v1/chat/completions | Chat, tools, JSON output, streaming. OpenAI-compatible. |
| POST /v1/responses | The OpenAI Responses API (Codex): function and custom tools, streaming. Stateless: send the whole conversation each turn; previous_response_id isn't supported. |
| POST /v1/completions | Raw text completion. |
| POST /v1/embeddings | Embeddings for embedding models. |
| GET /v1/models | Model ids live in this region (OpenAI list format). No auth. |
| GET /v1/models/{id} | One model: pricing, context, benchmarks and live_in_region. No auth. |
| GET /v1/models/{id}/benchmarks | Our own per-task scores and speed. |
| GET /v1/account | Plan, region, balance, spend, key count and notices (low_balance) with notice_text to relay to your human. |
| PATCH /v1/account | Account settings: {"ad_measurement": false} opts out of ad measurement (any key); true needs the keys or billing scope. |
| GET /v1/keys | List keys. |
| POST /v1/keys | Create a key: scopes (a subset of yours), daily_budget_usd, rate limits, expires_in or expires_at (max 365d), child: true for a sub-agent key, lives_in (where it will be stored, display only). |
| POST /v1/keys/{id}/rotate | Replace a key. The new key is returned once; the old one works for grace (default 24h, 0 to 7d). |
| PATCH /v1/keys/{id} | Change a key's name, daily budget, rate limits or lives_in (null clears it). |
| DELETE /v1/keys/{id} | Revoke a key and its sub-agent keys. |
| DELETE /v1/keys/self | The calling key revokes itself and its sub-agent keys. No scope needed. |
| GET /v1/usage | Requests, tokens and cost (days, group_by). |
| GET /v1/billing | Credit balance, auto-reload, pending top-ups and recent transactions. |
| POST /v1/billing/topup | Buy credits: {amount_usd, auto_reload?} returns an approval_url for your human. |
| GET /v1/billing/topups/{id} | One top-up's status (open, paid, expired, failed). |
| PATCH /v1/billing/auto-reload | Disable or lower auto-reload. Raising it needs a new top-up approval. |
| GET /v1/billing/transactions | The credit ledger, newest first (cursor). |
| POST /v1/webhooks | Add a webhook: {url (public https, port 443), events}. Returns signing_secret once. Billing scope; at most 5. |
| GET /v1/webhooks | Your webhook endpoints (status, last success and failure). |
| DELETE /v1/webhooks/{id} | Delete a webhook endpoint. |
| POST /v1/files | Upload JSONL (purpose=batch or fine-tune). |
| POST /v1/batches | Start a batch. GET /v1/batches/{id} to poll, POST /v1/batches/{id}/cancel to stop. |
| POST /v1/fine_tuning/jobs | Start a LoRA job from an uploaded purpose=fine-tune file. |
| GET /v1/status | Per-model health in this region, last hour. |
| POST /v1/dashboard/link | A URL for your human's dashboard (optional page), the owners, and a message to relay. billing or keys scope. |
| POST /v1/device/codes | Ask to connect to an existing account. No key. Returns device_code (secret), user_code for your human to type at verification_url, expires_in, interval. |
| POST /v1/device/token | Collect the key once approved: {device_code}, or {connect_code} (stl_…) for a dashboard connect line. 428 authorization_pending until then; one key per code, with the approver's scopes. |
| GET /v1/members | Who can sign in to the dashboard (email, role, status). read scope. |
Rate-Limits
Limits gelten pro Key. Über dem Limit liefern Aufrufe 429 rate_limit_exceeded mit einem Retry-After-Header in Sekunden. Bis zum ersten Guthabenkauf des Kontos können Keys ihre Limits senken, aber nicht erhöhen.
- Neues Konto
- Anfragen / Min.: 60
- Tokens / Min.: 200,000
- Ausgaben: Bis zum ersten Guthabenkauf: bis zu 5 Keys
- Prepaid-Guthaben
- Anfragen / Min.: 3,000
- Tokens / Min.: 5,000,000
- Ausgaben: Guthaben, das die Person kauft, für die dein Agent arbeitet: $20 bis $2,000 pro Aufladung, $2,000 pro 24 h
- Skalierung
- Anfragen / Min.: Individuell
- Tokens / Min.: Individuell
- Ausgaben: Sprich mit uns
| Plan | Anfragen / Min. | Tokens / Min. | Ausgaben |
|---|---|---|---|
| Neues Konto | 60 | 200,000 | Bis zum ersten Guthabenkauf: bis zu 5 Keys |
| Prepaid-Guthaben | 3,000 | 5,000,000 | Guthaben, das die Person kauft, für die dein Agent arbeitet: $20 bis $2,000 pro Aufladung, $2,000 pro 24 h |
| Skalierung | Individuell | Individuell | Sprich mit uns |
Fehler
API-Fehler haben die Form {"error":{"message","type","code"}}. CLI-Fehler ergänzen einen hint und enden mit einem Exit-Code ungleich null.
- 400
- Code: invalid_request
- Was zu tun ist: Fix the field named in message. Don't retry unchanged.
- 400
- Code: invalid_body
- Was zu tun ist: Fix the field named in message. Don't retry unchanged.
- 400
- Code: invalid_json
- Was zu tun ist: Send valid JSON with `content-type: application/json`.
- 401
- Code: invalid_api_key
- Was zu tun ist: Key missing, mistyped or revoked. Load ST_API_KEY from .env; don't create a new account.
- 401
- Code: missing_api_key
- Was zu tun ist: Send `Authorization: Bearer $ST_API_KEY`.
- 401
- Code: key_expired
- Was zu tun ist: The key's expires_at has passed. Use another key, or create a new one with a key that has the keys scope.
- 400
- Code: invalid_expiry
- Was zu tun ist: expires_in or expires_at must be in the future and at most 365 days ahead. Send one, not both.
- 400
- Code: expiry_exceeds_parent
- Was zu tun ist: A key can't outlive the key that creates it. Ask for at most max_expires_at from the body.
- 403
- Code: scope_not_allowed
- Was zu tun ist: Ask only for scopes your own key has (allowed_scopes in the body).
- 400
- Code: budget_exceeds_parent
- Was zu tun ist: A sub-agent key's daily budget must fit in what its parent has left today (max_daily_budget_usd in the body).
- 400
- Code: limit_exceeds_parent
- Was zu tun ist: A sub-agent key's rate limits and budget can't exceed its parent's (or, when it changes itself, its own).
- 400
- Code: key_depth_exceeded
- Was zu tun ist: Sub-agent keys nest at most 16 levels. Create the key from a key higher up.
- 404
- Code: key_not_found
- Was zu tun ist: No such key on this account, or (for a sub-agent key) it's outside the keys you created.
- 409
- Code: key_not_active
- Was zu tun ist: Only an active key can be rotated. Create a new key instead.
- 402
- Code: budget_exceeded
- Was zu tun ist: This key's daily budget is spent. Resets 00:00 UTC. Tell your human; don't retry now.
- 402
- Code: insufficient_credits
- Was zu tun ist: The credit balance can't cover the request (the body has balance_usd and required_usd). Run `billing topup --amount-usd 20` and send your human the approval_url.
- 402
- Code: daily_cap_exceeded
- Was zu tun ist: An operator-set daily cap on this account is reached. Resets 00:00 UTC. Tell your human.
- 402
- Code: credits_required_for_batches
- Was zu tun ist: Batches are paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves.
- 402
- Code: credits_required_for_fine_tuning
- Was zu tun ist: Fine-tuning is paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves.
- 409
- Code: too_many_pending_topups
- Was zu tun ist: The account already has 2 unpaid approval links. Ask your human to pay one (`billing status` lists them), or wait for them to expire.
- 409
- Code: daily_topup_limit
- Was zu tun ist: Top-ups are limited to $2,000 per account per rolling 24 hours, open links and auto-reloads included. Retry with at most available_usd from the body, or wait.
- 403
- Code: approval_required
- Was zu tun ist: Turning auto-reload on or raising it needs your human. Run `billing auto-reload setup --below <usd> --amount <usd>` (a link your human approves; nothing is bought) and give them the approval_url. Disabling or lowering needs no approval.
- 402
- Code: free_tier_key_limit
- Was zu tun ist: Accounts that haven't bought credits have 5 active keys. Revoke one (`keys revoke <id>`) or buy credits.
- 402
- Code: free_tier_limit
- Was zu tun ist: Accounts that haven't bought credits can't raise budgets or rate limits. Buy credits first (`billing topup --amount-usd 20`).
- 409
- Code: fine_tuning_requires_self_hosted
- Was zu tun ist: This base model isn't served on our own GPUs in your region, so it can't be fine-tuned here. Pick another base model.
- 409
- Code: model_not_live
- Was zu tun ist: That model isn't served in your region yet. Pick one from `models --live`.
- 400
- Code: invalid_video_url
- Was zu tun ist: video_url must be a public https URL or a data:video/mp4 (webm, mov) URL within the size limit.
- 403
- Code: insufficient_scope
- Was zu tun ist: This key lacks the scope. Use the default key from init.
- 403
- Code: account_suspended
- Was zu tun ist: Stop. Tell your human to email hello@scaledthought.com.
- 404
- Code: model_not_found
- Was zu tun ist: Not live here. Pick an id from `models --live` or `GET $ST_BASE_URL/models`.
- 404
- Code: not_found
- Was zu tun ist: Wrong path. ST_BASE_URL already ends in /v1; append /chat/completions.
- 421
- Code: wrong_region
- Was zu tun ist: The key belongs to the other region. Use the `base_url` in the error body; remove any hard-coded host.
- 429
- Code: rate_limit_exceeded
- Was zu tun ist: Wait `Retry-After` seconds, then retry.
- 429
- Code: capacity_exhausted
- Was zu tun ist: Canada: every replica of the model is busy and Canadian requests never overflow to another country. Wait `Retry-After` seconds and retry with backoff, or use another model.
- 400
- Code: invalid_webhook_url
- Was zu tun ist: Webhook URLs must be public https endpoints on port 443 (no other port, no private, loopback or internal hosts). Fix the URL.
- 409
- Code: too_many_webhooks
- Was zu tun ist: An account has at most 5 webhook endpoints. Remove one (`webhooks remove <id>`) first.
- 404
- Code: webhook_not_found
- Was zu tun ist: No such webhook on this account. List them with `webhooks list`.
- 503
- Code: webhooks_unavailable
- Was zu tun ist: Webhooks aren't enabled in this region yet. Poll `GET /v1/account` for `notices` instead.
- 502
- Code: upstream_error
- Was zu tun ist: Transient. Retry with backoff, or use another model from `models --live`.
- 503
- Code: region_not_open
- Was zu tun ist: The Canada region isn't open yet. Check with your human that US hosting is acceptable, then use `init --region us` and the US host.
- 503
- Code: service_unavailable
- Was zu tun ist: Transient. Retry in a few seconds.
- exit 1
- Code: no_key
- Was zu tun ist: No ST_API_KEY in the environment or ./.env. For an existing account run `login`; for a new one, `init --region us`.
- exit 1
- Code: key_exists
- Was zu tun ist: login: this folder already has a key. Use it, or pass --force to replace it.
- 428
- Code: authorization_pending
- Was zu tun ist: login --wait: your human hasn't typed the code yet. Run it again (codes last 10 minutes).
- 410
- Code: expired_token
- Was zu tun ist: The connect code expired. Run `login` again for a new one.
- 409
- Code: already_claimed
- Was zu tun ist: A connect code works once. Run `login` again (or ask for a new connect line).
- 403
- Code: access_denied
- Was zu tun ist: Your human denied the connection. Ask them before trying again.
- exit 1
- Code: region_mismatch
- Was zu tun ist: A key from the other region already exists here. Use it, or ask your human before creating a second account elsewhere.
- exit 1
- Code: wrong_region_endpoint
- Was zu tun ist: ST_BASE_URL / ST_API_URL points at the other region. Unset it. Nothing was sent.
- exit 1
- Code: network_error
- Was zu tun ist: Couldn't reach the API. Check the network, then retry.
- exit 1
- Code: bad_region
- Was zu tun ist: Use `--region us`. Canada (`ca`) is coming soon.
- exit 2
- Code: usage_error
- Was zu tun ist: Unknown command, flag or missing argument. Run the command with --help.
| Status | Code | Was zu tun ist |
|---|---|---|
| 400 | invalid_request | Fix the field named in message. Don't retry unchanged. |
| 400 | invalid_body | Fix the field named in message. Don't retry unchanged. |
| 400 | invalid_json | Send valid JSON with `content-type: application/json`. |
| 401 | invalid_api_key | Key missing, mistyped or revoked. Load ST_API_KEY from .env; don't create a new account. |
| 401 | missing_api_key | Send `Authorization: Bearer $ST_API_KEY`. |
| 401 | key_expired | The key's expires_at has passed. Use another key, or create a new one with a key that has the keys scope. |
| 400 | invalid_expiry | expires_in or expires_at must be in the future and at most 365 days ahead. Send one, not both. |
| 400 | expiry_exceeds_parent | A key can't outlive the key that creates it. Ask for at most max_expires_at from the body. |
| 403 | scope_not_allowed | Ask only for scopes your own key has (allowed_scopes in the body). |
| 400 | budget_exceeds_parent | A sub-agent key's daily budget must fit in what its parent has left today (max_daily_budget_usd in the body). |
| 400 | limit_exceeds_parent | A sub-agent key's rate limits and budget can't exceed its parent's (or, when it changes itself, its own). |
| 400 | key_depth_exceeded | Sub-agent keys nest at most 16 levels. Create the key from a key higher up. |
| 404 | key_not_found | No such key on this account, or (for a sub-agent key) it's outside the keys you created. |
| 409 | key_not_active | Only an active key can be rotated. Create a new key instead. |
| 402 | budget_exceeded | This key's daily budget is spent. Resets 00:00 UTC. Tell your human; don't retry now. |
| 402 | insufficient_credits | The credit balance can't cover the request (the body has balance_usd and required_usd). Run `billing topup --amount-usd 20` and send your human the approval_url. |
| 402 | daily_cap_exceeded | An operator-set daily cap on this account is reached. Resets 00:00 UTC. Tell your human. |
| 402 | credits_required_for_batches | Batches are paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves. |
| 402 | credits_required_for_fine_tuning | Fine-tuning is paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves. |
| 409 | too_many_pending_topups | The account already has 2 unpaid approval links. Ask your human to pay one (`billing status` lists them), or wait for them to expire. |
| 409 | daily_topup_limit | Top-ups are limited to $2,000 per account per rolling 24 hours, open links and auto-reloads included. Retry with at most available_usd from the body, or wait. |
| 403 | approval_required | Turning auto-reload on or raising it needs your human. Run `billing auto-reload setup --below <usd> --amount <usd>` (a link your human approves; nothing is bought) and give them the approval_url. Disabling or lowering needs no approval. |
| 402 | free_tier_key_limit | Accounts that haven't bought credits have 5 active keys. Revoke one (`keys revoke <id>`) or buy credits. |
| 402 | free_tier_limit | Accounts that haven't bought credits can't raise budgets or rate limits. Buy credits first (`billing topup --amount-usd 20`). |
| 409 | fine_tuning_requires_self_hosted | This base model isn't served on our own GPUs in your region, so it can't be fine-tuned here. Pick another base model. |
| 409 | model_not_live | That model isn't served in your region yet. Pick one from `models --live`. |
| 400 | invalid_video_url | video_url must be a public https URL or a data:video/mp4 (webm, mov) URL within the size limit. |
| 403 | insufficient_scope | This key lacks the scope. Use the default key from init. |
| 403 | account_suspended | Stop. Tell your human to email hello@scaledthought.com. |
| 404 | model_not_found | Not live here. Pick an id from `models --live` or `GET $ST_BASE_URL/models`. |
| 404 | not_found | Wrong path. ST_BASE_URL already ends in /v1; append /chat/completions. |
| 421 | wrong_region | The key belongs to the other region. Use the `base_url` in the error body; remove any hard-coded host. |
| 429 | rate_limit_exceeded | Wait `Retry-After` seconds, then retry. |
| 429 | capacity_exhausted | Canada: every replica of the model is busy and Canadian requests never overflow to another country. Wait `Retry-After` seconds and retry with backoff, or use another model. |
| 400 | invalid_webhook_url | Webhook URLs must be public https endpoints on port 443 (no other port, no private, loopback or internal hosts). Fix the URL. |
| 409 | too_many_webhooks | An account has at most 5 webhook endpoints. Remove one (`webhooks remove <id>`) first. |
| 404 | webhook_not_found | No such webhook on this account. List them with `webhooks list`. |
| 503 | webhooks_unavailable | Webhooks aren't enabled in this region yet. Poll `GET /v1/account` for `notices` instead. |
| 502 | upstream_error | Transient. Retry with backoff, or use another model from `models --live`. |
| 503 | region_not_open | The Canada region isn't open yet. Check with your human that US hosting is acceptable, then use `init --region us` and the US host. |
| 503 | service_unavailable | Transient. Retry in a few seconds. |
| exit 1 | no_key | No ST_API_KEY in the environment or ./.env. For an existing account run `login`; for a new one, `init --region us`. |
| exit 1 | key_exists | login: this folder already has a key. Use it, or pass --force to replace it. |
| 428 | authorization_pending | login --wait: your human hasn't typed the code yet. Run it again (codes last 10 minutes). |
| 410 | expired_token | The connect code expired. Run `login` again for a new one. |
| 409 | already_claimed | A connect code works once. Run `login` again (or ask for a new connect line). |
| 403 | access_denied | Your human denied the connection. Ask them before trying again. |
| exit 1 | region_mismatch | A key from the other region already exists here. Use it, or ask your human before creating a second account elsewhere. |
| exit 1 | wrong_region_endpoint | ST_BASE_URL / ST_API_URL points at the other region. Unset it. Nothing was sent. |
| exit 1 | network_error | Couldn't reach the API. Check the network, then retry. |
| exit 1 | bad_region | Use `--region us`. Canada (`ca`) is coming soon. |
| exit 2 | usage_error | Unknown command, flag or missing argument. Run the command with --help. |