Skip to content

Create a chat completion

POST
/chat/completions
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.

PAYMENT-SIGNATURE
string

Without a key, base64 of the x402 payment payload that signs the quote from a previous 402.

X-PAYMENT
string

The same payload under the header name of the first x402 version, paid with exact.

Media typeapplication/json
object
model
required
string
messages
required
Array<object>
object
role
required
string
Allowed values: system user assistant tool
content
required
Any of:
string
name
string
tool_call_id
string
stream
boolean
max_tokens

Bounds the output and therefore the maximum charge.

integer
temperature
number
top_p
number
tools
Array<object>
object
tool_choice
response_format
object
stop
Example
{
"model": "katara/llama-3.1-8b-instruct@1",
"messages": [
{
"role": "user",
"content": "Explain a Merkle tree in two sentences."
}
],
"max_tokens": 200
}

The completion, or a server-sent event stream when stream is true.

object
id
required
string
object
required
string
Allowed value: chat.completion
model
required
string
system_fingerprint

Who served the request. <bundle>:<profile> for a named model, cortex:<model> for a reply routed by katara/cortex@1.

string
choices
required
Array<object>
object
index
integer
finish_reason
string
Allowed values: stop length tool_calls content_filter
message
object
role
string
content

Null when the reply is tool calls only.

string | null
tool_calls

Validated calls. Every entry has an id, a non-empty name and arguments that parse as a JSON object.

Array<object>
object
id
string
type
string
Allowed value: function
function
object
name
string
arguments

A JSON object document.

string
usage
required
object
prompt_tokens
integer
completion_tokens
integer
total_tokens
integer
katara
required
Any of:

What this reply cost and who produced it.

object
cost_usdc
required

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.

string
cost_usd

The Credits charge as a decimal string. This legacy field name is retained for compatibility; display Credits without a dollar sign.

string
billing_method
string
Allowed values: credits usdc
payment

On a request paid with x402, the payment that settles the reply.

object
scheme
string
Allowed values: upto exact
network
string
asset

The token paid.

string
amount

The charge in the token’s base units, the same as amount in PAYMENT-RESPONSE.

string
provider

The provider’s address, or managed when a vendor answered.

string
served

The concrete model behind every successful named-model or Cortex reply.

object
model
required
string
bundleId
string
provider

The address that served, or the managed identity.

string
managed

True when a managed vendor answered.

boolean
reason

named for a selected model, available, pinned, failover:<n> after n models failed before delivering, or managed:<why>.

string
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"
}
}
x-katara-request-id
string

Request id for support and for matching usage records.

PAYMENT-RESPONSE
string

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).

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
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.

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
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.

Media typeapplication/json
One of:
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
PAYMENT-REQUIRED
string

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).

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

Unknown model (model_not_found).

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
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.

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
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.

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
Retry-After
integer

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.

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
Retry-After
integer

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.

Media typeapplication/json
object
error
required
object
message
required

For people. Wording may change.

string
type
required
string
Allowed values: invalid_request_error insufficient_quota rate_limit_error server_error
code
required

Stable. Branch on this.

string
Allowed values: invalid_api_key model_not_found invalid_request feature_not_supported insufficient_quota account_suspended wrong_environment no_capacity test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited stateless_only unsupported_parameter provider_failed provider_rejected_request internal_error
param
string | null
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
Retry-After
integer