Messages API
Call Kimi models with an Anthropic Messages API compatible format, supporting streaming, tool use, image input, thinking, and structured output.
curl --request POST \
--url https://api.moonshot.ai/anthropic/v1/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "kimi-k3",
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"max_tokens": 2
}
'import requests
url = "https://api.moonshot.ai/anthropic/v1/messages"
payload = {
"model": "kimi-k3",
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"max_tokens": 2
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({model: 'kimi-k3', messages: [{role: 'user', content: 'Hello'}], max_tokens: 2})
};
fetch('https://api.moonshot.ai/anthropic/v1/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.moonshot.ai/anthropic/v1/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'kimi-k3',
'messages' => [
[
'role' => 'user',
'content' => 'Hello'
]
],
'max_tokens' => 2
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.moonshot.ai/anthropic/v1/messages"
payload := strings.NewReader("{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.moonshot.ai/anthropic/v1/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/anthropic/v1/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"type": "message",
"role": "assistant",
"model": "<string>",
"content": [
{
"type": "thinking",
"thinking": "<string>",
"signature": "<string>"
}
],
"stop_reason": "end_turn",
"stop_sequence": "<string>",
"usage": {
"input_tokens": 123,
"output_tokens": 123,
"cache_read_input_tokens": 123,
"cache_creation_input_tokens": 123,
"cache_creation": {
"ephemeral_5m_input_tokens": 123,
"ephemeral_1h_input_tokens": 123
},
"output_tokens_details": {
"thinking_tokens": 123
}
}
}{
"type": "error",
"error": {
"type": "<string>",
"message": "<string>"
},
"request_id": "<string>"
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"type": "error",
"error": {
"type": "<string>",
"message": "<string>"
},
"request_id": "<string>"
}https://api.moonshot.ai/anthropic to call Kimi models directly.
Context Caching (Cache Write)
Context Caching (Cache Write)
cache_control field (only effective at the top level; cache_control markers inside the messages array are ignored):| Parameter | Type | Description |
|---|---|---|
cache_control | object | Context cache write options, only effective when passed at the top level; when omitted, the request only reads the cache (5m tier) without writing |
cache_control.type | "ephemeral" | Cache type, fixed as ephemeral |
cache_control.ttl | "5m" | "1h" | Lifetime of the written cache. Only 5m and 1h are supported (default 5m); the two tiers are independent |
- Pass top-level
cache_control: write the request prefix to the cache with the given TTL. - Omit
cache_control: the request only attempts to read the cache (5mtier) and does not write, so no cache write charge is incurred.
{
"model": "kimi-k3",
"cache_control": { "type": "ephemeral", "ttl": "1h" },
"messages": [{"role": "user", "content": "Hello"}]
}
- The cache is isolated per organization (org); caches are never shared across organizations.
- When a request with the same prefix hits the cache within its lifetime, the cache entry is refreshed with its original TTL. Cache hits are billed only at the cache read price, with no additional cache write charge.
- Cache writes are billed by TTL; see Pricing for details.
- Manual cache clearing is not supported; cached prefixes expire automatically after at least 5 minutes of inactivity.
| Field | Description |
|---|---|
usage.input_tokens | Input tokens neither read from the cache nor used to create a cache entry |
usage.cache_read_input_tokens | Input tokens read from the cache (cache read) |
usage.cache_creation_input_tokens | Input tokens written to the cache when creating a new entry (cache write) |
usage.cache_creation.ephemeral_5m_input_tokens | Input tokens written to the 5m tier |
usage.cache_creation.ephemeral_1h_input_tokens | Input tokens written to the 1h tier |
input_tokens + cache_read_input_tokens + cache_creation_input_tokens.input_tokens on this page differs from the Chat Completions / Responses API: in those APIs, prompt_tokens / input_tokens is always the total input, with cache reads and writes broken out in their respective details fields.Authorizations
The Authorization header expects a Bearer token. Use an MOONSHOT_API_KEY as the token. This is a server-side secret key. Generate one on the API keys page in your dashboard.
Headers
A client-generated random nonce (a UUID v4 is recommended). Sending it enables Request Signature: the Kimi API returns Msh-Request-Timestamp and Msh-Request-Signature in the response headers, which can later be used to prove that the request was handled by the Kimi API. Exactly one non-empty header value is allowed; if the value is invalid, the request proceeds normally but the headers above are not returned. See Verify Request Signature.
1"7d929748-0ae6-41c2-ab5d-a186498ad721"
Body
Model ID
kimi-k3 The conversation messages. If the last message is from the assistant, the model continues from that content (Partial Mode).
Show child attributes
Show child attributes
Maximum number of tokens to generate, required. If the limit is reached before the model finishes, stop_reason is max_tokens.
x >= 1System prompt, either a string or an array of text blocks
Whether to stream the response as Server-Sent Events, default false
Stop sequences. Generation stops on an exact match; the matched sequence itself is not output. Up to 5 entries, each at most 32 bytes.
5List of tools the model may call
Show child attributes
Show child attributes
Controls whether the model calls tools. auto (default): the model decides; any: force a call to any tool; none: do not call tools.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Context cache write options. Only effective when passed at the top level; cache_control markers inside the messages array are ignored. When omitted, the request only attempts to read the cache (5m tier) and does not write
Show child attributes
Show child attributes
Output configuration: reasoning effort and structured output
Show child attributes
Show child attributes
Response
Message response
Unique identifier of the response
message "message"
assistant The model specified in the request
Content blocks, ordered thinking → text → tool_use
- thinking
- text
- tool_use
Show child attributes
Show child attributes
Stop reason. end_turn: finished naturally (including a stop_sequences match); max_tokens: reached the max_tokens limit; tool_use: the model issued a tool call; refusal: content safety review was triggered.
end_turn, max_tokens, tool_use, refusal, null The stop sequence that was matched
Token usage
Show child attributes
Show child attributes
Was this page helpful?
curl --request POST \
--url https://api.moonshot.ai/anthropic/v1/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "kimi-k3",
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"max_tokens": 2
}
'import requests
url = "https://api.moonshot.ai/anthropic/v1/messages"
payload = {
"model": "kimi-k3",
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"max_tokens": 2
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({model: 'kimi-k3', messages: [{role: 'user', content: 'Hello'}], max_tokens: 2})
};
fetch('https://api.moonshot.ai/anthropic/v1/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.moonshot.ai/anthropic/v1/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'kimi-k3',
'messages' => [
[
'role' => 'user',
'content' => 'Hello'
]
],
'max_tokens' => 2
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.moonshot.ai/anthropic/v1/messages"
payload := strings.NewReader("{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.moonshot.ai/anthropic/v1/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/anthropic/v1/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"kimi-k3\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello\"\n }\n ],\n \"max_tokens\": 2\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"type": "message",
"role": "assistant",
"model": "<string>",
"content": [
{
"type": "thinking",
"thinking": "<string>",
"signature": "<string>"
}
],
"stop_reason": "end_turn",
"stop_sequence": "<string>",
"usage": {
"input_tokens": 123,
"output_tokens": 123,
"cache_read_input_tokens": 123,
"cache_creation_input_tokens": 123,
"cache_creation": {
"ephemeral_5m_input_tokens": 123,
"ephemeral_1h_input_tokens": 123
},
"output_tokens_details": {
"thinking_tokens": 123
}
}
}{
"type": "error",
"error": {
"type": "<string>",
"message": "<string>"
},
"request_id": "<string>"
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"type": "error",
"error": {
"type": "<string>",
"message": "<string>"
},
"request_id": "<string>"
}