API reference

Estro speaks the OpenAI chat-completions dialect. Point any client, SDK, or IDE extension at it by changing the base URL and key.

Estro is available on your favorite platforms:

Pick a platform above to see its setup.

Authentication

Sign in to get a session token. Pass it as Authorization: Bearer <token> or X-Api-Key. Tokens last 30 days and can be revoked from your account page.

Run
curl https://estro.help/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"you","password":"yourpassword"}'

# Response:
# {"token":"eyJ...","user":{"id":1,"username":"you",...}}

Models

GET /v1/models returns this list live.

Model IDNameBest for
kali-gammaKali GammaDeep reasoning, multi-step work, large codebases
kali-betaKali BetaEveryday coding, writing, extended context
kali-epsilonKali EpsilonFast iteration, quick answers

Chat completions

POST /v1/chat/completions takes the standard OpenAI request shape. Set stream: true for server-sent events.

Run
curl -N https://estro.help/v1/chat/completions \
  -H "Authorization: Bearer $ESTRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kali-gamma",
    "stream": true,
    "messages": [
      {"role": "user", "content": "Refactor this function and explain the tradeoffs."}
    ]
  }'

Reasoning / chain-of-thought

When a model thinks before answering, stream chunks include reasoning_content deltas before the answer content. The chat UI renders these as a collapsible "Thought process" block.

Run
# Reasoning deltas appear as "reasoning_content" in each chunk's delta.
# The full response includes a collapsible thought process.

curl -N https://estro.help/v1/chat/completions \
  -H "Authorization: Bearer $ESTRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kali-beta",
    "stream": true,
    "messages": [{"role": "user", "content": "Prove that sqrt(2) is irrational."}]
  }'

# Stream events include:
# {"choices":[{"delta":{"reasoning_content":"Let me think..."}}]}
# {"choices":[{"delta":{"content":"Here is the proof..."}}]}

Request format

FieldTypeRequiredDescription
modelstringyeskali-gamma, kali-beta, or kali-epsilon
messagesarrayyesArray of {role, content} objects. Roles: system, user, assistant
streambooleannoDefault false. When true, response is SSE with data: lines
temperaturenumbernoSampling temperature, 0 to 2. Passed through to the model
max_tokensintegernoMaximum tokens in the response
top_pnumbernoNucleus sampling threshold
stopstring | arraynoStop sequences

Response format

Non-streaming responses return standard chat.completion JSON:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "model": "kali-gamma",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "Here is the refactored function...",
      "reasoning_content": "Let me analyze the code..."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 128,
    "total_tokens": 170
  }
}

Errors & limits

StatusCodeMeaning
400bad_requestMalformed JSON or empty messages
401noneMissing or expired session token
403email_unverifiedVerify your email address first
403bannedAccount suspended by admin
402billing_errorNo active plan. The API and Kali Gamma and Beta need one; see pricing
404model_not_foundUnknown model id
429rate_limit_exceededDaily request cap reached (resets at midnight UTC)
429usage_limit_reachedA 5-hour or weekly window is full; resets_in and Retry-After say when
502noneThe model provider is unavailable

Error bodies follow the OpenAI shape: {"error":{"message":"...","type":"invalid_request_error","code":"..."}}

All endpoints

Chat & models

MethodPathAuthDescription
POST/v1/chat/completionsrequiredChat completion (stream or JSON)
GET/v1/modelsnoList available models
GET/api/modelsnoModels with availability status
GET/api/usagerequiredYour daily usage + limit

Keys

Create a long-lived key from your account page or with these calls. A key works anywhere a session token does.

MethodPathAuthDescription
POST/api/auth/loginnoSign in, returns a session token
GET/api/account/api-keysrequiredList your keys (prefix only)
POST/api/account/api-keysrequiredCreate a key; the secret is returned once
DELETE/api/account/api-keys/:idrequiredRevoke a key

Rate limits

Model endpoints allow 120 requests a minute per account with a burst of 120, which is plenty for agent loops that fire many calls in sequence. Sign-in and password endpoints allow 10 a minute per IP. Over the limit you get 429 with a Retry-After header; the daily request cap is separate and resets at midnight UTC.