Skip to main content
Third-party model integration tutorial

Kimi

This document describes how to call the Kimi model inference service deployed on Alibaba Cloud Model Studio.

Moonshot-Kimi-K2-Instruct and kimi-k2-thinking were retired on July 9, 2026. We recommend migrating to qwen3.7-plus, qwen3.8-max, or qwen3.8-flash.
Supported regions: China (Beijing), Singapore, Japan (Tokyo), China (Hong Kong), Germany (Frankfurt), and US (Virginia). Model experience: You can try the Kimi model in the model trial center. Service endpoints are region-specific. Configure the correct base URL for your region.
  • OpenAI compatible
  • DashScope
  • US (Virginia)
  • Germany (Frankfurt)
  • Singapore
  • Japan (Tokyo)
  • China (Beijing)
  • China (Hong Kong)
The base_url for SDK calls is: https://{WorkspaceId}.us-east-1.maas.aliyuncs.com/compatible-mode/v1HTTP request URL: POST https://{WorkspaceId}.us-east-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions
Replace {WorkspaceId} with your actual workspace ID. Prerequisites: You must get an API key and set it as an environment variable. If you use the SDK, you must install the SDK.

Get started

The following examples use text-only input. For multimodal examples, see multimodal call.
  • OpenAI compatible
  • DashScope
  • Anthropic compatible
  • Python
  • Node.js
  • HTTP
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[{"role": "user", "content": "Who are you?"}],
    stream=True,
    extra_body={"enable_thinking": True},  # Enable thinking mode to get reasoning_content
)

reasoning_content = ""  # Complete thinking process
answer_content = ""     # Complete response
is_answering = False    # Tracks if the main response has started.

print("\n" + "=" * 20 + "Thinking Process" + "=" * 20 + "\n")

for chunk in completion:
    if chunk.choices:
        delta = chunk.choices[0].delta
        # Store content from the thinking process.
        if hasattr(delta, "reasoning_content") and delta.reasoning_content is not None:
            if not is_answering:
                print(delta.reasoning_content, end="", flush=True)
            reasoning_content += delta.reasoning_content
        # Start printing the main response once its content arrives.
        if hasattr(delta, "content") and delta.content:
            if not is_answering:
                print("\n" + "=" * 20 + "Complete Response" + "=" * 20 + "\n")
                is_answering = True
            print(delta.content, end="", flush=True)
            answer_content += delta.content

Response

====================Thinking Process====================

The user asks "Who are you?", which is a direct question about my identity. I need to answer truthfully based on my actual identity.

I am Kimi, an AI assistant developed by Moonshot AI. I should introduce myself clearly and concisely, including:
1. My identity: AI assistant
2. My developer: Moonshot AI
3. My name: Kimi
4. My core capabilities: long-text processing, intelligent conversation, file processing, search, etc.

I should maintain a friendly and professional tone, avoiding overly technical terms for clarity. I should also emphasize that I am an AI without personal consciousness, emotions, or experiences to prevent misunderstandings.

Response structure:
- Directly state my identity
- Mention my developer
- Briefly introduce core capabilities
- Keep it clear and concise
====================Complete Response====================

I am Kimi, an AI assistant developed by Moonshot AI. I am based on a Mixture-of-Experts (MoE) architecture and have capabilities such as ultra-long context understanding, intelligent conversation, file processing, code generation, and complex task reasoning. How can I help you?

Multimodal calls

The kimi-k2.7-code, kimi-k2.6, and kimi-k2.5 models can simultaneously process text, images, or video. Use the enable_thinking parameter to enable thinking mode. The following examples show how to use this capability.

Enable or disable thinking mode

kimi-k2.6 and kimi-k2.5 are hybrid thinking models. These models can reply after thinking or reply directly. You can use the enable_thinking parameter to control whether to enable the thinking mode:
  • true: Enable thinking mode
  • false (default): Disables the thinking mode
kimi-k2.7-code is a thinking-only model: thinking mode is always enabled (enable_thinking defaults to true and cannot be disabled), and preserve_thinking defaults to true. kimi-k2.6 supports passing the thinking process in multi-turn conversations by using the preserve_thinking parameter. For more information, see Pass the thinking process. The following examples show how to use an image URL and enable thinking mode. The main example demonstrates single-image input, while the commented-out code is an example of multi-image input.
  • OpenAI compatible
  • DashScope
Python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)

