API reference
GET /models
List the curated model ids.
Krallo exposes a small, fixed catalogue of curated model ids. Each id is a stable public alias — the underlying provider and model version can change without breaking your integration, and Krallo never exposes the internal routing string a public id maps to. Use this endpoint to discover the valid ids, then pass one to the model field of Chat completions.
The response is deliberately OpenAI-shaped ({ "object": "list", "data": [ … ] }) so that OpenAI-compatible clients — opencode, Aider, Continue, nanocoder, or any SDK pointed at base URL https://exe.krallo.com/api/v1 — can probe it during startup and populate a model picker automatically.
Request
/api/v1/modelsAuthenticated with a bearer key. This endpoint requires a valid key only — it does not require any specific scope, unlike /chat/completions (which needs ai:invoke). It is rate-limited per key but not metered: listing models never draws down your credit balance.
See Authentication for how to send the key.
Parameters
None. The endpoint takes no path, query, or body parameters. Any query string is ignored, and a request body is not read.
| Header | Required | Description |
|---|---|---|
Authorization | required | Bearer krallo_live_… — a live API key. |
Example request
cURLcurl https://exe.krallo.com/api/v1/models \
-H "Authorization: Bearer $KRALLO_API_KEY"
Node.js
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.KRALLO_API_KEY,
baseURL: "https://exe.krallo.com/api/v1",
});
const models = await client.models.list();
for (const m of models.data) {
console.log(m.id); // krallo-chat, krallo-code, krallo-fast, krallo-reasoning
}
The curated model ids
Four public ids are available. All are owned_by krallo. Pick by the shape of the work, not by a specific underlying model — Krallo may re-point an alias to a newer or better model at any time.
| Model id | Best for |
|---|---|
krallo-code default |
Agentic coding — code generation, editing, and tool-driven work. This is the default model used by Chat completions when the model field is omitted or blank, and the default surfaced to opencode/Aider/Continue/nanocoder. |
krallo-chat |
General-purpose conversation and everyday assistant turns where balanced quality and cost matter more than deep reasoning. |
krallo-reasoning |
Hard, multi-step problems that benefit from extended, deliberate reasoning — analysis, planning, and complex logic. |
krallo-fast |
Low-latency, low-cost turns — classification, short rewrites, extraction, and other high-volume simple tasks where speed and price win. |
The ids in data are returned in alphabetical order: krallo-chat, krallo-code, krallo-fast, krallo-reasoning. Do not hard-code the ordering as a priority ranking — treat it as a set. The default model is always krallo-code regardless of list position.
Response
200 OK with an OpenAI-shaped list envelope. Each element is a minimal model object — Krallo returns only id, object, and owned_by; it does not return context windows, pricing, or created timestamps.
| Field | Type | Description |
|---|---|---|
object | string | Always "list". |
data | array | The curated model objects, alphabetically ordered by id. |
data[].id | string | The public model id you pass to model in a completion request. |
data[].object | string | Always "model". |
data[].owned_by | string | Always "krallo". |
Example response
{
"object": "list",
"data": [
{ "id": "krallo-chat", "object": "model", "owned_by": "krallo" },
{ "id": "krallo-code", "object": "model", "owned_by": "krallo" },
{ "id": "krallo-fast", "object": "model", "owned_by": "krallo" },
{ "id": "krallo-reasoning", "object": "model", "owned_by": "krallo" }
]
}
Every authenticated response also carries advisory rate-limit headers — X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset — reflecting your per-key budget.
Passing a model to chat completions
The id values from this list are exactly what Chat completions accepts in its model field:
{
"model": "krallo-reasoning",
"messages": [
{ "role": "user", "content": "Prove that the sum of two even integers is even." }
]
}
- Omitting or leaving
modelblank falls back tokrallo-code. - An unrecognized id is rejected by the completions endpoint with
400model_not_found; the error message lists the valid ids. CallingGET /modelsfirst avoids that round-trip.
Errors
The catalogue is fixed, so this endpoint has no request-validation errors of its own beyond the wrong HTTP method — the remaining failures come from the shared auth and rate-limit gates.
| Status | Code | When |
|---|---|---|
| 404 | not_found | The developer API is disabled for this deployment (the master switch is off). Every /api/v1 route 404s while dark. |
| 401 | unauthorized | No Authorization: Bearer credential was sent. |
| 401 | invalid_token | The bearer token does not match any known key. |
| 401 | token_revoked | The key has been revoked. |
| 401 | token_expired | The key has passed its expiry time. |
| 403 | app_disabled | The owning app is inactive or missing. |
| 403 | owner_suspended | The owner account (or a linked identity) is suspended. |
| 405 | method_not_allowed | Any method other than GET (or the CORS preflight OPTIONS, which returns 204). |
| 429 | — | The per-key rate limit (or the coarse per-IP auth-flood throttle) was exceeded. See Rate limits. |
This endpoint mixes error shapes. Its own 405 method_not_allowed is emitted in the OpenAI-shaped form ({ "error": { "message", "type" } }) so OpenAI SDKs parse it. The auth failures above use the standard developer-API envelope ({ "error": { "code", "message" }, "meta": { "request_id" } }), while the 429 is a flat { "error": "rate_limited", … } body with a Retry-After header. See Errors for the formats and guidance on handling them.