Moonshot AI (Kimi)
Moonshot AI provides the Kimi family of models through a hosted API. Applications call Kimi through stable AISIX aliases while the gateway keeps the Moonshot credential out of client code.
Prerequisites
Before starting, prepare the following:
- One AISIX setup:
- For AISIX Cloud, an environment with an attached gateway and a write-scoped admin token. For On-Premises, follow the AISIX Cloud Quickstart. To request Hybrid Cloud access, contact API7.
- For the open-source AISIX gateway, prepare either a local AISIX installation or the Docker setup from the Open-Source AISIX Gateway Quickstart. Configure the gateway to load a declarative resources file.
- A Moonshot API key from the Kimi API Platform.
curlandjq.
Configure with AISIX Cloud
Export the AISIX Cloud connection details:
# AISIX_CP is the Admin API base URL; include /api and omit a trailing slash
# The local On-Premises quickstart uses http://localhost:8080/api
export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
Create a provider key, model alias, and caller API key for the Moonshot-backed chat-completions route.
Because Moonshot AI exposes an OpenAI-compatible API, AISIX connects through the openai adapter and uses the API root for the region where you created the credential.
Create a Provider Key
Moonshot AI serves its API from two independent hosts, and the catalog models them as two separate provider IDs. Pick the pair that matches the console where you created the API key:
| Provider ID | API root | Use when |
|---|---|---|
moonshotai | https://api.moonshot.ai/v1 | The key was issued on the global platform. |
moonshotai-cn | https://api.moonshot.cn/v1 | The key was issued on the China platform. |
The two hosts are separate deployments with separate consoles, so a key issued on one platform does not authenticate against the other. Select the provider ID that matches the key, rather than pointing one ID at the other platform's host: the provider ID is what usage records and cost reports attribute traffic to.
For new provider keys, api_base is optional on both IDs. The AISIX Cloud Admin API fills the global root for moonshotai and the China root for moonshotai-cn. The examples set it explicitly so the target platform remains visible.
An older moonshotai key created before the regional defaults were corrected can remain pinned to the China root. Set the global root explicitly when updating that configuration for a global-platform credential.
The examples below use moonshotai. If your account is on the China platform, substitute moonshotai-cn and https://api.moonshot.cn/v1 throughout.
Create the provider key that stores the Moonshot credential and API root, and capture its ID:
# Replace with your value
export MOONSHOT_API_KEY="YOUR_PROVIDER_API_KEY"
PROVIDER_KEY_ID=$(curl -sS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "moonshot-prod",
"provider": "moonshotai",
"api_key": "'"${MOONSHOT_API_KEY}"'",
"api_base": "https://api.moonshot.ai/v1",
"allowed_environments": ["'"${ENV_ID}"'"]
}' | jq -r '.provider_key.id')
echo "$PROVIDER_KEY_ID"
❶ provider is moonshotai, not moonshot or kimi. The AISIX Cloud Admin API only accepts catalog provider IDs and rejects other spellings with 400 INVALID_REQUEST. The AISIX Cloud Admin API derives the adapter from the catalog provider; the adapter field is only accepted on BYO provider keys.
❷ api_key stores the Moonshot API key and is sent as a bearer token. The value is encrypted before storage and never returned by read endpoints. It follows the credential-handling behavior in Provider Keys.
❸ api_base already includes the /v1 path segment, because Moonshot AI publishes its OpenAI-compatible surface under /v1 rather than at the host root. AISIX appends the endpoint path to it, so use https://api.moonshot.ai/v1 without a trailing /chat/completions. To route to the China platform instead, create a separate provider key with provider set to moonshotai-cn and api_base set to https://api.moonshot.cn/v1.
The command captures the returned provider key ID in PROVIDER_KEY_ID.
Create a Model
Moonshot model IDs follow a kimi-<generation> pattern, with an optional suffix for a task-specific or throughput-specific variant. For example, kimi-k2.6 is the general-purpose model, kimi-k2.7-code is the coding model, and kimi-k2.7-code-highspeed is its higher-throughput variant. kimi-k3 is the current flagship. Moonshot AI retires older snapshots such as the earlier kimi-k2-*-preview IDs, so confirm the ID against the Kimi model list before pinning it.
Create the model alias callers will send in requests:
MODEL_ID=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/models" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "kimi-k26-prod",
"model_name": "kimi-k2.6",
"provider_key_id": "'"${PROVIDER_KEY_ID}"'"
}' | jq -r '.model.id')
echo "$MODEL_ID"
❶ display_name is the alias callers send in model. The alias is independent of the upstream ID, so it does not need to carry the generation number.
❷ model_name is the Moonshot model ID, for example kimi-k2.6, kimi-k2.7-code, or kimi-k3. The dot is part of the upstream ID and must be preserved exactly.
❸ provider_key_id attaches the alias to the Moonshot provider key.
Create a Caller API Key
Create the caller API key that can access the model alias. The gateway generates the key value and returns the plaintext once in the create response, so capture it now:
AISIX_API_KEY=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/api_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "moonshot-caller",
"allowed_models": ["'"${MODEL_ID}"'"]
}' | jq -r '.plaintext')
echo "$AISIX_API_KEY"
The allowed_models value references the model by its ID, so the key can only access the alias you created. After the write, the configuration projects to attached gateways automatically.
Configure with the Open-Source AISIX Gateway
Export the upstream credential and choose the caller API key that applications will send to the gateway:
export MOONSHOT_API_KEY="YOUR_PROVIDER_API_KEY"
export CALLER_API_KEY="YOUR_CALLER_API_KEY"
Create a complete declarative resources file for this provider:
_format_version: "1"
provider_keys:
- display_name: "moonshot-prod"
provider: "moonshotai"
adapter: "openai"
api_key: ${MOONSHOT_API_KEY}
api_base: "https://api.moonshot.ai/v1"
models:
- display_name: "kimi-k26-prod"
provider: "moonshotai"
model_name: "kimi-k2.6"
provider_key: "moonshot-prod"
api_keys:
- display_name: "moonshot-caller"
key_env: CALLER_API_KEY
allowed_models:
- "kimi-k26-prod"
If AISIX is installed locally, validate the file before loading it:
aisix validate --resources resources.yaml
After validation, start the gateway with the referenced environment variables in its process environment. Reload an existing gateway only if those variables are already available to the process; otherwise, restart it with the updated environment.
If you use Docker, adapt the validation and startup commands in the Open-Source AISIX Gateway Quickstart. Mount this resources.yaml file and pass every environment variable it references with -e in both commands. After the resources load, prepare the shared verification request below:
export AISIX_API_KEY="$CALLER_API_KEY"
Verify the Provider Connection
Export the AISIX gateway origin:
# The local quickstarts use http://127.0.0.1:3000
export AISIX_PROXY="YOUR_AISIX_GATEWAY_ORIGIN"
Send a chat-completions request through the AISIX proxy:
curl -sS -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "kimi-k26-prod",
"messages": [
{
"role": "user",
"content": "Say hello from Kimi."
}
]
}'
The gateway returns an OpenAI-compatible response that echoes the caller-facing alias kimi-k26-prod. If the request fails, check the provider key api_key, api_base, and the Moonshot model ID in model_name. An authentication failure on a key that works in the Moonshot console usually means the api_base host does not match the platform that issued the key.
Use Thinking Mode
Current Kimi generations expose different reasoning controls. On kimi-k2.6, send {"type": "disabled"} in the top-level thinking object to turn reasoning off for a request:
{
"thinking": {
"type": "disabled"
}
}
AISIX forwards top-level request fields it does not model itself, including thinking, verbatim to the upstream, so no provider-key override is needed to use this control. Reasoning controls differ across model generations:
| Model | Reasoning control | Preserved thinking across turns |
|---|---|---|
kimi-k2.6 | thinking.type accepts enabled (default) or disabled. | thinking.keep defaults to null; set it to all to preserve historical reasoning_content. |
kimi-k2.7-code and kimi-k2.7-code-highspeed | Reasoning is always on. Omit thinking, or use the only accepted type, enabled. | Always on. The only accepted explicit thinking.keep value is all. |
kimi-k3 | Reasoning is always on and the thinking object is not supported. Set top-level reasoning_effort to low, high, or max (default). | Always on. |
Check the Kimi thinking mode guide for the parameters each model accepts.
Moonshot AI returns reasoning text in the reasoning_content field, which is the canonical field AISIX already normalizes to. On streaming responses, reasoning_content deltas arrive before content deltas; on non-streaming responses, the field appears at choices[0].message.reasoning_content. Because the upstream shape already matches, the moonshotai catalog entry sets no response.reasoning_field override and none is required. Set response.reasoning_field only for an upstream that streams reasoning from a different delta path.
For K3 and K2.7 tool loops or multi-turn conversations, append the complete assistant message returned by AISIX to the next chat-completions request. AISIX preserves message-level reasoning_content on this route. Copying only content and tool_calls loses the reasoning history that these models require. Apply the same rule to K2.6 when you set thinking.keep to all.
Reasoning tokens and final-answer tokens share Moonshot AI's max_completion_tokens budget. The deprecated max_tokens field remains accepted. Raise the limit when a reasoning-heavy prompt returns truncated content, and account for the same tokens when you set per-model budgets in AISIX.
Review Endpoint Support
Moonshot primarily documents Chat Completions plus OpenAI-compatible file and batch management. AISIX behavior depends on both the adapter and route-specific provider checks:
| Route | Behavior with a Moonshot alias |
|---|---|
/v1/chat/completions | Supported, including streaming, tools, structured output, and image or video content blocks on compatible Kimi models. |
/v1/responses | Supported through the chat-based Responses bridge, not a Moonshot-native Responses endpoint. The bridge drops Responses reasoning controls and does not encode Moonshot reasoning_content in the returned Responses output, so use chat completions for reasoning workflows. |
/v1/messages | Supported through Anthropic-to-chat translation, not Moonshot's separate Anthropic-compatible API. The bridge does not preserve Moonshot reasoning history as Anthropic thinking blocks. /v1/messages/count_tokens requires an Anthropic-backed model and rejects this configuration. |
/v1/files and /v1/batches | Supported through the openai adapter. AISIX rewrites returned resource IDs so later file and batch calls route to the same alias. Each request in an uploaded batch JSONL file must name the upstream Kimi model ID, such as kimi-k2.6; AISIX does not rewrite model names inside the file. |
/v1/embeddings, /v1/completions, /v1/audio/*, and /v1/fine_tuning/jobs | Not supported. Moonshot does not document compatible upstream endpoints for these routes. |
/v1/images/generations | Rejected with 400. The route requires a model whose provider is openai. |
/v1/rerank | Rejected with 400. The route accepts only the openai, cohere, and jina provider values. |
/v1/videos | Rejected with 501 not_implemented. The route's provider allowlist does not include moonshotai. Kimi's video capability is video understanding through chat input, not video generation. |
/passthrough/moonshotai/* | Available through a configured passthrough route for Moonshot-native routes beneath the route's /v1 target. |
The routed ID returned by normalized /v1/files is suitable for later normalized file and batch routes. It is not a raw Moonshot file ID. When a Kimi chat message must reference an uploaded image or video as ms://<file-id>, upload and manage that asset through /passthrough/moonshotai/files so the application receives the native ID.
For a Moonshot-native endpoint that AISIX does not model, use a passthrough route. The /passthrough/moonshotai paths on this page assume a route claiming that prefix with https://api.moonshot.ai/v1 as its target_url; grant the route name on the caller key's allowed_routes:
curl -sS -X GET "$AISIX_PROXY/passthrough/moonshotai/v1/models" \
-H "Authorization: Bearer ${AISIX_API_KEY}"
Passthrough keeps caller authentication and, on an inject-mode route, injects the route's provider key credential upstream. When the request path starts with the same version segment that already ends the route's target_url, AISIX collapses the duplicate, so the request above reaches https://api.moonshot.ai/v1/models rather than a doubled /v1/v1 path.
Other useful native paths include /tokenizers/estimate-token-count, /users/me/balance, /files, and /batches. Passthrough does not rewrite an AISIX model alias or resource ID and relays upstream responses and SSE incrementally. AISIX detects chat, completions, and Responses envelopes and records supported usage fields. Requests without a recognized carrier field remain opaque: buffered responses record zero tokens, while opaque SSE can still record top-level supported usage fields. Each route binds one fixed target and, in inject mode, one provider key, so create separate routes when several Moonshot accounts or roots are in use.
Moonshot's Anthropic-compatible API uses the separate https://api.moonshot.ai/anthropic root. It is outside the /v1 root used in this guide, so a route targeting that root cannot reach it; the Anthropic-compatible API needs its own passthrough route.
Next Steps
You have now connected AISIX to Moonshot AI and verified the model alias. Continue with these guides:
- Model Aliases: configure routing, retry behavior, or cost metadata for this alias.
- Routing and Failover: fail over between Moonshot AI and a second provider.
- Provider-Specific Overrides: adapt request and response shapes when an upstream API differs from its adapter.
- Provider Compatibility: review supported proxy endpoints and provider-specific boundaries.