Skip to content
This is the public test network documentation. Everything here runs on Avalanche Fuji with test USDC.

Katara Cortex

katara/cortex@1 is the model to use unless you need a specific one. Send it any chat request and Katara picks a model for it: whichever candidate is available, fits the task, and costs the least under a published ceiling. When a provider drops out between one message and the next, the next message is still answered.

Cortex chooses among the catalog models listed under its candidates on /v1/models. Marketplace models come first. A managed model, one that Katara serves through a vendor’s API rather than a provider’s node, is picked only when no marketplace provider can take the request at all. A vendor never wins on price against a provider that can serve you.

Every candidate is checked against your request first. A request with tools only goes to a model certified for tools; a response_format nobody serves is refused with feature_not_supported, the same answer a named model would give.

  1. Availability: a model with no provider that passes the selection filters is skipped, and a model whose recent requests mostly failed ranks after the ones that answer, until it answers again.
  2. The conversation: a conversation that Cortex already served stays on the same model, and on the same provider or vendor, while that one is available, so an agent loop sees one model for the whole session. The conversation is recognised by your key and the first message of the transcript.
  3. Task fit: katara.task in the request (code, chat, or extract) says what you are doing. Without it, a request that carries tools counts as code. Models are tagged with the tasks they are preferred for.
  4. Price: among what is left, the cheapest; then the faster of two at the same price.

Every reply, from a provider or from a vendor, passes the same validation before you see it. A reply with nothing in it, a tool call that cannot be delivered, or a stop the runtime did not mean is refused and the next candidate is tried; nothing is charged for a refused reply.

{
"model": "katara/cortex@1",
"messages": [{ "role": "user", "content": "Refactor this function." }],
"katara": { "task": "code" }
}

The katara block is read by Cortex and removed before the request reaches any model.

The reply’s model is katara/cortex@1, the id you asked for. system_fingerprint is cortex:<model> naming the concrete model. The katara object carries a served block:

"katara": {
"cost_usdc": "0.000018",
"provider": "0xfFe5…38DC",
"served": {
"model": "katara/qwen3-coder-30b-a3b@1",
"bundleId": "0x80ab…",
"provider": "0xfFe5…38DC",
"managed": false,
"reason": "available"
}
}

reason is available when the first choice served, failover:N when N earlier models failed before delivering anything, and starts with managed: when a vendor answered. The signed receipt behind the charge names the concrete model and provider, never Cortex.

You pay the price of the model that served you. Cortex has a published ceiling per million input and output tokens, shown as its pricing on /v1/models with basis: ceiling; a model priced above the ceiling is not a candidate. There is no extra charge for routing.

Only before anything was delivered. If the first model’s providers all fail before the first token, the next model is tried. If a provider fails after it has already sent part of a reply, the reply ends with an error chunk and nothing is charged; Cortex does not switch models in the middle of an answer. Send the message again.

For wallet-paid requests, where one payment is bound to one provider, a failure before delivery answers with a fresh 402 challenge for the next candidate instead. Sign it and retry; the first authorization expires unused.

Ask for a specific model when you need exactly that model. A named model is served by that model or refused with 503 no_capacity; it is never substituted. That holds for managed models too: katara/glm-5.3-flash@1 named directly is answered by that vendor or not at all, and a marketplace model named directly never falls back to a vendor.

A vendor sees the prompt it answers. If that is not acceptable, an API key can be marked marketplace-only: Cortex then serves it from providers or refuses it, and a managed model named with that key is refused. Named marketplace models are unaffected because they never reach a vendor.