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/cortex", "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.

Any model name is accepted and served by Katara Cortex; the reply names katara/cortex. Without a key the request may instead name katara/cortex-genius or katara/cortex-smart, which fix the model and which the reply names; with a key those two are refused with model_requires_x402. The reply carries a katara object with what you were charged. Top-level katara_web_search, or OpenAI’s web_search_options, lets the model search the web (Web search). Stop sequences are applied by Katara: the reply ends before the first match. 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 402 insufficient_quota and nothing is charged.

Fields current OpenAI clients send that change nothing a Katara reply can contain (metadata, store, service_tier, safety_identifier, verbosity, moderation, prediction, prompt_cache_options, prompt_cache_retention, modalities: ["text"]) are accepted and dropped, as is user, which never reaches a provider. seed reaches a model that reads it. prompt_cache_key keeps a conversation on the model holding its prompt in cache.

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

Lowered to a model’s own cap when it is above it.

number
<= 2
top_p
number
tools

Function tools, and custom tools that take one string of input. Names up to 128 characters.

Array<object>
object
tool_choice
parallel_tool_calls

False gets at most one tool call per reply.

boolean
response_format
object
stop

Applied by Katara; the reply ends before the first match.

katara_web_search

Lets the model search the web, at most five times per request, each successful search charged 0.006 USDC or credits; a request that ends without an answer is charged nothing for its searches or the model calls after the first search, which run on managed models only. The first call routes as any request does, Katara Community included, and stays charged when Katara Community served it. Not offered without a key, on the Test network, on a marketplace-only key, or with tool_choice none or a named function.

object
max_uses
integer
>= 1 <= 5
allowed_domains
Array<string>
blocked_domains

Not with allowed_domains.

Array<string>
user_location
object
key
additional properties
any
web_search_options

OpenAI’s web search option. It turns on katara_web_search with its user_location.approximate; katara_web_search wins when both are sent.

object
katara

Read by Katara and removed before the request reaches any model.

object
task
string
Allowed values: code chat extract
session

Opaque routing token from the last served reply; it grants no payment authority.

string
reset_session

Start a new routing session explicitly.

boolean
summary

A short step summary, limited to 80 words by Katara Cortex.

string
community
boolean
knowledge
boolean
compaction

When the request’s input passes trigger_tokens, Katara has a fast model summarise every turn before the last keep_turns, sends the model the summary in their place, and returns it as katara.compaction in the reply. Send that summary instead of those turns from then on. The summary is billed to you as its own request and shown in katara.compaction.summary. Not offered without an API key.

object
trigger_tokens
integer
default: 150000 >= 8192
keep_turns
integer
default: 2 >= 1 <= 20
context_edits

Once the request’s tool results add up to trigger_tokens, results from turns at least keep_turns old are replaced with a one-line note before the model sees them. The cleared span grows keep_turns turns at a time, so the start of the conversation stays the same between steps. The reply’s katara.context_edits says what was cleared.

object
keep_turns
integer
default: 3 >= 1 <= 100
trigger_tokens
integer
default: 10000
cache

Keep the start of the request in an explicit cache, for a model that offers one (the Standard and Light models). The tools and the first messages messages are cached; 0, the default, caches the leading system messages. The request that writes a cache pays to keep it for ttl_seconds; later requests with the same start read it at the cached input rate. Ignored on account credits and by models without explicit caching.

