kimik3.io/API guide

Kimi K3 API

Model ID, auth, a request that works, and how to tell a real success from a silent failure. Every response body on this page came off the wire on 2026-07-16.

K3 is OpenAI-format compatible. Any OpenAI SDK works — you point base_url at an endpoint that carries kimi-k3 and set the model string. That is the whole integration.

Quickstart

This calls K3 through EvoLink, which carries kimi-k3 on an OpenAI-compatible endpoint. Swap the base_url for any other gateway and the rest is unchanged.

python · openai sdk
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_EVOLINK_API_KEY",
    base_url="https://direct.evolink.ai/v1",   # <-- the one line you change
)

response = client.chat.completions.create(
    model="kimi-k3",
    messages=[
        {"role": "user", "content": "Explain prompt caching in two sentences."},
    ],
)

print(response.choices[0].message.content)
print(response.usage)
curl
curl https://direct.evolink.ai/v1/chat/completions \
  -H "Authorization: Bearer $EVOLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "messages": [
      {"role": "user", "content": "Explain prompt caching in two sentences."}
    ]
  }'

Auth is a bearer token: Authorization: Bearer <key>. Keep it in an environment variable, never in source. The endpoint path is /v1/chat/completions — if you are using an OpenAI SDK, give it the /v1 root and let the SDK append the rest.

The key: two honest ways to get one

The code above needs an API key, and you have two legitimate options. Three things are identical either way — the rates ($3.00 / $0.30 / $15.00 per 1M, date-stamped), the model's behaviour (cache blocks, reasoning billing — it's the same model), and your code (OpenAI format both ways; switching later is one base_url). What differs is everything around the call:

Moonshot directVia EvoLink
Getting started A separate Moonshot platform account One account, 10 free credits, sign up from anywhere in minutes
Models on the key The Kimi family GPT, Claude, Gemini, K3, and dozens of the world's mainstream models — one key, one endpoint
Billing operations Another balance to fund, watch, and reconcile — per provider you add One balance and one statement across every model you call
Multi-model & agent work Model routing, fallbacks, and A/B evals mean juggling one account per provider Routing, fallback, and model comparison are a string change on the same key

When is direct the right call? If you will only ever use Kimi models and want no intermediary in the path, go direct — the code on this page works there too, with Moonshot's base_url. For everyone else, the gateway column is why this site's examples default to it.

Get an EvoLink API key — 10 free credits

Sign-up drops you into the dashboard with onboarding. Already have an account? Grab a key from your dashboard →

What a real response looks like

Trimmed, but otherwise exactly what came back:

{
  "id": "chatcmpl-6a593017ec44f116fb614895",
  "object": "chat.completion",
  "created": 1784229923,
  "model": "kimi-k3",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "OK",
      "reasoning_content": "The user is asking me to reply with exactly \"OK\". This is a simple request with no complications..."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 90,
    "completion_tokens": 47,
    "total_tokens": 137,
    "completion_tokens_details": {"reasoning_tokens": 31},
    "prompt_tokens_details": {"cached_tokens": 90}
  }
}

Two fields deserve attention because they have no OpenAI equivalent:

  • message.reasoning_content — K3's thinking, returned alongside the answer. Read content for the answer. Reasoning is not a mode you enable on K3; it is always on.
  • usage.completion_tokens_details.reasoning_tokens — how many output tokens went to thinking. Above, 31 of 47 tokens for a two-letter reply. That is billed at the output rate.

Confirm the call actually worked

An HTTP 200 is not proof of success on K3. Check four things:

  1. model echoes back kimi-k3 — not a fallback the gateway silently substituted.
  2. finish_reason is stop, not lengthlength with empty content is the signature of the reasoning-budget trap.
  3. content is a real string, not "".
  4. usage.total_tokens is non-zero — and tells you what you spent.

In code, the one assertion worth writing:

choice = response.choices[0]
if choice.finish_reason == "length" and not choice.message.content:
    raise RuntimeError(
        f"Reasoning consumed the whole budget "
        f"({response.usage.completion_tokens_details.reasoning_tokens} reasoning tokens). "
        f"Raise max_completion_tokens."
    )

Parameters that matter

K3-relevant parameters. Defaults per Moonshot's API docs, read 2026-07-16; behaviour notes are ours, measured.
ParameterDefaultWhat you need to know
model Exactly kimi-k3. Not kimi-k3-chat, not moonshot-k3.
max_completion_tokens131,072 Leave it alone unless you know what you're doing. Reasoning draws from this budget; cap it low and you get billed for an empty string. The full story.
streamfalse Strongly recommended at long context — we measured 52s on a 498k-token prompt.
stream_options Set {"include_usage": true} or you get no usage block while streaming, and you are blind to spend.
tools Function calling, max 128 tools, JSON Schema format.
tool_choiceauto auto · none · required · or a named function.
response_format{"type":"text"} Supports json_object and json_schema for structured output.
prompt_cache_keynull We could not measure any effect for prefix reuse — caching already happens automatically. What we tested.
reasoning_effort Only max is supported — but passing an unsupported value returns HTTP 200, not an error. Do not trust it to validate.

Full parameter and response-schema reference: EvoLink's kimi-k3 API docs.

Streaming

Server-sent events, terminated by data: [DONE]. The wrinkle specific to K3: the first tokens you receive are reasoning, not your answer. We measured a 2.8s median to first token — and in three of five runs, no content token ever arrived because a 128-token ceiling was consumed by thinking.

stream = client.chat.completions.create(
    model="kimi-k3",
    messages=[{"role": "user", "content": "Count to three."}],
    stream=True,
    stream_options={"include_usage": True},   # or you get no usage at all
)

for chunk in stream:
    if not chunk.choices:
        continue
    delta = chunk.choices[0].delta
    if getattr(delta, "reasoning_content", None):
        pass                      # thinking — usually not what you render
    if delta.content:
        print(delta.content, end="", flush=True)

If you render reasoning_content to users, know that you are showing them the model's scratchpad. Most products want to show a spinner during reasoning and stream only content.

API FAQ

What is the Kimi K3 model ID?

Exactly kimi-k3 — not kimi-k3-chat, not moonshot-k3. The response echoes it back in the model field, which is worth asserting on.

Is Kimi K3 OpenAI-compatible?

Yes. K3 is served over the standard /v1/chat/completions shape, so any OpenAI SDK works unchanged — you set base_url and the model string. The two K3-specific additions are reasoning_content in the message and reasoning_tokens in usage.

Do I need a Moonshot account to use the Kimi K3 API?

No. Any endpoint that carries kimi-k3 works — through EvoLink, one account with 10 free credits reaches K3 alongside GPT, Claude, Gemini, and dozens of the world's mainstream models, at the same rates as Moonshot direct.

What base_url do I use for Kimi K3?

Through EvoLink: https://direct.evolink.ai/v1. Direct to Moonshot: https://api.moonshot.ai/v1. The rest of your code is identical either way.

Get a key and run the code above

EvoLink carries kimi-k3 on an OpenAI-compatible endpoint — one key reaches GPT, Claude, Gemini, and dozens of the world's mainstream models. 10 free credits, sign up from anywhere — no Chinese phone number.

Get an EvoLink API key