Create a chat completion
const url = 'https://api.katara.com/v1/chat/completions';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"model":"katara/llama-3.1-8b-instruct@1","messages":[{"role":"user","content":"Explain a Merkle tree in two sentences."}],"max_tokens":200}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.katara.com/v1/chat/completions \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "model": "katara/llama-3.1-8b-instruct@1", "messages": [ { "role": "user", "content": "Explain a Merkle tree in two sentences." } ], "max_tokens": 200 }'Same request body as OpenAI chat completions. Set stream: true for server-sent events.
The reply carries a katara object with what you were charged and who served you.
In a stream it arrives as one final chunk with an empty choices array, after the content
and before data: [DONE].
Admission is checked before any work starts: the balance behind the key must cover the
maximum this request could cost (input estimate plus max_tokens at the offer price).
Otherwise the request is refused with insufficient_quota and nothing is charged.
Without a key the request is paid with x402: the answer is 402 with a quote in the
PAYMENT-REQUIRED header, and the same body sent again with a signed payment for one of
the quote’s entries in PAYMENT-SIGNATURE is served and settled on the Live network.
Pay per request with x402 describes the exchange.
Authorizations
Section titled “Authorizations”- bearerAuth
- None
Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Without a key, base64 of the x402 payment payload that signs the quote from a previous 402.
The same payload under the header name of the first x402 version, paid with exact.
Request Bodyrequired
Section titled “Request Bodyrequired”object
object
object
Bounds the output and therefore the maximum charge.
object
object
Example
{ "model": "katara/llama-3.1-8b-instruct@1", "messages": [ { "role": "user", "content": "Explain a Merkle tree in two sentences." } ], "max_tokens": 200}Responses
Section titled “Responses”The completion, or a server-sent event stream when stream is true.
object
Who served the request. <bundle>:<profile> for a named model,
cortex:<model> for a reply routed by katara/cortex@1.
object
object
Null when the reply is tool calls only.
Validated calls. Every entry has an id, a non-empty name and arguments that parse as a JSON object.
object
object
A JSON object document.
object
What this reply cost and who produced it.
object
The settled price, in USDC, as a decimal string. For a request paid with x402 it is the charge, the 0.025 USDC minimum included.
The Credits charge as a decimal string. This legacy field name is retained for compatibility; display Credits without a dollar sign.
On a request paid with x402, the payment that settles the reply.
object
The token paid.
The charge in the token’s base units, the same as amount in PAYMENT-RESPONSE.
The provider’s address, or managed when a vendor answered.
The concrete model behind every successful named-model or Cortex reply.
object
The address that served, or the managed identity.
True when a managed vendor answered.
named for a selected model, available, pinned, failover:<n> after n models failed before delivering, or managed:<why>.
What this reply cost and who produced it.
object
The settled price, in USDC, as a decimal string. For a request paid with x402 it is the charge, the 0.025 USDC minimum included.
The Credits charge as a decimal string. This legacy field name is retained for compatibility; display Credits without a dollar sign.
On a request paid with x402, the payment that settles the reply.
object
The token paid.
The charge in the token’s base units, the same as amount in PAYMENT-RESPONSE.
The provider’s address, or managed when a vendor answered.
The concrete model behind every successful named-model or Cortex reply.
object
The address that served, or the managed identity.
True when a managed vendor answered.
named for a selected model, available, pinned, failover:<n> after n models failed before delivering, or managed:<why>.
Example
{ "id": "chatcmpl-7f3a9c2e1b0d", "object": "chat.completion", "model": "katara/llama-3.1-8b-instruct@1", "system_fingerprint": "0xb353…:0x620b…", "choices": [ { "index": 0, "finish_reason": "stop", "message": { "role": "assistant", "content": "A Merkle tree hashes data in pairs up to one root hash…" } } ], "usage": { "prompt_tokens": 18, "completion_tokens": 52, "total_tokens": 70 }, "katara": { "cost_usdc": "0.000018", "provider": "0xfFe5…38DC" }}data: {chunk} lines ending with data: [DONE]: a role chunk, content deltas, each
tool call whole in one chunk, a finish chunk, a chunk with empty choices carrying
usage, then one carrying katara. A failure after content was sent ends with an
error chunk (stream_interrupted or provider_output_invalid) before [DONE].
Headers
Section titled “Headers”Request id for support and for matching usage records.
On a request paid with x402, base64 of { success, payer, transaction, network, amount }.
amount is the charge in the token’s base units, equal to katara.payment.amount, and is
absent on a stream, whose headers are sent before the cost is known; the stream’s final
chunk carries it. transaction is empty: settlement is submitted after the reply.
X-PAYMENT-RESPONSE carries the same value.
Malformed request, a feature the model does not support (feature_not_supported, with param naming the field for tool options), or a model that a key paid with account credits cannot use (model_requires_usdc).
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}Missing or unknown key (invalid_api_key). On the Test network a model call needs a Test key.
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}The key pays with account credits and the available credits cannot cover this request
(insufficient_credits). Add credits in the portal, then retry.
Without a key, a quote: PAYMENT-REQUIRED holds base64 of a PaymentRequired object and
the body is the same object. Sign it and send the same body again. A 402 that answers
a paid request with a quote is a new one, for the next candidate of katara/cortex@1
after the first failed before delivering. A payment that does not verify is refused with
payment_invalid and no PAYMENT-REQUIRED header.
object
object
For people. Wording may change.
Stable. Branch on this.
An x402 quote for one request.
object
The ways this request can be paid, for the same maximum. upto entries, where offered, come before exact. Sign one.
object
upto: a Permit2 transfer of at most amount, of which only the charge is pulled. exact: an EIP-3009 transfer of amount, with the difference refunded. Neither collects more than was signed.
The chain as a CAIP-2 id.
The USDC contract the authorization is for.
The most this request can cost, in the token’s base units. At least 25000 (0.025 USDC).
The settlement contract; the authorization’s to.
Validity to give the authorization.
object
The token’s EIP-712 domain name.
The token’s EIP-712 domain version.
exact only. The job this quote is bound to. It may be signed as the authorization nonce; a random nonce also works.
The job this quote is bound to.
upto only.
upto only. The address that settles; the signed witness names it.
The address paid for the reply.
The model the request named.
The model that will answer.
True when a vendor’s model will answer.
eip2612GasSponsoring, when present: the token takes EIP-2612 permits, and a permit for
Permit2 sent with an upto payment is submitted with the settlement at Katara’s cost.
object
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}Headers
Section titled “Headers”Base64 of the PaymentRequired object in the body. Present only on a quote.
The account is suspended (account_suspended), credit billing is paused for it (billing_suspended), or a Live key was sent to the Test network’s address under /test/ (wrong_environment).
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}Unknown model (model_not_found).
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}An x402 payment with upto from a wallet that has not approved Permit2 for the token and carries no permit (permit2_allowance_required). The quote stays valid; approve once, or pay it with exact.
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}The key pays with USDC and its spendable balance cannot cover this request
(insufficient_quota). Add USDC, or raise the budget cap, then retry.
Without a key, too many unpaid quotes from one address (quote_rate_limited): each may
ask for 10 at once and 30 a minute after that, and hold 16 open. Retry after Retry-After.
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}Headers
Section titled “Headers”Every provider tried answered with something the marketplace refused to deliver, such as a malformed tool call (provider_output_invalid), a Test key’s request did not reach the Test network (test_network_unavailable), or the provider quoted for an x402 payment on a named model failed before delivering (provider_failed; request a new quote). Nothing was charged. Retry after Retry-After.
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}Headers
Section titled “Headers”No provider can take the request right now (no_capacity); a named model is never substituted. Test has no managed fallback, so a Test request answers this whenever no Test provider is free. Retry after Retry-After, or ask katara/cortex@1.
object
object
For people. Wording may change.
Stable. Branch on this.
Example
{ "error": { "type": "invalid_request_error", "code": "invalid_api_key" }}