Skip to main content

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-preview
    • kimi-k2-0905-preview
    • kimi-k2-turbo-preview
    • kimi-k2-thinking
    • kimi-k2-thinking-turbo
  • The moonshot-v1 family (including auto and vision-preview variants) and kimi-k2.5 were 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.x model 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.

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_filter or 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.2 or 0.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_url and api_key environment 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_URL matches 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')))" and echo "$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 editionUncached inputCached inputOutputCache 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:

5. Optional support and sensible next steps​

Once this single request works with your own prompt, you can extend it safely:

  1. Replace the example prompt with your real use case text. Keep the same parameters until you understand K3’s behavior under load.
  2. Audit your existing integration:
    • Remove retired model IDs (any kimi-k2-* or moonshot-v1 unless explicitly current).
    • Check for unsupported parameter overrides that may conflict with K3’s defaults.
  3. 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.
  4. 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.

6. Official sources for deeper dives​

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_KEY and a single MOONSHOT_BASE_URL that 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-k3 and 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.