# Single-image input example (thinking mode enabled)
completion = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What scene is depicted in the image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"
                    }
                }
            ]
        }
    ],
    extra_body={"enable_thinking":True}  # Enable thinking mode
)

# Print the thinking process
if hasattr(completion.choices[0].message, 'reasoning_content') and completion.choices[0].message.reasoning_content:
    print("\n" + "=" * 20 + "Thinking Process" + "=" * 20 + "\n")
    print(completion.choices[0].message.reasoning_content)

# Print the complete response
print("\n" + "=" * 20 + "Complete Response" + "=" * 20 + "\n")
print(completion.choices[0].message.content)

# Multi-image input example (thinking mode enabled, uncomment to use)
# completion = client.chat.completions.create(
#     model="kimi-k2.6",
#     messages=[
#         {
#             "role": "user",
#             "content": [
#                 {"type": "text", "text": "What do these images depict?"},
#                 {
#                     "type": "image_url",
#                     "image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"}
#                 },
#                 {
#                     "type": "image_url",
#                     "image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/tiger.png"}
#                 }
#             ]
#         }
#     ],
#     extra_body={"enable_thinking":True}
# )
#
# # Print the thinking process and complete response
# if hasattr(completion.choices[0].message, 'reasoning_content') and completion.choices[0].message.reasoning_content:
#     print("\nThinking Process:\n" + completion.choices[0].message.reasoning_content)
# print("\nComplete Response:\n" + completion.choices[0].message.content)

Video understanding

kimi-k3 does not currently support video input (it supports text and image input only), so the video understanding examples in this section do not apply to kimi-k3.
  • Video file
  • Image list
The kimi-k2.7-code, kimi-k2.6, and kimi-k2.5 models analyze videos by extracting a sequence of frames. You can control the frame extraction strategy with the following parameters:
  • fps: Controls the frame extraction frequency. The interval between extracted frames is f p s 1 ​ seconds. The value must be in the range of [0.1, 10]. The default value is 2.0.
    • For high-motion scenes: Set a higher fps value to capture more detail.
    • For static or long videos: Set a lower fps value to improve processing efficiency.
  • max_frames: Specifies the maximum number of frames to extract from a video. The default and maximum value is 2000. If the number of frames calculated from the fps value exceeds this limit, the system automatically extracts frames uniformly to stay within the max_frames limit. This parameter is available only when you use the DashScope SDK.
  • OpenAI compatible
  • DashScope
When passing a video file to the model using the OpenAI SDK or an HTTP request, set the "type" parameter in the user message to "video_url".
Python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {
            "role": "user",
            "content": [
                # When passing a video file directly, set the "type" parameter to "video_url".
                {
                    "type": "video_url",
                    "video_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4"
                    },
                    "fps": 2
                },
                {
                    "type": "text",
                    "text": "What is the content of this video?"
                }
            ]
        }
    ]
)

print(completion.choices[0].message.content)

Pass a local file

The following examples show how to pass a local file. The OpenAI-compatible API supports only Base64 encoding, while DashScope supports both Base64 encoding and file paths.
  • OpenAI compatible
  • DashScope
To pass a local file using Base64 encoding, construct a Data URL. For instructions, see Construct a Data URL.
Python
from openai import OpenAI
import os
import base64

# Encoding function: Converts a local file to a Base64-encoded string.
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")

# Replace "xxx/eagle.png" with the absolute path to your local image.
base64_image = encode_image("xxx/eagle.png")

client = OpenAI(
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    # China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/png;base64,{base64_image}"},
                },
                {"type": "text", "text": "What scene is depicted in the image?"},
            ],
        }
    ],
)
print(completion.choices[0].message.content)

# The following examples show how to pass a local video file and a local image list.

# [Local video file] Encode the local video as a Data URL and pass it to the video_url parameter:
#   def encode_video_to_data_url(video_path):
#       with open(video_path, "rb") as f:
#           return "data:video/mp4;base64," + base64.b64encode(f.read()).decode("utf-8")

#   video_data_url = encode_video_to_data_url("xxx/local.mp4")
#   content = [{"type": "video_url", "video_url": {"url": video_data_url}, "fps": 2}, {"type": "text", "text": "What is the content of this video?"}]

# [Local image list] Encode multiple local images with Base64 and pass them as a list to the video parameter:
#   image_data_urls = [f"data:image/jpeg;base64,{encode_image(p)}" for p in ["xxx/f1.jpg", "xxx/f2.jpg", "xxx/f3.jpg", "xxx/f4.jpg"]]
#   content = [{"type": "video", "video": image_data_urls, "fps": 2}, {"type": "text", "text": "Describe the sequence of events in this video."}]

File limitations

  • Image limitations
  • Video limitations
  • Image resolution:
    • Minimum size: Width and height must each exceed 10 pixels.
    • Aspect ratio: The ratio of the longest side to the shortest side must not exceed 200:1.
    • Maximum resolution: The recommended maximum is 8K(7680x4320). Higher resolutions may cause API call timeouts due to large file sizes or slow network transfers.
  • Supported image formats
    • The following formats are supported for resolutions below 4K(3840x2160):

      Image format

      File extension

      MIME type

      BMP

      .bmp

      image/bmp

      JPEG

      .jpe, .jpeg, .jpg

      image/jpeg

      PNG

      .png

      image/png

      TIFF

      .tif, .tiff

      image/tiff

      WEBP

      .webp

      image/webp

      HEIC

      .heic

      image/heic

    • For resolutions between 4K(3840x2160) and 8K(7680x4320), only JPEG, JPG, and PNG are supported.
  • Image size:
    • When providing an image via a public URL or local path, its size must not exceed 10 MB.
    • When using Base64 encoding, the encoded string must not exceed 10 MB.
    To compress a file, see How to compress an image or video to meet the size limit.
  • Number of supported images: When providing multiple images, the total number of tokens for all images and text must not exceed the model's maximum input limit.

Other features

Model

Multi-turn conversation

Deep thinking

Function calling

Structured output

Web search

Prefix completion

Context cache

kimi-k3

Supported

Supported

Supported

Supported

Supported

Supported

Supported

kimi-k2.7-code

Supported

Supported

Supported

Not supported

Not supported

Not supported

Supported

kimi-k2.6

Supported

Supported

Supported

Not supported

Not supported

Not supported

Supported

kimi-k2.5

Supported

Supported

Supported

Not supported

Not supported

Not supported

Supported

kimi-k2-thinking

Supported

Supported

Supported

Supported

Not supported

Not supported

Supported

Moonshot-Kimi-K2-Instruct

Supported

Not supported

Supported

Not supported

Supported

Not supported

Supported

Dynamically Loaded Tools (Kimi K3)

When an application needs to mount a large number of tools, putting every tool declaration into the request's top-level tools field at once leads to Tool Definition Bloat: every request must carry the description and parameter schema of all tools, driving up token consumption; and the more candidate tools there are, the more likely the model is to pick the wrong tool and construct incorrect call arguments. Dynamically Loaded Tools let you inject tools on demand during a conversation: mount only a few core tools first, and when the conversation reaches a point where a specific tool is needed, dynamically insert it into messages, thereby reducing token consumption and improving tool-selection accuracy.
Dynamically loaded tools are currently supported only by kimi-k3; requesting them on other models (such as kimi-k2.6) returns a tokenization failed error.

Inject tool declarations in messages

Insert a message with role set to system into messages, and declare the tools to load via that message's tools field. The format is identical to that of the request's top-level tools field, and you must provide the complete tool information (name, description, parameters).
  • A system message carrying tools has the same status as an ordinary message: the tools become visible to the model starting from the position where that message appears in the messages list.
  • Dynamically loaded tools coexist with the global tools declared in the request's top-level tools field; the model can see both kinds of tools at the same time.
  • A dynamically injected tool declaration must be a complete tool definition; you cannot pass only a tool name or reference a globally declared tool.
  • A system message carrying tools must not also carry a content field, otherwise the request fails with a 400 error. When using the OpenAI SDK, you can pass the tools field through directly in messages.
Python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following is the URL for the China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID; URLs vary by region.
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Please calculate 23 * 47 for me."},
        # Dynamically load a tool: insert a system message carrying a tools field into the conversation
        {
            "role": "system",
            "tools": [
                {
                    "type": "function",
                    "function": {
                        "name": "Calculator",
                        "description": "Calculator; evaluates a single arithmetic expression only",
                        "parameters": {
                            "type": "object",
                            "properties": {
                                "expr": {
                                    "type": "string",
                                    "description": "Arithmetic expression supporting basic operations, exponentiation, logarithms, and trigonometric functions, in JavaScript syntax",
                                }
                            },
                            "required": ["expr"],
                        },
                    },
                }
            ],
        },
    ],
)

print(completion.choices[0].message.tool_calls)

