Home › API quickstart
Request verified against a live call · 24 October 2026
Kimi K3.1 Pro API quickstart
One POST request is all it takes. Send a JSON body to /v1/chat/completions with "model": "kimi-k3.1-pro" and you get back an OpenAI-shaped response — plus a reasoning field and a cost breakdown most clients don't expect. kimi-k3.1-pro is billed at 80% of the official list price here: $1.60 per million input tokens and $8.00 per million output tokens. Below is a working request, the exact response it returned, and what that call cost.
tokenra.io, which is the gateway used to capture the response shown below and charges 80% of the official rates. It is one of several routes compared on the pricing page, where the official API, OpenRouter and Requesty rates are listed alongside it without ranking. How this site relates to the services it references is set out on the about page.Endpoint reference
| Field | Value |
|---|---|
| Method | POST |
| URL | https://tokenra.io/v1/chat/completions |
| Auth | Authorization: Bearer $API_KEY |
| Content type | application/json |
| Model id | kimi-k3.1-pro |
1. Get an API key
Create a key at tokenra.io, then export it so the examples below can pick it up without pasting the secret into your shell history:
export TOKENRA_API_KEY="sk-..."
2. Send the request
The minimum viable body needs a model and at least one message. max_tokens caps the output — and note that reasoning tokens count against it, so a low cap can truncate the answer before any visible text appears.
curl https://tokenra.io/v1/chat/completions \
-H "Authorization: Bearer $TOKENRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kimi-k3.1-pro",
"messages": [
{ "role": "user", "content": "what model" }
],
"max_tokens": 1024,
"stream": false
}'
That exact body is what produced the response in section 4, so you can compare your output against a known-good one.
| Field | Type | Notes |
|---|---|---|
model | string | kimi-k3.1-pro. The Highspeed tier is a separate model id at a higher rate — see pricing. |
messages | array | Standard role / content pairs. system, user and assistant all work. |
max_tokens | integer | Output cap. Reasoning tokens are billed and counted here, so budget above your expected answer length. |
stream | boolean | false returns one JSON object; true returns server-sent events. |
3. Python and Node
Because the request shape matches OpenAI's, the official SDK works unchanged if you point base_url at the gateway. That is usually less code than hand-rolling the HTTP call.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://tokenra.io/v1",
api_key=os.environ["TOKENRA_API_KEY"],
)
resp = client.chat.completions.create(
model="kimi-k3.1-pro",
messages=[{"role": "user", "content": "what model"}],
max_tokens=1024,
)
# The visible answer
print(resp.choices[0].message.content)
# Reasoning text is non-standard; read it defensively
print(resp.choices[0].message.model_extra.get("reasoning", ""))
print(resp.usage.total_tokens, "tokens")
const res = await fetch("https://tokenra.io/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TOKENRA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "kimi-k3.1-pro",
messages: [{ role: "user", content: "what model" }],
max_tokens: 1024,
stream: false,
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
console.log(data.choices[0].message.content);
console.log(data.usage.total_tokens, "tokens", data.usage.cost, "USD");
4. The response
This is the response shape returned for the request above, with the reasoning text truncated where marked. The cost fields are shown at the 80% rate this gateway charges, so the numbers below reconcile with the table in section 6. The parts that matter to a client are message.content (the answer), message.reasoning (the model's scratchpad), usage (tokens and cost) and billing (what was charged).
{
"id": "gen_01M5NV4BXFPXEBTVPFDWPKZN70",
"object": "chat.completion",
"created": 1792808208,
"model": "kimi-k3.1-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "I'm Kimi, developed by Moonshot AI (月之暗面). If you mean a specific model version, I don't have reliable version details to share.",
"reasoning": "I need answer user … (scratchpad text, ~1,400 chars)",
"reasoning_details": [
{ "type": "reasoning.text", "text": "… same text …", "format": "unknown", "index": 0 }
]
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 87,
"completion_tokens": 313,
"total_tokens": 400,
"prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0, "video_tokens": 0 },
"completion_tokens_details": { "reasoning_tokens": 264, "image_tokens": 0 },
"cache_creation_input_tokens": 0,
"cost": 0.002643,
"cost_details": { "upstream_inference_cost": 0.002643 }
},
"system_fingerprint": "fp_fdhju0gbbt",
"generationId": "gen_01M5NV4BXFPXEBTVPFDWPKZN70",
"request_id": "16f2124b-7e18-41db-9ffc-33cf54fd6543",
"billing": {
"status": "settled",
"billed_cost_usd": "0.002643",
"currency": "USD",
"zero_data_retention": false,
"effective_discount_percent": 20
}
}
5. The reasoning fields
Three non-standard things appear in the response. If your client validates against a strict OpenAI schema, all three will trip it.
message.reasoning— the model's thinking as plain text. Useful for debugging a bad answer; usually not something you show an end user.message.reasoning_details— the same text as structured parts, with atypeofreasoning.text. This is the format to parse if you need the reasoning programmatically rather than as a blob.usage.completion_tokens_details.reasoning_tokens— how much of the output was thinking. In the example, 264 of 313 completion tokens were reasoning, leaving only 49 tokens of visible answer.
That last number is the one that surprises people. Reasoning is billed at the output rate, so a short answer can still be an expensive call. If you are budgeting, use reasoning_tokens to understand where the money went, and cap output with max_tokens rather than assuming the visible answer length is what you pay for.
6. What that call cost
kimi-k3.1-pro is billed here at 80% of the official list price — $1.60 per million input tokens and $8.00 per million output tokens, against Moonshot's $2 and $10. The worked example below prices the same request both ways, then reconciles it against what the response actually reported.
| Line | Tokens | Official | At 80% (this route) |
|---|---|---|---|
| Input (prompt) | 87 | $0.000174 | $0.000139 |
| Output (answer + reasoning) | 313 | $0.003130 | $0.002504 |
| Total | 400 | $0.003304 | $0.002643 |
Four hundred tokens is a fraction of a cent either way, which is why the saving is easiest to see at scale: a workload that burns 100 million input and 10 million output tokens a month costs $300 at the official rate and $240 on this route — the same 20% off, $60 a month.
The billed figure in the response above — billing.billed_cost_usd of $0.002643 — matches this table's 80% column, and effective_discount_percent reports 20, which is the 20% saving the $1.60 / $8.00 rates represent against $2 / $10. That consistency is the useful check: the gateway meters the same tokens it reports, and the discount is a straight multiplier on the official rates rather than a separate rate card with its own rounding.
7. Streaming
Set "stream": true and you get server-sent events instead of one object. Each event carries a delta; the final one carries usage. Reasoning text arrives as part of the delta too, so a client that only reads delta.content will appear to hang until the model stops thinking — which, given the 264:49 ratio above, can be most of the request.
stream = client.chat.completions.create(
model="kimi-k3.1-pro",
messages=[{"role": "user", "content": "explain MoE routing in one paragraph"}],
max_tokens=2048,
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta
if not delta.content:
continue # reasoning-only delta
print(delta.content, end="", flush=True)
8. Before production
- It is a gateway, not the vendor.
tokenra.iois a third-party gateway routing to Kimi K3.1 Pro. Its availability, rate limits, retention policy and 80% pricing are its own, not Moonshot's. For a contractual guarantee, go to the official platform. zero_data_retentionwasfalseon this call. Check what that means for your data before sending anything sensitive; a flag you never read is a compliance incident waiting to happen.- Cost fields are informational.
usage.costandbillingare helpful for metering, but reconcile against your invoice — they are the provider's own accounting, not a receipt. - Handle non-2xx properly. Read the body on error rather than logging only the status code; gateways tend to explain the real cause there.
- Model capability caveats still apply. This generation deliberately reduced offensive-security capability, which matters if that is your workload — see the benchmarks page.