Skip to content

Chat completions

This page documents POST /v1/chat/completions end to end: every field you should care about as an integrator, how responses and streams are shaped, how usage and prompt caching surface, how rate limits behave, and how overage protection can silently tighten completion budgets on platform-metered traffic.

If you read nothing else: send Authorization: Bearer <api-key>, Content-Type: application/json, and a body with at least messages. Everything else is optional sugar—until it isn’t, which is why the tables below exist.

Endpoint & host

http
POST /v1/chat/completions

Production base URL: https://api.rikaii.com
Full URL: https://api.rikaii.com/v1/chat/completions

Authentication

HeaderRequiredValue
AuthorizationYesBearer <api-key> — opaque key from Dashboard → API keys (format is commonly rk_live_…).
Content-TypeYesapplication/json

See Authentication.

Request model vs. response model

You may send model for OpenAI SDK compatibility. Interpretation depends on BYOK and the Routing engine. The model field in JSON responses and SSE chunks is always the gateway catalog slug (same family as GET /v1/modelsmodelSlug), not necessarily the upstream vendor’s private SKU string.


Request body — parameter reference

Unless noted, omitted fields are left unset or forwarded as-is after sanitization. Unknown JSON keys are generally ignored at ingress where safe.

Core

JSON keyJSON typeRequiredValid range / notes
messagesarray of message objectsYesAt least one element for typical calls; each object follows OpenAI’s chat message shape (see Messages).
modelstringNoNon-empty string when you want to pin or hint a catalog slug; routing may still override unless Tier 1 BYOK routing applies—see Routing.

Sampling & length

JSON keyJSON typeRequiredValid range / notes
temperaturenumberNoTypically 0 ≤ x ≤ 2 on OpenAI-style models; forwarded when the resolved upstream supports it. Unsupported values may be clamped or dropped during sanitization.
top_pnumberNo0 < x ≤ 1 nucleus sampling when supported.
max_tokensinteger | nullNoWhen present as a positive integer, caps generated tokens on providers that use the legacy field. Merged with max_completion_tokens per family rules.
max_completion_tokensinteger | nullNoPreferred on reasoning-first / newer OpenAI families; the gateway may send only max_completion_tokens or only max_tokens upstream depending on the resolved model.
nintegerNoNumber of completion choices; must be positive when set. Values > 1 may be unsupported or downgraded on some routes—prefer 1 unless you have verified behavior for your slug.

Effective completion ceiling: before the upstream call, the gateway may set the outbound completion cap to the minimum of:

  • your requested cap (from max_tokens / max_completion_tokens coalescing),
  • the catalog hard maximum for the resolved upstream model,
  • an optional budget-derived cap from Overage protection on platform-metered traffic.

So your requested 4096 might become a lower integer without error—that is expected when a tighter bound wins.

Penalties & seeds

JSON keyJSON typeRequiredValid range / notes
presence_penaltynumberNoOpenAI-style -2.0 … 2.0 when supported; stripped or clamped on incompatible providers.
frequency_penaltynumberNoOpenAI-style -2.0 … 2.0 when supported; stripped or clamped on incompatible providers.
seedintegerNoDeterministic sampling when supported; may be stripped for some providers.

Stop sequences & logprobs

JSON keyJSON typeRequiredValid range / notes
stopstring | string[] | nullNoUp to provider limits; arrays may be normalized.
logprobsbooleanNoWhen true, requests logprobs where the upstream supports them.
top_logprobsintegerNo0–20 typical on OpenAI when logprobs is enabled.

Tools & structured output

JSON keyJSON typeRequiredValid range / notes
toolsarrayNoTool definitions (OpenAI tool schema).
tool_choicestring | objectNoauto, none, required, or a specific tool {"type":"function","function":{"name":"…"}} object.
parallel_tool_callsbooleanNoWhen true, allows parallel tool calls if the upstream supports it.
response_formatobjectNoStructured output hints (e.g. JSON mode) when supported.

Streaming & misc

JSON keyJSON typeRequiredValid range / notes
streambooleanNotrueSSE stream (text/event-stream). Omit or false for single JSON object.
logit_biasobject | nullNoMap of token id → bias; may be stripped when the resolved provider does not support it.
userstringNoEnd-user id for abuse analytics; opaque string (≤ 64 chars recommended).

Rikaii may apply additional parameter sanitization—see Parameter sanitization.

Messages

Each element of messages is an object:

FieldTypeNotes
rolestringsystem, user, assistant, tool, or provider-specific roles when applicable.
contentstring | arrayPlain text or multimodal parts per OpenAI’s structured content conventions.
namestringOptional short name for the speaker on some providers.
tool_callsarrayOn assistant messages when the model issued tool calls.
tool_call_idstringOn tool messages—links the tool result to the call id.

Keyword routing (Dashboard rules) only inspects the last user message text extracted from messages—see Routing.

Minimal & maximal examples

Minimal valid body:

json
{
  "messages": [{ "role": "user", "content": "Hello" }]
}

Typical production body:

json
{
  "model": "gpt-4o-mini",
  "messages": [
    { "role": "system", "content": "You are a concise assistant." },
    { "role": "user", "content": "Summarize TLS 1.3 in one paragraph." }
  ],
  "temperature": 0.2,
  "max_tokens": 512,
  "stream": false
}

Successful response (non-streaming)

HTTP 200 with Content-Type: application/json.

Top-level fields mirror OpenAI’s chat.completion object. Integrators should treat unknown keys as forward-compatible.

FieldTypeMeaning
idstringCompletion id (gateway-generated or forwarded where applicable).
objectstringTypically chat.completion.
createdintegerUnix timestamp (seconds).
modelstringGateway catalog slug used for billing and logs.
choicesarrayOne entry per n (almost always length 1).
usageobjectToken accounting—see Usage & caching below.

