Migrating Your Old Kimi K2 or Moonshot V1 Text Script to Kimi K3 (API Only)
You have a working Python script that calls the Kimi/Moonshot text-generation API. It uses an old model name like kimi-k2-0711-preview, moonshot-v1-auto, or even kimi-k2.5. You want to move it forward: pick the right regional endpoint, swap out retired model IDs, and run one clean, bounded text request with Kimi K3.
This tutorial does exactly that. By the end, you will:
- Understand which models are retired and why your old config won’t work.
- Configure your regional API key and base URL correctly.
- Run a complete example that requests a full text answer from Kimi K3.
- Inspect the response to confirm success and avoid common traps.
- Spot the one or two changes you need in your own integration to migrate.
This covers only a single text request (no images, no tools, no self-hosted deployment). Those have their own guides.
1. Background: what’s retired and what’s current
Official documentation lists clear retirement dates:
-
The original K2 family was discontinued on May 25, 2026. This includes:
kimi-k2-0711-previewkimi-k2-0905-previewkimi-k2-turbo-previewkimi-k2-thinkingkimi-k2-thinking-turbo
-
The
moonshot-v1family (including auto and vision-preview variants) andkimi-k2.5were discontinued on August 31, 2026. Replacing a retired V1 with a retired K2 ID will not “restore” the old hosted API; it will simply fail.
Important nuances:
- This lifecycle applies to the official hosted API. Downloadable weights and third-party deployments have their own availability and policies.
- K3’s context window is 1,048,576 tokens, which is larger than K2’s 128K (and K2 Instruct 0905/K2 Thinking at 256K). These are different models. A bigger context is not a promise that you must upload your entire codebase to test it.
- The retirement of the original K2 family does not mean every later
kimi-k2.xmodel is retired. For example, K2.6 and K2.7 Code are separately named current models with their own status.
Migration target: use kimi-k3 for your standard text-generation needs on the official platform.
2. Prerequisites and regional choice
You will run this on macOS, Linux, or WSL (Windows Subsystem for Linux). The shell commands below assume a Unix-like environment; adjust path syntax if necessary.
Python environment
For this tutorial we pin the OpenAI Python SDK to 3.26.0 as a safe, stable baseline; remember that this package itself requires Python 3.10 or newer, so ensure your base environment meets that threshold before proceeding.
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
python -m pip install "openai==3.26.0"
API key and endpoint
You must have an API key on the platform you intend to use, with billing available there. A consumer Kimi membership price does not define the cost of this API call.
-
Global platform
- Console: https://platform.kimi.ai/console/api-keys
- Endpoint:
https://api.moonshot.ai/v1 - Published prices in USD
-
China platform
- Console: https://platform.kimi.com/console/api-keys
- Endpoint:
https://api.moonshot.cn/v1 - Published prices in CNY
Your key and endpoint must belong to the same regional platform. Set MOONSHOT_BASE_URL to one endpoint only, not both.
export MOONSHOT_API_KEY="your-api-key"
# Global platform
export MOONSHOT_BASE_URL="https://api.moonshot.ai/v1"
# China platform: replace the endpoint assignment above with this alternative.
# export MOONSHOT_BASE_URL="https://api.moonshot.cn/v1"
Save this script
kimi_text.py · verify_offline.py
Save the following Python code as kimi_text.py in your working directory.
import os
from openai import OpenAI
with OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url=os.environ["MOONSHOT_BASE_URL"],
) as client:
completion = client.chat.completions.create(
model="kimi-k3",
reasoning_effort="low",
max_completion_tokens=4096,
messages=[
{"role": "user", "content": "Describe a code review in one sentence."}
],
)
choice = completion.choices[0]
if choice.finish_reason != "stop" or not choice.message.content:
raise RuntimeError(f"No complete text answer: finish_reason={choice.finish_reason}")
print(choice.message.content)
Run it with:
python kimi_text.py
3. How to understand and verify the result
When you run this script correctly:
- You will see a single line of text: Kimi K3’s final answer. Wording varies; this is an actual API call and incurs usage charges.
- The script checks two conditions:
finish_reason == "stop": ensures the model chose to end naturally instead of truncation, timeout, or policy cutoff.- Nonempty
choice.message.content: confirms you actually received a response string.
If either check fails, the script raises RuntimeError instead of silently printing a partial result.
Common finish reasons and what they mean
stop: Normal termination by the model. Ideal outcome for a bounded text request.length: The completion hit its token budget (max_completion_tokens). This does not mean “successful” if you expected a full answer. Our script raises to flag this case.content_filteror similar: Indicates policy-level behavior (e.g., safety filters). Check the platform’s error docs for specifics.
Tuning the completion budget
The example uses:
max_completion_tokens=4096
This is a starting allowance, not a guarantee of 4096 visible tokens. K3 always engages reasoning, and that reasoning consumes from the completion allowance as well. If you see truncated or oddly cut-off output:
- Increase
max_completion_tokens. - Simplify the prompt to reduce necessary reasoning steps.
- Inspect whether the response includes long internal monologue you don’t need in your final output.
Reasoning effort parameter
Top-level reasoning_effort accepts:
"low""high""max"(default)
This small example explicitly sets reasoning_effort="low" because we only ask for a single clear sentence. It is not an off switch for reasoning; it adjusts the intensity of internal thought before generating the final text.
For simple queries, low effort can reduce token usage and latency while preserving clarity. For complex tasks (multi-step logic, code generation, research summarization), you may want "high" or "max".
Removing legacy parameters
When moving from older clients or homegrown wrappers, you will likely see:
temperature=0.2or0.3- Custom
top_p,n, presence/frequency penalties
Kimi K3 standardizes its chat behavior around fixed generation parameters rather than letting you freely override them. The official defaults are:
- temperature=1.0
- top_p=0.95, n=1, presence_penalty=0, frequency_penalty=0
Drop these legacy overrides and let the API use the model’s tuned settings instead.
SDK vs old client libraries
This integration uses:
- The official OpenAI Python SDK
- Your chosen
base_urlandapi_keyenvironment variables
Do not use the legacy from moonshot import Moonshot pattern for this configuration; that is an older, separate path. If you see authentication or routing errors:
- Confirm your
MOONSHOT_BASE_URLmatches your selected platform (global or China). - Verify your key was generated on the same platform.
- Check environment variables with
python -c "import os; print(bool(os.environ.get('MOONSHOT_API_KEY')))"andecho "$MOONSHOT_BASE_URL".
4. Billing and token accounting
All prices below are per 1,000,000 tokens. Remember: billing units (tokens) and K3’s context window (1,048,576 tokens) are different numbers.
| K3 API edition | Uncached input | Cached input | Output | Cache write, 5min / 1h |
|---|---|---|---|---|
| Global, USD | $3 | $0.30 | $15 | $3 / $6 |
| China, CNY | ¥20 | ¥2 | ¥100 | ¥20 / ¥40 |
Key points:
- Input, output, and cache writes are billed separately.
- A cache hit renews its TTL without incurring another cache-write charge.
- Global prices exclude applicable taxes; check the official pricing page for your region.
- Old claims like “¥168/month unlimited K2 API” do not describe this metered K3 service. Consumer membership quotas and pricing are separate from the API table.
Link to official pricing:
- Global: https://platform.kimi.ai/docs/pricing/chat
- China: https://platform.kimi.com/docs/pricing/chat
5. Optional support and sensible next steps
Once this single request works with your own prompt, you can extend it safely:
- Replace the example prompt with your real use case text. Keep the same parameters until you understand K3’s behavior under load.
- Audit your existing integration:
- Remove retired model IDs (any
kimi-k2-*ormoonshot-v1unless explicitly current). - Check for unsupported parameter overrides that may conflict with K3’s defaults.
- Remove retired model IDs (any
- For multi-turn conversations or tool loops:
- Use the complete assistant message returned by the API, including reasoning-related fields where applicable.
- Follow the official multi-turn and agent guides instead of reinventing structures.
- If you need image inputs with K3:
- Image input in K3 can be a base64 string or
ms://<file-id>, where the latter refers to a file already uploaded to Kimi's service, not your local filesystem. - Public image URLs are generally unsupported in this context. See the quickstart for image integration details rather than expanding inline.
- Image input in K3 can be a base64 string or
6. Official sources for deeper dives
- Current models and retirement dates:
https://platform.kimi.ai/docs/models
https://platform.kimi.com/docs/models - K3 request/parameter reference:
https://platform.kimi.ai/docs/guide/kimi-k3-quickstart
https://platform.kimi.com/docs/guide/kimi-k3-quickstart - Regional pricing:
https://platform.kimi.ai/docs/pricing/chat
https://platform.kimi.com/docs/pricing/chat - Original model cards (for historical reference):
https://github.com/MoonshotAI/Kimi-K2
https://huggingface.co/moonshotai/Kimi-K2-Instruct-0905
https://huggingface.co/moonshotai/Kimi-K2-Thinking
7. Wrap-up: your migration checklist
Before you integrate this into production, run through this short list:
- Create an API key on the correct regional platform (global or China) with billing enabled.
- Set
MOONSHOT_API_KEYand a singleMOONSHOT_BASE_URLthat matches your chosen platform. - Install the pinned SDK:
"openai==3.26.0"with Python 3.10+. - Save and run the example script; verify it prints a complete answer without raising errors.
- Swap in your real prompt and confirm
finish_reason == "stop"for normal cases. - Audit your codebase for retired model IDs and legacy parameters, then replace them with
kimi-k3and K3-appropriate defaults.
That’s it. You now have a clean, bounded text request running on Kimi K3, and you know exactly what to change in your own integration when retiring old model references.