Chat Completions

The OpenAI-compatible endpoint. Anything built on the openai packages works against it unchanged.

POST/v1/chat/completions
curl https://api.xkiro.com/v1/chat/completions \
  -H "Authorization: Bearer $XKIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "messages": [
      { "role": "system", "content": "You are a concise assistant." },
      { "role": "user", "content": "Name three uses for a paperclip." }
    ],
    "temperature": 0.7,
    "max_tokens": 500
  }'

Request body#

Core fields
FieldTypeDescription
modelrequiredstringFull model ID including the vendor prefix, e.g. openai/gpt-5.6-sol. See Models.
messagesrequiredarrayThe conversation so far. Each entry has a role (system, user, assistant or tool) and content.
streambooleanStream tokens as server-sent events. Default false. See Streaming.
max_tokensintegerUpper bound on generated tokens. Never raised on your behalf; clamped down if it exceeds what the model allows.
temperaturenumberRandomness, 0–2. Clamped to each model's accepted range. Ignored while reasoning is active, because reasoning models reject it.
top_pnumberNucleus sampling. Use this or temperature, not both.
stopstring | string[]Up to four sequences that end generation.
frequency_penaltynumber−2 to 2. Discourages repeating tokens already used.
presence_penaltynumber−2 to 2. Encourages introducing new topics.
seedintegerBest-effort determinism. Not guaranteed across providers.
response_formatobjectSet { "type": "json_object" } to constrain output to valid JSON. Your prompt must still ask for JSON.
userstringOpaque end-user identifier, echoed into your logs for abuse tracing.
Tools
FieldTypeDescription
toolsarrayFunction definitions the model may call. See Tool calling.
tool_choicestring | objectauto (default), none, required, or { "type": "function", "function": { "name": "..." } } to force one.
Reasoning
FieldTypeDescription
reasoning_effortstringnone, low, medium, high, xhigh or max. Omit to keep the model's own default. See Reasoning.

Message content#

content is either a plain string or an array of parts. Use the array form to mix text and images.

Text and image in one message
{
  "role": "user",
  "content": [
    { "type": "text", "text": "What is unusual about this chart?" },
    {
      "type": "image_url",
      "image_url": { "url": "https://example.com/chart.png" }
    }
  ]
}

Base64 data URLs work too. xKiro detects the real media type from the bytes rather than trusting the label, so a JPEG mislabelled as PNG still reaches the model correctly.

Response#

200 OK
{
  "id": "chatcmpl-9f1c2a4e",
  "object": "chat.completion",
  "created": 1785734400,
  "model": "openai/gpt-5.6-sol",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 88,
    "total_tokens": 112
  }
}

finish_reason

FieldTypeDescription
stopstringThe model finished on its own.
lengthstringHit max_tokens or the context window. The answer is cut off — raise the limit or shorten the input.
tool_callsstringThe model wants to call a tool. Run it and send the result back.
content_filterstringThe provider blocked the content. Retrying the same input will not help.

model always reflects what you requested

The model field always matches the model in your request, and pricing follows that same model.

Behaviour worth knowing#

  • Non-streaming requests time out at 95 seconds. Use stream: true for long generations.
  • Cancelling stops the upstream call. Close the connection and xKiro aborts the provider request. You are billed for what was generated before that point, not for the whole request.
  • Identical blocking requests are de-duplicated. The same body sent twice within about two minutes replays the first result instead of billing twice — see Idempotency & retries.

Was this page helpful?