The Kimi API is compatible with the OpenAI interface, so migration usually means changing only three things: the base URL, the API key, and the model name. In 2026, however, several interface details are easy to trip over: older models have been retired, max_tokens is deprecated, K3 defaults to the highest reasoning effort, and streaming usage is returned only in the final chunk.
This article walks through integration from zero: confirm the site and protocol, choose a model, complete the first curl and Python calls, then work through the migration checklist and error reference. Models and prices follow the in-site model pricing page.
Note: Moonshot and Kimi are trademarks of their respective owners. This article is for technical integration discussion only. Model lists, context lengths, and parameter rules may change; defer to the current official documentation.
1. Confirm Three Things Before You Start
- Site: the China site is
platform.kimi.com; the international site isplatform.kimi.ai. Accounts, balances, and keys are completely independent between the two. - Protocol: most projects use the OpenAI-compatible Chat Completions interface; projects already built on the Anthropic SDK can use the Messages-compatible entry point.
- Model: check which models your account can see before writing names into code. Do not copy a tutorial from several months ago.
The China-site request domain is https://api.moonshot.cn; the international site uses https://api.moonshot.ai. Domain and key must match, and this is one of the most common causes of a 401.
2. Base URLs and Endpoint Paths
| Protocol | Base URL | Endpoint path |
|---|---|---|
| OpenAI Chat Completions | https://api.moonshot.cn/v1 |
/chat/completions |
| OpenAI Responses | https://api.moonshot.cn/v1 |
/responses |
| Anthropic Messages | https://api.moonshot.cn/anthropic |
/v1/messages |
| Model list | https://api.moonshot.cn/v1 |
/models |
| Balance query | https://api.moonshot.cn/v1 |
/users/me/balance |
For the international site, replace the domain with api.moonshot.ai; the paths stay the same. The OpenAI SDK's base_url should stop at /v1, because the SDK appends /chat/completions itself; curl requires the full path. Mixing the two conventions produces an extra or missing /v1, which shows up as a 404.
The Anthropic-compatible base URL does not include /v1, unlike the OpenAI entry point. When integrating through Claude Code or another Anthropic SDK, use https://api.moonshot.cn/anthropic as shown in the official examples.
3. How to Choose a Model Name
| Model name | Context | Suitable tasks | Notes |
|---|---|---|---|
kimi-k3 |
1M | Complex reasoning, software engineering, knowledge work, very long documents | Default reasoning_effort is max |
kimi-k2.7-code |
256K | Code generation, repository Q&A, agents | Better instruction following over long context |
kimi-k2.7-code-highspeed |
256K | Low-latency completion, interactive coding | Same model as the standard version, faster |
kimi-k2.6 |
256K | General chat, extraction, vision and text input | Supports both thinking and non-thinking modes |
Older models have been retired: the entire moonshot-v1 series and kimi-k2.5 stopped being supported on August 31, 2026; the kimi-k2 series stopped on May 25, 2026; and kimi-latest stopped earlier. Projects still using these names should migrate directly to kimi-k3 or the current K2 series rather than searching for old documentation.
Do not default to K3 for every general task. K3 is capable, but its default reasoning effort is high, which increases both latency and output tokens; kimi-k2.6 is often a better fit for simple classification and fixed-format extraction. Consider the K2.7 Code series for coding tasks.
4. First Call: curl
export MOONSHOT_API_KEY="your-key-here"
curl "https://api.moonshot.cn/v1/chat/completions" \
-H "Authorization: Bearer $MOONSHOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kimi-k3",
"messages": [
{"role": "user", "content": "Reply only: setup successful"}
],
"max_completion_tokens": 64
}'
A 200 response with the expected content confirms that the key, site, model name, and path are all correct. A 401 points first to a site and key mismatch; a 404 points first to the model name and /v1; a 400 points first to whether the error message mentions the context or output limit.
5. Python SDK and Streaming
Install OpenAI SDK 1.0 or later and change only base_url and the key:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url="https://api.moonshot.cn/v1",
)
stream = client.chat.completions.create(
model="kimi-k3",
messages=[{"role": "user", "content": "In three points, explain what kinds of teams an API gateway suits"}],
max_completion_tokens=512,
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
if chunk.usage:
print("\nUsage:", chunk.usage)
A streaming response is SSE, with each line beginning with data: and the stream ending with data: [DONE]. With include_usage enabled, one extra chunk with an empty choices array and only usage is returned before the end. If the connection drops mid-stream, that chunk may never arrive, so do not rely entirely on the client for usage accounting.
6. max_completion_tokens and Reasoning Effort
max_tokens is deprecated; new code should use max_completion_tokens consistently. It represents the expected output length, not input plus output. The K3 default is 131072 and the maximum is 1048576; if the input plus this value exceeds the context window, the request returns invalid_request_error.
Two practical rules:
- Keep the value small for tests and fixed-format tasks, for example 256 to 1024, to avoid long output.
- When the limit is reached,
finish_reasonislength; a normal finish isstop. Do not retry immediately onlength; first judge whether the output genuinely needs to be longer or the prompt is too open-ended.
K3 also has a top-level reasoning_effort parameter with low, high, and max options; the default is max. Lowering it to low for simple tasks reduces latency and token consumption; raise it for complex reasoning. With the OpenAI SDK, if your version does not include the parameter, pass it through extra_body. K3's thinking content is returned in reasoning_content and must be passed back unchanged in multi-turn conversations and tool calls.
7. Migrating from OpenAI or Older Moonshot Versions
- Inventory every old model name in code and configuration, and build a replacement table.
- Change
base_url: China sitehttps://api.moonshot.cn/v1, international sitehttps://api.moonshot.ai/v1. - Switch to a key for the matching site; never reuse a key across sites.
- Replace model names, preferring
kimi-k3or current models in the K2 series. - Change
max_tokenstomax_completion_tokens. - Replace the K2.x
thinkingsetting with K3'sreasoning_effort; do not send both. - Add
stream_options={"include_usage": True}to streaming requests. - Run a regression with the same set of real tasks, recording quality, latency,
finish_reason, and usage. - Keep the old configuration for one release cycle, then remove it after confirming everything works.
Do not switch everything at once. Move the test environment first, then low-risk workloads, and finally core paths, keeping a rollback switch at every step.
8. Common Error Reference
| Status code | Error type | Common cause | Action |
|---|---|---|---|
| 400 | invalid_request_error |
Bad parameter, context too long, output limit exceeded | Adjust the request |
| 400 | content_filter |
Input or output triggered content safety | Adjust the prompt |
| 401 | invalid_authentication_error |
Invalid key, site mismatch | Change the key or domain |
| 404 | resource_not_found_error |
Wrong model name or path | Check the model list |
| 429 | rate_limit_reached_error |
Concurrency, RPM, TPM, or TPD exceeded | Slow down or upgrade the tier |
| 429 | exceeded_current_quota_error |
Unpaid balance or insufficient quota | Top up |
| 504 | Gateway Time-out |
Non-streaming long request waited too long | Switch to streaming |
A non-streaming request that waits more than 900 seconds on the server may return a 504. For long-form generation, long-document analysis, and coding agents, prefer streaming: it keeps data flowing to the client and avoids the waste of waiting for a timeout and then retrying.
FAQ
How far should the base URL go?
For the OpenAI SDK, use https://api.moonshot.cn/v1 and do not include /chat/completions. For curl, use the full https://api.moonshot.cn/v1/chat/completions. For the Anthropic SDK, use https://api.moonshot.cn/anthropic.
Why is max_tokens not taking effect?
The parameter is deprecated, and some models ignore it or return an error. Use max_completion_tokens instead, and note that it is an output limit, not an input-plus-output limit.
Why is the K3 response slower than expected?
K3 defaults to reasoning_effort of max, which performs deeper reasoning. For simple tasks, set it to low or high and limit output length; latency usually improves noticeably.
Why is there no usage after the stream ends?
You need to set stream_options={"include_usage": True} explicitly. Even then, the final chunk may be lost if the connection drops, so production systems should keep their own server-side accounting.
What else must change when migrating from OpenAI?
Most code needs only the base URL, key, and model name changed. Also check max_tokens, streaming usage, error-type mapping, and retry policy, especially how 429 responses are classified.
Next Steps
Create a test key on the ZSQH AI Gateway, run one real task each with kimi-k3 and kimi-k2.6, confirm the path, and then connect production. Available models and billing follow the model pricing page.
Related reading:
