Skip to main content

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.
  • curl and jq.

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 IDAPI rootUse when
moonshotaihttps://api.moonshot.ai/v1The key was issued on the global platform.
moonshotai-cnhttps://api.moonshot.cn/v1The 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:

resources.yaml
_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:

ModelReasoning controlPreserved thinking across turns
kimi-k2.6thinking.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-highspeedReasoning is always on. Omit thinking, or use the only accepted type, enabled.Always on. The only accepted explicit thinking.keep value is all.
kimi-k3Reasoning 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:

RouteBehavior with a Moonshot alias
/v1/chat/completionsSupported, including streaming, tools, structured output, and image or video content blocks on compatible Kimi models.
/v1/responsesSupported 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/messagesSupported 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/batchesSupported 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/jobsNot supported. Moonshot does not document compatible upstream endpoints for these routes.
/v1/images/generationsRejected with 400. The route requires a model whose provider is openai.
/v1/rerankRejected with 400. The route accepts only the openai, cohere, and jina provider values.
/v1/videosRejected 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: