curl --request POST \
--url https://api.moonshot.ai/v1/signatures/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"nonce": "7d929748-0ae6-41c2-ab5d-a186498ad721",
"timestamp": 1786338000123,
"model": "kimi-k2.7-code",
"signature": "reqsigv1_<opaque-token>"
}
'import requests
url = "https://api.moonshot.ai/v1/signatures/verify"
payload = {
"nonce": "7d929748-0ae6-41c2-ab5d-a186498ad721",
"timestamp": 1786338000123,
"model": "kimi-k2.7-code",
"signature": "reqsigv1_<opaque-token>"
}
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({
nonce: '7d929748-0ae6-41c2-ab5d-a186498ad721',
timestamp: 1786338000123,
model: 'kimi-k2.7-code',
signature: 'reqsigv1_<opaque-token>'
})
};
fetch('https://api.moonshot.ai/v1/signatures/verify', 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/v1/signatures/verify",
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([
'nonce' => '7d929748-0ae6-41c2-ab5d-a186498ad721',
'timestamp' => 1786338000123,
'model' => 'kimi-k2.7-code',
'signature' => 'reqsigv1_<opaque-token>'
]),
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/v1/signatures/verify"
payload := strings.NewReader("{\n \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\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/v1/signatures/verify")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/v1/signatures/verify")
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 \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\n}"
response = http.request(request)
puts response.read_body{
"valid": true
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}Verify Request Signature
Verify a request signature to prove that a request was handled by the Kimi API for the specified model, rather than routed elsewhere.
curl --request POST \
--url https://api.moonshot.ai/v1/signatures/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"nonce": "7d929748-0ae6-41c2-ab5d-a186498ad721",
"timestamp": 1786338000123,
"model": "kimi-k2.7-code",
"signature": "reqsigv1_<opaque-token>"
}
'import requests
url = "https://api.moonshot.ai/v1/signatures/verify"
payload = {
"nonce": "7d929748-0ae6-41c2-ab5d-a186498ad721",
"timestamp": 1786338000123,
"model": "kimi-k2.7-code",
"signature": "reqsigv1_<opaque-token>"
}
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({
nonce: '7d929748-0ae6-41c2-ab5d-a186498ad721',
timestamp: 1786338000123,
model: 'kimi-k2.7-code',
signature: 'reqsigv1_<opaque-token>'
})
};
fetch('https://api.moonshot.ai/v1/signatures/verify', 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/v1/signatures/verify",
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([
'nonce' => '7d929748-0ae6-41c2-ab5d-a186498ad721',
'timestamp' => 1786338000123,
'model' => 'kimi-k2.7-code',
'signature' => 'reqsigv1_<opaque-token>'
]),
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/v1/signatures/verify"
payload := strings.NewReader("{\n \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\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/v1/signatures/verify")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/v1/signatures/verify")
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 \"nonce\": \"7d929748-0ae6-41c2-ab5d-a186498ad721\",\n \"timestamp\": 1786338000123,\n \"model\": \"kimi-k2.7-code\",\n \"signature\": \"reqsigv1_<opaque-token>\"\n}"
response = http.request(request)
puts response.read_body{
"valid": true
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}X-Msh-Request-Nonce request header. The response then carries Msh-Request-Timestamp (the Unix millisecond timestamp at which the Kimi API accepted the request) and Msh-Request-Signature (a signature token prefixed with reqsigv1_), for both streaming and non-streaming requests. Submit the nonce, timestamp, the request’s model, and the signature to this endpoint; it returns valid: true when the signature matches all three exactly, and valid: false otherwise.
The signature only proves that the Kimi API accepted this nonce and request model at that time; it does not prove that the request ultimately succeeded or that the response is complete. The server does not record nonces, so replaying the same parameters still returns valid: true — replay protection and validity windows are the caller’s responsibility.
Example
Example
import os
import uuid
import requests
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url="https://api.moonshot.ai/v1",
)
nonce: str = str(uuid.uuid4())
model: str = "kimi-k2.7-code"
# 1. Call the model endpoint with X-Msh-Request-Nonce and read the response headers
raw = client.chat.completions.with_raw_response.create(
model=model,
messages=[{"role": "user", "content": "Hello"}],
extra_headers={"X-Msh-Request-Nonce": nonce},
)
timestamp: int = int(raw.headers["Msh-Request-Timestamp"])
signature: str = raw.headers["Msh-Request-Signature"]
# 2. Verify the signature
verify = requests.post(
"https://api.moonshot.ai/v1/signatures/verify",
headers={
"Authorization": f"Bearer {os.environ['MOONSHOT_API_KEY']}",
"Content-Type": "application/json",
},
json={
"nonce": nonce,
"timestamp": timestamp,
"model": model,
"signature": signature,
},
)
print(verify.json()) # {"valid": true}
NONCE="$(uuidgen)"
MODEL="kimi-k2.7-code"
# 1. Call the model endpoint with X-Msh-Request-Nonce and save the response headers
curl -sS -D response.headers -o response.json \
https://api.moonshot.ai/v1/chat/completions \
-H "Authorization: Bearer $MOONSHOT_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Msh-Request-Nonce: $NONCE" \
-d "{\"model\": \"$MODEL\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}]}"
TIMESTAMP="$(awk -F': ' 'tolower($1)=="msh-request-timestamp" {gsub("\\r", "", $2); print $2}' response.headers)"
SIGNATURE="$(awk -F': ' 'tolower($1)=="msh-request-signature" {gsub("\\r", "", $2); print $2}' response.headers)"
# 2. Verify the signature
curl -sS https://api.moonshot.ai/v1/signatures/verify \
-H "Authorization: Bearer $MOONSHOT_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"nonce\": \"$NONCE\", \"timestamp\": $TIMESTAMP, \"model\": \"$MODEL\", \"signature\": \"$SIGNATURE\"}"
const { randomUUID } = require("crypto");
const OpenAI = require("openai");
const apiKey = process.env.MOONSHOT_API_KEY;
const client = new OpenAI({
apiKey,
baseURL: "https://api.moonshot.ai/v1",
});
async function main() {
const nonce = randomUUID();
const model = "kimi-k2.7-code";
// 1. Call the model endpoint with X-Msh-Request-Nonce and read the response headers
const { response } = await client.chat.completions
.create(
{ model, messages: [{ role: "user", content: "Hello" }] },
{ headers: { "X-Msh-Request-Nonce": nonce } },
)
.withResponse();
const timestamp = Number(response.headers.get("Msh-Request-Timestamp"));
const signature = response.headers.get("Msh-Request-Signature");
// 2. Verify the signature
const verify = await fetch("https://api.moonshot.ai/v1/signatures/verify", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ nonce, timestamp, model, signature }),
});
console.log(await verify.json()); // { valid: true }
}
main();
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.
Body
The nonce sent in the X-Msh-Request-Nonce request header of the model call, exactly as sent.
1"7d929748-0ae6-41c2-ab5d-a186498ad721"
The Unix millisecond timestamp returned in the Msh-Request-Timestamp response header of the model call.
x >= 11786338000123
The model value from the request body of the model call, exactly as sent.
1"kimi-k2.7-code"
The signature token returned in the Msh-Request-Signature response header of the model call.
1"reqsigv1_<opaque-token>"
Response
Verification result
Whether the signature is valid. true means the signature was issued by the Kimi API and matches the submitted nonce, timestamp, and model exactly; otherwise false.
true
Was this page helpful?