Kimi K3.1 Pro API: Endpoints, Tool Calling, Caching und Fehlerbehandlung erklaert
Die Kimi K3.1 Pro API laeuft unter api.moonshot.ai mit den Modell-IDs kimi-k3.1-pro und kimi-k3.1-pro-highspeed. Sie unterstuetzt OpenAI Chat Completions, die Responses API und Anthropic Messages, sodass bestehende SDKs nach Anpassung der Base URL weiter nutzbar sind.

Posted on Oct 26 • Originally published at apidog.com
The Kimi K3.1 Pro API runs at https://api.moonshot.ai/v1 with model IDs kimi-k3.1-pro and kimi-k3.1-pro-highspeed. It speaks three wire formats: OpenAI Chat Completions, the Responses API and Anthropic Messages, so the SDKs you already use work with a changed base URL. The model unlocks after a $1 minimum top-up.
This is the reference for production code. For your first call, streaming and the Codex or Claude Code setups, read how to use Kimi K3.1 Pro; for costs, see Kimi K3.1 Pro pricing. Facts come from Moonshot's K3.1 Pro quickstart and linked docs, read October 24, 2026.
Moonshot exposes K3.1 Pro through three API surfaces. Pick the one your client library or agent already speaks; the model, key and billing are the same on all three.
They differ in how you set the cache TTL and where usage lands (see caching below). Coming from K3? Our Kimi K3 API guide still applies; K3.1 Pro is a post-trained K3 with the same 1,048,576-token context.
You need a funded account and a key from the right product. Four steps:
curl https://api.moonshot.ai/v1/models \ --header "Authorization: Bearer $MOONSHOT_API_KEY " | grep -o '"kimi-k3.1-pro[^"]*"' Enter fullscreen mode Exit fullscreen mode If the model isn't listed, fix that first. Kimi API, Kimi Code and Kimi Membership are separate products: a Kimi Code key won't work on the API endpoint, and a membership doesn't become API balance.
Most OpenAI parameters behave as you'd expect. These are the ones that differ or catch people out:
Reasoning tokens count toward your usage, so use "low" for classification and extraction. Preserved Thinking is always on, so every assistant message goes back with its reasoning_content intact ( thinking models guide ).
A production tool loop on K3.1 Pro follows four rules from Moonshot's docs:
import json, os from openai import OpenAI client = OpenAI ([ REDACTED CREDENTIAL ], base_url = " https://api.moonshot.ai/v1 " ) TOOLS = [{ " type ": " function ", " function ": { " name ": " get_order_status ", " description ": " Look up an order ' s shipping status by ID ", " parameters ": { " type ": " object ", " properties ": { " order_id ": { " type ": " string " }}, " required ": [ " order_id " ]}}}] def get_order_status ( order_id ): return { " order_id ": order_id, " status ": " shipped " } messages = [{ " role ": " user ", " content ": " Where is order A-1042? " }] tool_choice = " required " for _ in range ( 8 ): # hard cap on turns resp = client. chat. completions. create ( model = " kimi-k3.1-pro ", reasoning_effort = " high ", messages = messages, tools = TOOLS, tool_choice = tool_choice ) msg = resp. choices [ 0 ]. message messages. append ( msg ) # whole message, not msg.content if not msg. tool_calls: print ( msg. content ) break for call in msg. tool_calls: result = get_order_status ( ** json. loads ( call. function. arguments )) messages. append ({ " role ": " tool ", " tool_call_id ": call. id, " content ": json. dumps ( result )}) tool_choice = " auto " Enter fullscreen mode Exit fullscreen mode The classic bug is appending msg.content instead of msg, which drops tool_calls and reasoning_content.
When your agent has dozens or hundreds of tools, don't send every definition on every request. Moonshot's K3 tool calling best practice recommends this flow:
# after search_tools returns ["create_github_pr"] messages. append ({ " role ": " system ", " tools ": [ CATALOG [ " create_github_pr " ]]}) Enter fullscreen mode Exit fullscreen mode Injected definitions use the top-level tools format and apply from that message onward. The server doesn't retain them, so keep the message in later requests. Neither changing tool_choice nor appending a definition breaks the prefix cache.
K3.1 Pro accepts images and video alongside text and returns text. Make content an array of parts: an image_url part (the quickstart example sends a base64 data URL, and notes public image URLs aren't supported) or a video_url part that points at an uploaded file with an ms:// ID.
from pathlib import Path video = client. files. create ( file = Path ( " demo.mp4 " ), purpose = " video " ) content = [{ " type ": " video_url ", " video_url ": { " url ": f " ms:// { video. id } " }}, { " type ": " text ", " text ": " Summarize this video. " }] Enter fullscreen mode Exit fullscreen mode Pass content as the user message, and delete the file with client.files.delete(video.id) when you're done.
Caching is automatic for repeated prefixes with a 5-minute default TTL. Cache hits bill at $0.20 per million tokens against $2.00 for uncached input, and a 1-hour write costs $4.00 against $2.00 for 5 minutes. On a 1M-token prefix, the 1-hour TTL pays for itself after two hits.
Put stable content first (system prompt, tool definitions, docs), changing content last, and no timestamps in the prefix. With the openai SDK, pass the TTL through extra_body:
resp = client. chat. completions. create ( model = " kimi-k3.1-pro ", messages = [{ " role ": " system ", " content ": DOCS }, { " role ": " user ", " content ": question }], extra_body = { " prompt_cache_options ": { " mode ": " implicit ", " ttl ": " 1h " }}, ) d = resp. usage. prompt_tokens_details print ( resp. usage. prompt_tokens, d. cached_tokens, getattr ( d, " cache_write_tokens ", 0 )) Enter fullscreen mode Exit fullscreen mode The Anthropic API sets the TTL with a top-level cache_control field; markers inside messages are ignored:
curl https://api.moonshot.ai/anthropic/v1/messages \ --header "Content-Type: application/json" \ --header "Authorization: Bearer $MOONSHOT_API_KEY " \ --data '{"model": "kimi-k3.1-pro", "max_tokens": 256, "cache_control": {"type": "ephemeral", "ttl": "1h"}, "messages": [{"role": "user", "content": "Hello"}]}' Enter fullscreen mode Exit fullscreen mode Where cache usage shows up depends on the surface:
When streaming Chat Completions, set stream_options.include_usage=true to get usage in the final chunk. Each hit renews the TTL, which is locked at first write. Full rules: the context caching guide.
Most failures fall into six patterns. Check error.type on every 429, because the fix depends on it.
Watch retries. The OpenAI SDK retries 2 times by default on connection errors, 408, 409, 429 and 5xx, so one call can become three requests against your RPM. On a low tier, lower the client's max_retries and back off on error.type yourself. Requests interrupted by a 429 aren't charged.
If a third-party agent fails, call the API directly with the same key, endpoint and model. If that works, the tool is the problem. See the troubleshooting page and error codes.
Your cumulative top-up sets your tier on the limits page:
Tier0 allows 3 requests per minute, and every turn of a tool loop is a request. A five-turn agent run already spills past one minute at that tier, so budget $10 cumulative before you test agents seriously.
A contract test catches the day your tool loop stops getting tool_calls back. Let your coding agent build it with Apidog CLI. Install and log in once:
npm install -g apidog-cli@latest apidog login --with-token <YOUR_TOKEN> apidog skill install Enter fullscreen mode Exit fullscreen mode Then prompt Claude Code, Codex or whichever agent you use:
In Apidog project <projectId>, create an environment for https://api.moonshot.ai/v1 and an endpoint for POST /chat/completions. Add a test case that sends model kimi-k3.1-pro, reasoning_effort "low", one get_order_status tool and tool_choice "required". Assert status 200 and that choices.message.tool_calls is non-empty. Run it and report failures. Enter fullscreen mode Exit fullscreen mode The agent reads the schema, validates its payload and runs the case:
apidog environment create kimi-prod --project <projectId> --base-url https://api.moonshot.ai/v1 apidog endpoint create --project <projectId> --file./endpoint.json apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <projectId> --file case.json apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json Enter fullscreen mode Exit fullscreen mode Test cases need a valid category; apidog test-case category --project <projectId> lists them. Once the run passes, swap -r cli,json for -r junit with --out-dir and the same check gates your CI, as our Apidog CLI CI/CD guide shows. Agent setup lives in Apidog CLI in Claude Code. Apidog's Free plan covers up to 4 users.
https://api.moonshot.ai/v1 for Chat Completions and the Responses API, and https://api.moonshot.ai/anthropic for the Anthropic-compatible Messages API.
No. Thinking is always on. Control it with the top-level reasoning_effort field ( "low", "high" or "max" ).
Read error.type. engine_overloaded_error is server capacity and a top-up won't fix it. rate_limit_reached_error means your tier's limits, and Tier0 allows only 3 RPM.
A non-zero cache read field in usage means a hit: prompt_tokens_details.cached_tokens on Chat Completions or cache_read_input_tokens on Messages.
No. The API needs a $1 minimum top-up. Free chat in the Kimi app is the $0 route, covered in how to use Kimi K3.1 Pro for free. For model background, see what Kimi K3.1 Pro is.