object
messages
integer
0
ttl_seconds
integer
default: 300 >= 60 <= 3600
Example
{
"model": "katara/cortex",
"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

katara-cortex on every reply.

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
prompt_tokens_details

Present when the vendor read part of the prompt from its cache.

object
cached_tokens

Prompt tokens billed at the cached input rate.

integer
katara
required
Any of:

What this reply cost.

object
cost_usdc
required

The settled price, in USDC, as a decimal string. For a request paid with x402 it is the charge, the model’s minimum included (0.025 USDC, 0.05 for katara/cortex-genius, 0.01 for katara/cortex-smart).

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
cached_tokens

Prompt tokens the vendor read from its cache, billed at the cached input rate.

integer
cache_saving_usdc

What the cached tokens saved against the input rate, in USDC.

string
cache_saving_usd

The same saving in Credits, on a reply paid with account credits.

string
compaction

When katara.compaction summarised the conversation.

object
message

The system message to send in place of the summarised messages.

object
replaces_from

First index in this request’s messages that the summary replaces.

integer
replaces_to

First index kept after it.

integer
model
string
tokens_before
integer
summary

The summary request’s usage and its cost (cost_usdc or cost_usd).

object
skipped

Why no summary was made; the request went whole.

string
context_edits
object
cleared_tool_results
integer
cleared_tokens
integer
through_turn
integer
cache_written_tokens

Tokens this request wrote to a new explicit cache (katara.cache).

integer
cache_ttl_seconds

How long that cache is kept.

integer
cache_storage_usdc

What keeping it costs, in USDC; included in cost_usdc.

string
simulated

On Test, a reply with fixed text that no model wrote, served when no Test provider was free.

boolean
stop_sequence

The stop sequence at which Katara ended the reply.

string
web_search

The searches this request was charged for.

object
requests

The successful searches; only those are charged, and none when the request ended without an answer.

integer
cost_usdc
string
cost_usd
string
model_calls

On a web search request, how many model calls it made.

integer
web_searches

Every search the model made, in order. Not on stream chunks, which carry each search as it runs.

Array<object>
object
id
required
string
query
required
string
results
required
Array<object>
object
url
string
title
string
page_age
string
content
string
error
string
Allowed values: invalid_input query_too_long too_many_requests unavailable max_uses_exceeded insufficient_quota
edit_id

On an image reply from a model that edits, the id to send as previous_edit_id.

string
Example
{
"id": "chatcmpl-7f3a9c2e1b0d",
"object": "chat.completion",
"model": "katara/cortex",
"system_fingerprint": "katara-cortex",
"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, something no candidate can serve (feature_not_supported, with param naming the field), a request longer than every candidate’s window (context_length_exceeded), a malformed katara_web_search (invalid_web_search) or custom tool (invalid_value), or a model that a key paid with account credits cannot use (model_requires_usdc), or katara/cortex-genius or katara/cortex-smart sent with a key (model_requires_x402). A media part of the wrong shape, an audio format or file type not listed, a PDF over 1,000 pages, or a file_id without a key is invalid_request.

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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

Missing or unknown key (invalid_api_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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
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), or it pays with USDC and its spendable balance cannot (insufficient_quota, with spendable_usdc and max_charge_usdc). Both are sent with x-should-retry: false so SDKs do not retry them. Add credits or USDC, or raise the budget cap, 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. When the quoted model fails before delivering, the request moves to the next model under the same payment. A 402 that answers a paid request with a quote is a new one: no model the signed amount covered answered and a dearer one is left, or the authorization had too little validity left. 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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
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), only Katara Community could serve the request and it is turned off (community_off), 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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

More than 20 MB of media in one request, counted after base64 decoding (media_too_large), or a body over 32 MB (request_too_large). A request without a key is limited to a 4 MB body in all.

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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

Every vendor that could serve the request is rate limiting it (provider_rate_limited). Nothing was charged; Retry-After repeats the vendor’s wait, up to 60 seconds.

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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
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), every provider refused the request body itself (provider_rejected_request, sent with an x-should-retry header of false), or a provider failed before answering a request that could not move to another (provider_failed). A web search request whose model searched and wrote no answer also ends with provider_output_invalid, its katara object listing the searches. Nothing was charged, except a first call that Katara Community served before the search began. Retry after Retry-After. The API never answers 502 or 504.

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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
Retry-After
integer

Every vendor that could serve the request is overloaded (provider_overloaded), no provider can take it right now (no_capacity), no candidate started its reply in time (upstream_timeout), USDC is still being moved into the prepaid balance (funding_pending), or a Test key’s request did not reach the Test network (test_network_unavailable). On Test, a Cortex request with no free Test provider gets a simulated reply instead. 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. Errors says what each code means and what to do; new codes may be added.

string
Allowed values: invalid_api_key model_not_found model_requires_x402 model_requires_usdc invalid_request invalid_value invalid_web_search context_length_exceeded feature_not_supported media_too_large insufficient_quota insufficient_credits funding_pending community_off account_suspended billing_suspended wrong_environment no_capacity upstream_timeout test_network_unavailable payment_invalid permit2_allowance_required quote_rate_limited unsupported_parameter provider_failed provider_output_invalid provider_rejected_request provider_rate_limited provider_overloaded request_too_large not_found method_not_allowed storage_unavailable internal_error
param
string | null
request_id

The response’s x-katara-request-id.

string
Example
{
"error": {
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
Retry-After
integer