choices[] shape

FieldTypeMeaning
indexintegerZero-based choice index.
messageobject{ "role": "assistant", "content": "…" } plus optional tool_calls, reasoning_content, etc.
finish_reasonstring | nullstop, length, tool_calls, content_filter, etc., per OpenAI semantics.
logprobsobject | nullPresent when requested and supported.

Reasoning & transparency

Some models return chain-of-thought or internal reasoning separately from user-visible content. Rikaii preserves OpenAI-compatible fields such as reasoning_content on assistant messages when the upstream exposes them.

If the model consumes completion tokens but returns no user-visible content or reasoning_content, the gateway may attach a short plain-language note in reasoning_content so non-zero usage.completion_tokens is not mysterious. Treat that as billing transparency, not end-user copy.

X-Rikaii-Fallback

When a fallback hop (configured fallback model on PAYG, or Safety Net retry on eligible BYOK) fulfills a non-streaming request, the gateway may add:

http
X-Rikaii-Fallback: true

Omitted when the primary path succeeded on the first try. Streaming completions do not attach this header today even if a fallback ran internally—see Fallback routing.


Usage & caching

How usage is produced

  1. The upstream LLM returns a JSON completion (or final stream chunk) that includes a usage object when the provider supports it.
  2. The gateway parses that object into its internal OpenAI-shaped record. prompt_tokens, completion_tokens, total_tokens, and nested prompt_tokens_details / completion_tokens_details are not recomputed by Rikaii for billing display in the wire response—they are whatever the provider supplied (after JSON deserialization).
  3. The gateway does rewrite other parts of the payload for consistency—most notably the top-level model string to the gateway catalog slug, plus optional assistant message normalization (for example splitting or annotating reasoning-related text for SDK compatibility). Those edits do not replace the numeric usage block.

So usage.prompt_tokens_details.cached_tokens appears only when the upstream included it (or compatible fields that deserialize into that shape). Rikaii does not invent cache hit counts.

JSON keyTypeMeaning
prompt_tokensintegerInput tokens as reported by the provider.
completion_tokensintegerOutput tokens as reported (may include reasoning on some SKUs).
total_tokensintegerSum when the provider sets it.
prompt_tokens_detailsobject | omittedWhen present, may include cached_tokens for providers that expose prompt-cache accounting (for example OpenAI-style APIs). Semantics are defined by that vendor.
completion_tokens_detailsobject | omittedWhen present, may include reasoning_tokens and other vendor counters.

Prompt caching takeaway: treat cached_tokens as an upstream telemetry field. If it is missing, the provider may not expose cache splits for that model, or the response path omitted them. If it is non-zero, your prompt likely hit that provider’s prompt cache for part of the input—compare billing and latency across cold vs warm repeats in your integration tests.


Streaming (stream: true)

Set "stream": true. The gateway returns HTTP 200 with Content-Type: text/event-stream and a body encoded as Server-Sent Events (SSE).

Event framing

  • Each logical chunk is delivered as an SSE data: line containing a JSON object (OpenAI chat.completion.chunk shape).
  • The stream ends with a data: [DONE] sentinel (OpenAI convention).

Chunk object shape

Streaming objects reuse OpenAI’s chunk schema:

FieldNotes
id, object, created, modelMetadata repeated on early chunks; model remains the gateway catalog slug.
choicesArray with delta objects instead of full message objects mid-stream.
choices[].deltaPartial content, optional role, tool_calls fragments, etc.
choices[].finish_reasonUsually null until the final chunk for that choice, then stop, length, tool_calls, …
usageOften omitted on intermediate chunks. For Rikaii-built outbound streams, stream_options.include_usage is enabled toward the upstream so a final chunk may include usage when the provider supports it—still, do not depend on usage unless you observed it for your model.

Client implementation notes

  • Use a line-oriented reader; do not buffer the entire response.
  • Official OpenAI SDKs handle streaming when stream: true is set; point the base URL at https://api.rikaii.com and keep the same path.
  • Always handle [DONE] and abrupt disconnects (TCP close) as terminal states.

Rate limiting (HTTP 429)

Chat completions enforce a workspace-level requests-per-minute bucket keyed off your API key’s owner. Defaults:

Workspace tierRPM
Standard (non‑Pro PAYG)60
Pro120

A custom RPM stored on the workspace (support/operations only—not editable in the Dashboard) replaces those defaults for all keys; see Rate limits.

When exceeded:

  • HTTP status: 429 Too Many Requests
  • Body: OpenAI-compatible JSON error, typically error.code = "rate_limit_exceeded"
  • Headers: Do not rely on Retry-After or X-RateLimit-* for programmatic backoff—the gateway does not document stable quota headers for chat. Use exponential backoff with jitter.

If the limiter backend is unhealthy, you may receive 503 instead (fail-closed). See Rate limits.


Billing guards (HTTP 402)

402 Payment Required indicates a billing prerequisite or no affordable headroom for a metered call. Common cases:

  • Monthly spend cap reached.
  • Prepaid / credit exhausted for the key or workspace.
  • Overage protection math leaves zero affordable completion tokens after estimated prompt retail—see Overage protection.

Always parse the JSON error.message for operator-facing detail.


Errors & validation

All non-2xx responses with JSON bodies use the nested error object described in Errors. Branch on error.code first.


OpenAI SDK compatibility

Pattern (pseudo-code):

text
base_url = "https://api.rikaii.com"
default_headers["Authorization"] = "Bearer " + RIKAII_API_KEY

Then call POST /v1/chat/completions exactly like OpenAI’s Chat Completions API. Tool calls, multimodal arrays, and streaming should work where the resolved upstream supports them.


Rikaii API documentation