On-demand loading combined with a search tool

There is no dedicated tool-search API. When there are many tools, you can combine a custom search tool with dynamically loaded tools to load tools on demand:
  1. At the start of the session, declare in the top-level tools only a search_tools tool implemented by your application backend (it returns matching tool names and summaries by keyword), plus a few core tools that may be used every turn.
  2. Declare the searchable keywords (such as a tool catalog or domain tags) in the system prompt to guide the model to call search_tools first when it needs a tool. You can set tool_choice: "required" on the first request to force the model to search before answering, then restore tool_choice to "auto" after the search. Changing tool_choice does not break the prefix cache.
  3. Based on the results returned by search_tools, the application dynamically inserts the complete declarations of the corresponding tools into messages via a system message carrying tools.
  4. The model can then call these newly loaded tools directly in subsequent generation.
This way, no matter how large the total number of tools is, only a few tool declarations are actually present in each request, keeping the context window and the model's selection pressure under control.

Notes

  • Dynamic tool declarations take effect per request and are not remembered by the server. Whether to keep carrying them in the next request is up to the integrator: keep carrying them and the tools remain available (which also helps hit the prefix cache); stop carrying them and the declaration expires — if the tool is not declared elsewhere, the model cannot call it, and the prefix cache after the change point may miss.
  • Appending a dynamic tool declaration at the end of messages does not affect the cache of the existing prefix; deleting or modifying earlier tool declarations may affect cache hits after the change point. Declaring global tools in the request's top-level tools field also does not affect cache hits.
  • A system message carrying tools also consumes context length, so inject only the tools truly needed by the current conversation.
  • Dynamic tool declarations use exactly the same format as global tools declarations, so integrators do not need to maintain two schemas.

Default parameters

Model

enable_thinking

temperature

top_p

presence_penalty

fps

max_frames

kimi-k3

true (thinking mode only, cannot be disabled)

1.0

0.95

0.0

-

-

kimi-k2.7-code

true (thinking mode only)

1.0

0.95

0.0

2

2000

kimi-k2.6

false

thinking mode: 1.0

non-thinking mode: 0.6

Both modes: 0.95

Both modes: 0.0

2

2000

kimi-k2.5

false

thinking mode: 1.0

non-thinking mode: 0.6

Both modes: 0.95

Both modes: 0.0

2

2000

kimi-k2-thinking

-

1.0

-

-

-

-

Moonshot-Kimi-K2-Instruct

-

0.6

1.0

0

-

-

A hyphen (-) indicates that the parameter is not applicable.

Models and billing

The Kimi series are large language models from Moonshot AI.
  • kimi-k3: Kimi's most capable flagship model to date. It always reasons and uses preserved thinking (thinking-only mode). Supports text and image input (video input is not supported), conversation and agent tasks, and dynamic tool loading.
  • kimi-k2.7-code: The most capable Kimi model for coding. It follows long-context instructions more reliably and achieves higher success rates on programming tasks. Supports text, image, and video input, thinking mode, conversation, and agent tasks.
  • kimi-k2.6: The newest and most capable model in the Kimi series. It offers improved performance in long-horizon coding, instruction following, and self-correction. Supports text, image, and video input, thinking and non-thinking modes, conversation, and agent tasks.
  • kimi-k2.5: It achieves state-of-the-art (SOTA) performance on open-source benchmarks for agent tasks, code generation, visual understanding, and other general intelligence tasks. Supports image, video, and text input, thinking and non-thinking modes, conversation, and agent tasks.
  • kimi-k2-thinking: Supports deep thinking mode only. It exposes the reasoning process through the reasoning_content field. It excels at coding and tool calling, and is suitable for use cases that require logical analysis, planning, or deep understanding.
  • Moonshot-Kimi-K2-Instruct: Does not support deep thinking. It generates responses with lower latency, and is suitable for use cases that need fast, direct answers.
kimi-k3 does not support the thinking_budget parameter. You cannot use this parameter to limit the thinking length.kimi-k3 does not support the OpenAI-compatible Responses API yet (coming soon). Use the OpenAI-compatible Chat Completions API instead.
For pricing, see model invocation billing.
For pricing and context window details, see the Model Studio console. Billing is based on input and output token counts.
In thinking mode, the chain of thought counts as output tokens.

Error codes

If a model call fails and returns an error message, see Error codes.
Token Plan
Model Playground
  • Music generation
Statistics and Monitoring
Support