Documentación
Empieza con un solo prompt.
ScaledThought está pensado primero para agentes: tu agente se registra y hace el trabajo, y tú tienes un panel para facturación, claves y compañeros de equipo cuando lo quieras. Todo lo que hay aquí está escrito para ti y para el agente. La API es OpenAI-compatible (compatible con OpenAI): la mayor parte del código con el SDK de OpenAI funciona cambiando la URL base y la clave.
Inicio rápido
Lo más fácil: pídeselo a tu agente
Pega esto en Claude Code, Codex, Cursor o cualquier agente que pueda ejecutar comandos. Lee /llms.txt y ejecuta los pasos de configuración.
Enlaces directos a apps que tienes instaladas. Claude y Claude Code son marcas comerciales de Anthropic; Codex es una marca comercial de OpenAI. ScaledThought no está afiliada a ninguna de ellas ni cuenta con su respaldo.
Sin afiliación ni respaldo de Anthropic, OpenAI, Cursor ni de ningún editor de modelos. Claude, Claude Code, Codex, Cursor, OpenAI y los nombres de los modelos son marcas comerciales de sus respectivos titulares.
O ejecuta un comando
Crea una cuenta en la región de EE. UU., escribe ST_API_KEY y ST_BASE_URL en .env y lista los modelos disponibles allí. Puedes volver a ejecutarlo sin riesgo: si ya hay una clave, solo informa sobre la cuenta. La región de Canadá estará disponible próximamente; hasta que abra, su API no responde y --region ca falla con network_error.
npx -y scaledthought@0.3 init --region usCompra créditos
Cada llamada se paga con créditos prepagados, de $20 a $2,000 por recarga, como máximo $2,000 cada 24 horas y 2 enlaces de aprobación abiertos a la vez. El agente solicita una recarga y le envía a la persona a cargo el approval_url que recibe, y esa persona paga con tarjeta. Hasta que llegan los créditos, las llamadas devuelven 402 insufficient_credits. Más información en Créditos y aprobación.
npx -y scaledthought@0.3 billing topup --amount-usd 20Haz tu primera llamada
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"}]
}'Autenticación
Envía tu clave como token bearer. Las claves están limitadas a una región y pueden tener su propio presupuesto. La URL base es el host de tu región, guardado en .env como ST_BASE_URL: https://api.us.scaledthought.com/v1 (https://api.ca.scaledthought.com/v1, la de Canadá, estará disponible próximamente).
Authorization: Bearer $ST_API_KEY
Content-Type: application/jsonChat completions
POST /v1/chat/completions acepta el formato de solicitud de OpenAI. Usa un id de modelo de npx -y scaledthought@0.3 models --live o de /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
Define stream: true para recibir server-sent events en el formato delta de OpenAI.
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="")Llamadas a herramientas
Pasa tools en el formato de OpenAI. Los modelos que admiten llamadas a herramientas devuelven tool_calls estándar. El soporte y la calidad varían según el modelo, así que revisa la ficha del modelo antes de depender de ello.
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)Salida estructurada
Usa response_format con un JSON schema. En los modelos que lo admiten, la salida se restringe al schema durante la decodificación. Valida el resultado antes de depender de él.
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 y Codex
POST $ST_BASE_URL/responses habla la Responses API de OpenAI, así que los clientes que solo usan ese protocolo, como Codex, pueden usar ScaledThought como proveedor de modelos. Acepta input (una cadena, o mensajes y elementos function_call y function_call_output), instructions, herramientas de función y personalizadas (formato libre), tool_choice, max_output_tokens, text.format para salida JSON y stream: true (eventos de Responses, que terminan con response.completed o response.incomplete con su usage, o con response.failed con un error).
No tiene estado. No almacenamos respuestas, así que envía la conversación completa en input en cada turno (Codex lo hace) y omite previous_response_id, que devuelve 400 invalid_request; store siempre es false. Las herramientas alojadas, como la búsqueda de archivos, devuelven 400; una herramienta de búsqueda web se ignora. Las solicitudes sin max_output_tokens reciben como tope lo que el contexto del modelo deja libre después de tu prompt, como máximo 32,768 tokens.
La facturación es la misma que en chat completions: por token, según el uso que informa el servidor del modelo, pagada con tus créditos.
# ~/.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 lee ST_API_KEY del entorno, así que primero carga ./.env en la shell. wire_api = "responses" es obligatorio: ScaledThought sirve a Codex mediante la Responses API.
model_catalog_url le indica a Codex las ventanas de contexto de los modelos disponibles en tu región, para que compacte las sesiones largas a tiempo, y le da su herramienta de edición apply_patch. Se genera a partir de los modelos disponibles en cada solicitud; Codex envía tu clave con ella, así que mantenla en el mismo host que base_url (el de tu región).
Modelos y benchmarks
GET /v1/models lista los ids de los modelos disponibles en tu región, en el formato de OpenAI. Esa lista es la referencia de lo que puedes llamar. GET /v1/models/{id} devuelve el precio, la longitud de contexto, la fecha de lanzamiento, los resultados de benchmarks y el estado de un modelo, para que un agente pueda elegir sin que una persona lea una página web. Para buscar y filtrar, usa npx -y scaledthought@0.3 models --live o la herramienta MCP models_search. Para las personas, /pricing lista cada modelo disponible en EE. UU. con su precio, desde la misma API.
curl "$ST_BASE_URL/models"
curl "$ST_BASE_URL/models/deepseek-v4-1-flash"Regiones y retención
Cada clave está vinculada a su región. La región de EE. UU. está abierta ahora; Canadá (ca) estará disponible próximamente; su API no responde hasta que abra. Las solicitudes se atienden y se registran, y los registros de cuenta y de uso se almacenan, solo en ese país. Los pagos con tarjeta de todas las regiones los procesa Stripe en EE. UU. Los prompts y las completions no se almacenan después de devolver la respuesta y nunca se usan para entrenar. Los archivos de lotes y de ajuste fino se borran después de 30 días, o antes con DELETE /v1/files/{id}. Cada respuesta lleva x-st-region y x-st-data-retention: none. Consulta seguridad (o /security.json) y la Política de privacidad (en inglés).
Claves y presupuestos
Los agentes pueden crear claves con alcances limitados y límites de gasto diario estrictos. Cuando se alcanza un presupuesto, las llamadas devuelven 402 en lugar de gastar más. Una clave revocada deja de funcionar en unos 30 segundos.
npx -y scaledthought@0.3 keys create --name support-bot --budget-usd 40Alcances: son inference, read, keys, billing. Una clave solo puede dar a una clave nueva los alcances que ella misma tiene (si no, 403 scope_not_allowed). Vencimiento: envía expires_in (como "30d") o expires_at, hasta 365 días; después, la clave recibe 401 key_expired. Una clave nunca dura más que la clave que la creó.
Claves de subagente: con child: true, la clave nueva registra a la clave que la llama como su clave madre. Su presupuesto diario cabe en lo que le queda hoy a la clave madre, sus límites de tasa y su vencimiento no superan los de la madre, y solo puede gestionar sus propias subclaves. Revocar una clave revoca todas las claves que dependen de ella.
Rotación: POST /v1/keys/{id}/rotate crea una clave de reemplazo con el mismo nombre, alcances, presupuesto y límites, que se devuelve una sola vez. La clave anterior sigue funcionando durante grace (por defecto 24h, de "0" a "7d"). Autorrevocación: DELETE /v1/keys/self revoca la clave que hace la llamada y sus claves de subagente, sin necesidad de ningún alcance, para que un agente que sospecha una filtración pueda actuar de inmediato.
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-selfMás sobre cómo se protegen las claves y los datos: seguridad.
Créditos y aprobación
El uso se paga con créditos prepagados, de $20 a $2,000 por recarga, como máximo $2,000 cada 24 horas y 2 enlaces de aprobación abiertos a la vez. El agente solicita una recarga ($20 por defecto) y recibe un approval_url: una página de fondeo donde la persona a cargo confirma o cambia el monto, puede activar la recarga automática y paga con tarjeta. Los créditos llegan una vez confirmado el pago, y enviamos un recibo por correo. Nunca se cobra nada sin esa aprobación. Los créditos no vencen. Cuando se acaban, las solicitudes devuelven 402 insufficient_credits con el saldo y el monto necesario.
npx -y scaledthought@0.3 billing topup --amount-usd 20La recarga automática es opcional y recomendada: cuando el saldo baja de un umbral (por defecto $5), la tarjeta guardada agrega un monto fijo (por defecto $20), para que el agente nunca se detenga. La persona a cargo la activa en la página de fondeo de cualquier recarga, o sin comprar nada mediante un enlace de configuración de recarga automática (billing auto-reload setup), donde guarda una tarjeta. Las cargas están limitadas a $2,000 cada 24 horas. Activarla o subir cualquier límite requiere una nueva aprobación; desactivarla o reducirla, no. Si se rechaza una recarga, la recarga automática se desactiva sola y el siguiente 402 le indica al agente que obtenga un enlace nuevo. billing status muestra el saldo y las recargas pendientes; billing transactions lista cada compra, recarga y cargo.
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 offAvisos y webhooks
Las respuestas pueden llevar x-st-notice con códigos separados por comas: low_balance (una cuenta cuyo saldo es menor a $5). Un agente que vea uno debería decirle a la persona a cargo qué aprobar. GET /v1/account, MCP account_status, status y doctor muestran los mismos códigos con el texto que hay que transmitir.
Los webhooks envían las mismas señales de forma activa: balance.low, key.expiring y budget.exhausted. Los endpoints deben ser URL https públicas en el puerto 443. Cada POST lleva x-st-signature: t=…,v1=…, un HMAC-SHA256 de <t>.<raw body> con la clave secreta de firma del endpoint, que se muestra una sola vez cuando lo agregas. Las entregas van a tu URL dondequiera que esté alojada, incluso fuera de la región de tu cuenta, y solo llevan id, type, created_at, region, account_id y data: ids, montos enteros en micro-dólares, cantidades de días y marcas de tiempo, nunca prompts, nombres ni correos. data por evento: balance.low {balance_micros, threshold_micros}, key.expiring {key_id, expires_at}, budget.exhausted {scope, key_id, budget_micros, spent_today_micros, resets_at}. Las entregas fallidas se reintentan con backoff durante unos dos días.
npx -y scaledthought@0.3 webhooks add https://hooks.example.com/st --events balance.low,budget.exhaustedEncabezados de solicitud opcionales: x-st-app nombra tu app en los registros de uso (no se publica), y x-st-session mantiene una conversación en la misma réplica para reutilizar su prefijo en caché (solo en memoria, nunca se almacena). En Canadá, las solicitudes nunca se desvían a otro país: cuando todas las réplicas de un modelo están ocupadas, una solicitud espera brevemente y luego recibe 429 capacity_exhausted con Retry-After.
Inferencia por lotes
Sube un archivo JSONL de solicitudes y obtén resultados al 50% del precio normal. Los lotes se ejecutan en una ventana de finalización de 24 horas y por lo general terminan dentro de ella, pero no se garantiza que terminen a tiempo. Los endpoints de Files y Batches siguen los de OpenAI, así que client.batches.create funciona. Cada línea se valida desde el inicio, así que un archivo con errores falla en segundos.
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 con un modelo de embeddings (encuentra uno con models --live --modality embedding). La entrada puede ser una cadena o un arreglo de cadenas.
vecs = client.embeddings.create(model="<embedding-model-id>", input=["open weights", "served hot"])Ajuste fino
Entrena un adaptador LoRA con tus propios ejemplos. El resultado es un id de modelo privado que solo tu cuenta puede llamar, servido en las mismas réplicas que su modelo base y cobrado al precio por token del modelo base. Solo se pueden entrenar modelos base que se ejecutan en nuestras propias GPU en tu región, y los adaptadores no se pueden descargar. El entrenamiento se cobra por cada 1M de tokens de entrenamiento (tokens del dataset × épocas); la respuesta del trabajo incluye una estimación antes de que se ejecute nada. Se paga con créditos prepagados. Consulta precios.
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=[...])Servidor MCP
MCP remoto en el host de la API de tu región: https://api.us.scaledthought.com/mcp (https://api.ca.scaledthought.com/mcp, el de Canadá, estará disponible próximamente; Streamable HTTP, especificación 2026-07-28). Autentícate con tu clave de API como token bearer. MCP no puede crear cuentas: regístrate primero con npx -y scaledthought@0.3 init o POST /v1/accounts, y luego npx -y scaledthought@0.3 mcp muestra el comando y la configuración exactos para tu región. El agente obtiene estas herramientas:
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.
| Herramienta | Qué hace |
|---|---|
| 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
Ejecútala como npx -y scaledthought@0.3 <command>. La salida es JSON siempre que stdout no sea una terminal (o con --json), y los errores son una línea JSON en stderr con code, message y hint. Nunca pide datos de forma interactiva. Las claves se leen de ST_API_KEY o ./.env, nunca de 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.
| Comando | Qué hace |
|---|---|
| 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. |
Referencia de la API
- 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.
| Endpoint | Descripción |
|---|---|
| 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. |
Límites de tasa
Los límites son por clave. Al superar el límite, las llamadas devuelven 429 rate_limit_exceeded con un encabezado Retry-After en segundos. Hasta la primera compra de créditos de la cuenta, las claves pueden bajar sus límites pero no subirlos.
- Cuenta nueva
- Solicitudes / min: 60
- Tokens / min: 200,000
- Gasto: Hasta la primera compra de créditos: hasta 5 claves
- Créditos prepagados
- Solicitudes / min: 3,000
- Tokens / min: 5,000,000
- Gasto: Créditos que compra la persona a cargo, de $20 a $2,000 por recarga, $2,000 cada 24 h
- Escala
- Solicitudes / min: A medida
- Tokens / min: A medida
- Gasto: Habla con nosotros
| Plan | Solicitudes / min | Tokens / min | Gasto |
|---|---|---|---|
| Cuenta nueva | 60 | 200,000 | Hasta la primera compra de créditos: hasta 5 claves |
| Créditos prepagados | 3,000 | 5,000,000 | Créditos que compra la persona a cargo, de $20 a $2,000 por recarga, $2,000 cada 24 h |
| Escala | A medida | A medida | Habla con nosotros |
Errores
Los errores de la API son {"error":{"message","type","code"}}. Los errores de la CLI agregan un hint y terminan con un código distinto de cero.
- 400
- Código: invalid_request
- Qué hacer: Fix the field named in message. Don't retry unchanged.
- 400
- Código: invalid_body
- Qué hacer: Fix the field named in message. Don't retry unchanged.
- 400
- Código: invalid_json
- Qué hacer: Send valid JSON with `content-type: application/json`.
- 401
- Código: invalid_api_key
- Qué hacer: Key missing, mistyped or revoked. Load ST_API_KEY from .env; don't create a new account.
- 401
- Código: missing_api_key
- Qué hacer: Send `Authorization: Bearer $ST_API_KEY`.
- 401
- Código: key_expired
- Qué hacer: The key's expires_at has passed. Use another key, or create a new one with a key that has the keys scope.
- 400
- Código: invalid_expiry
- Qué hacer: expires_in or expires_at must be in the future and at most 365 days ahead. Send one, not both.
- 400
- Código: expiry_exceeds_parent
- Qué hacer: A key can't outlive the key that creates it. Ask for at most max_expires_at from the body.
- 403
- Código: scope_not_allowed
- Qué hacer: Ask only for scopes your own key has (allowed_scopes in the body).
- 400
- Código: budget_exceeds_parent
- Qué hacer: A sub-agent key's daily budget must fit in what its parent has left today (max_daily_budget_usd in the body).
- 400
- Código: limit_exceeds_parent
- Qué hacer: A sub-agent key's rate limits and budget can't exceed its parent's (or, when it changes itself, its own).
- 400
- Código: key_depth_exceeded
- Qué hacer: Sub-agent keys nest at most 16 levels. Create the key from a key higher up.
- 404
- Código: key_not_found
- Qué hacer: No such key on this account, or (for a sub-agent key) it's outside the keys you created.
- 409
- Código: key_not_active
- Qué hacer: Only an active key can be rotated. Create a new key instead.
- 402
- Código: budget_exceeded
- Qué hacer: This key's daily budget is spent. Resets 00:00 UTC. Tell your human; don't retry now.
- 402
- Código: insufficient_credits
- Qué hacer: 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
- Código: daily_cap_exceeded
- Qué hacer: An operator-set daily cap on this account is reached. Resets 00:00 UTC. Tell your human.
- 402
- Código: credits_required_for_batches
- Qué hacer: Batches are paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves.
- 402
- Código: credits_required_for_fine_tuning
- Qué hacer: Fine-tuning is paid from prepaid credits. Run `billing topup --amount-usd 20`, then retry once your human approves.
- 409
- Código: too_many_pending_topups
- Qué hacer: 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
- Código: daily_topup_limit
- Qué hacer: 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
- Código: approval_required
- Qué hacer: 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
- Código: free_tier_key_limit
- Qué hacer: Accounts that haven't bought credits have 5 active keys. Revoke one (`keys revoke <id>`) or buy credits.
- 402
- Código: free_tier_limit
- Qué hacer: Accounts that haven't bought credits can't raise budgets or rate limits. Buy credits first (`billing topup --amount-usd 20`).
- 409
- Código: fine_tuning_requires_self_hosted
- Qué hacer: 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
- Código: model_not_live
- Qué hacer: That model isn't served in your region yet. Pick one from `models --live`.
- 400
- Código: invalid_video_url
- Qué hacer: video_url must be a public https URL or a data:video/mp4 (webm, mov) URL within the size limit.
- 403
- Código: insufficient_scope
- Qué hacer: This key lacks the scope. Use the default key from init.
- 403
- Código: account_suspended
- Qué hacer: Stop. Tell your human to email hello@scaledthought.com.
- 404
- Código: model_not_found
- Qué hacer: Not live here. Pick an id from `models --live` or `GET $ST_BASE_URL/models`.
- 404
- Código: not_found
- Qué hacer: Wrong path. ST_BASE_URL already ends in /v1; append /chat/completions.
- 421
- Código: wrong_region
- Qué hacer: The key belongs to the other region. Use the `base_url` in the error body; remove any hard-coded host.
- 429
- Código: rate_limit_exceeded
- Qué hacer: Wait `Retry-After` seconds, then retry.
- 429
- Código: capacity_exhausted
- Qué hacer: 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
- Código: invalid_webhook_url
- Qué hacer: Webhook URLs must be public https endpoints on port 443 (no other port, no private, loopback or internal hosts). Fix the URL.
- 409
- Código: too_many_webhooks
- Qué hacer: An account has at most 5 webhook endpoints. Remove one (`webhooks remove <id>`) first.
- 404
- Código: webhook_not_found
- Qué hacer: No such webhook on this account. List them with `webhooks list`.
- 503
- Código: webhooks_unavailable
- Qué hacer: Webhooks aren't enabled in this region yet. Poll `GET /v1/account` for `notices` instead.
- 502
- Código: upstream_error
- Qué hacer: Transient. Retry with backoff, or use another model from `models --live`.
- 503
- Código: region_not_open
- Qué hacer: 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
- Código: service_unavailable
- Qué hacer: Transient. Retry in a few seconds.
- exit 1
- Código: no_key
- Qué hacer: No ST_API_KEY in the environment or ./.env. For an existing account run `login`; for a new one, `init --region us`.
- exit 1
- Código: key_exists
- Qué hacer: login: this folder already has a key. Use it, or pass --force to replace it.
- 428
- Código: authorization_pending
- Qué hacer: login --wait: your human hasn't typed the code yet. Run it again (codes last 10 minutes).
- 410
- Código: expired_token
- Qué hacer: The connect code expired. Run `login` again for a new one.
- 409
- Código: already_claimed
- Qué hacer: A connect code works once. Run `login` again (or ask for a new connect line).
- 403
- Código: access_denied
- Qué hacer: Your human denied the connection. Ask them before trying again.
- exit 1
- Código: region_mismatch
- Qué hacer: A key from the other region already exists here. Use it, or ask your human before creating a second account elsewhere.
- exit 1
- Código: wrong_region_endpoint
- Qué hacer: ST_BASE_URL / ST_API_URL points at the other region. Unset it. Nothing was sent.
- exit 1
- Código: network_error
- Qué hacer: Couldn't reach the API. Check the network, then retry.
- exit 1
- Código: bad_region
- Qué hacer: Use `--region us`. Canada (`ca`) is coming soon.
- exit 2
- Código: usage_error
- Qué hacer: Unknown command, flag or missing argument. Run the command with --help.
| Estado | Código | Qué hacer |
|---|---|---|
| 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. |