Kimi K3.1 Pro costs $2 per million input tokens and $10 per million output, a third less than the Kimi K3 model it replaces. It keeps K3’s 2.8T-parameter mixture-of-experts with 104B parameters active per token and the same 1M-token context, and Artificial Analysis already scores it 55 on its Intelligence Index, eleven points above K3. The wiring is what will cost you an afternoon. Moonshot runs two API endpoints with two model ID schemes, and on one of them a mistyped ID quietly routes your agent to K2.8 Preview with thinking switched off.
This guide explains what changed, which endpoint and model ID your coding agent needs, and how to wire kimi-k3.1-pro into Kimi Code CLI and Claude Code. We installed both agents on an Ubuntu 26.04 VM and pointed them at api.moonshot.ai with a deliberately invalid key to see how each one fails. We had no funded key, so the benchmark numbers come from Moonshot and Artificial Analysis. The setup and failure behavior described here was checked against Kimi Code CLI 2.3.2 and Claude Code 2.1.310 in October 2026.
What changed between Kimi K3 and K3.1 Pro
K3.1 Pro is K3 with a much larger post-training run on top, not a new architecture. Moonshot’s K3.1 Pro technical blog calls it “a post-trained version of Kimi K3, with substantially larger post-training compute”, spent on joint reinforcement learning across hundreds of task domains. So the parameter count, the context window and the reasoning controls carry over, while the price, the benchmark scores and the hallucination rate moved. The side-by-side below uses Moonshot’s API price list and the public benchmark figures:
| Item | Kimi K3 | Kimi K3.1 Pro |
|---|---|---|
| API model ID | kimi-k3 | kimi-k3.1-pro, kimi-k3.1-pro-highspeed |
| Architecture | MoE, 2.8T total, 104B active | Same base, post-trained further |
| Context window | 1,048,576 tokens | 1,048,576 tokens |
| reasoning_effort | low, high, max | low, high, max |
| Input / cached input / output per 1M tokens | $3.00 / $0.30 / $15.00 | $2.00 / $0.20 / $10.00 |
| Highspeed variant | None | $4.00 / $0.20 / $20.00, about 2 to 3x faster |
| Kimi Code Bench 3.0 Long-horizon (Moonshot) | 55.95% | 61.2% |
| Terminal-Bench 4.0 (Moonshot, Claude Code harness) | Not published | 65.7% |
| Hallu Bench Hard with tools, claim-level hallucination (Moonshot) | 23.4% | 8.3% |
| Artificial Analysis Intelligence Index | 44 | 55 |
| Output speed (Artificial Analysis) | 52.7 tokens/s | 52.2 tokens/s |
| Open weights | Published | Promised by November 4, 2026 |
Read the table as “smarter and cheaper, not faster”. The per-token price dropped by a third and the coding scores rose. Artificial Analysis still clocks both models at about 52 output tokens per second and labels K3.1 Pro “notably slow and very verbose”, with 150M output tokens spent on its index run. Verbosity matters for agents, because a coding loop pays for every reasoning token, so a cheaper rate on a talkative model does not automatically mean a cheaper task. Our own K3 versus GPT-6 Astra cost test found exactly that with K3, where token volume, not the rate card, decided the invoice. Caching is automatic on K3-series models, and cache writes are billed on top: $2.00 per million tokens for the default 5-minute TTL on K3.1 Pro and $4.00 for the 1-hour TTL.
Two other changes are easy to miss. The Highspeed variant is the only lever Moonshot gives you on latency, and it doubles the input and output rates while keeping the same cached-input price. And Moonshot says it removed cyber-related training data before the open-weight release, which drops K3.1 Pro to 81.0% on its internal exploit benchmark against 90.5% for the unfiltered checkpoint. The rest of the launch post covers 3D modelling, finance workbooks and the kimi.ai consumer app, none of which changes how you call the API.
Why K3.1 Pro has no medium reasoning effort
K3.1 Pro takes three values in its reasoning_effort field, low, high and max, with nothing in between. Some early write-ups call the middle level medium, but Moonshot’s K3.1 Pro quickstart names it high, and the Kimi Code docs map a medium sent by a third-party tool to high. The default is where the two Moonshot services disagree, and that difference changes your bill:
- Kimi API Platform: a request with no
reasoning_effortruns atmax, the same setting Moonshot used for its published benchmarks. - Kimi Code subscription: no effort means
high;max,xhighandultraall map tomax, andlow,minimumandlightmap tolow. - Thinking off: K3.1 Pro always thinks; the subscription endpoint answers a thinking-off request with HTTP 400, while K3 there quietly serves it from K2.8 Preview without thinking.
So the same agent config can run K3.1 Pro at two different effort levels depending on which endpoint it points at. When you pay per token on the Platform API, we’d set the effort explicitly rather than inherit max. An agent that reads files and edits code in a loop rarely needs the deepest setting on every turn, and the longest reasoning traces are the ones you pay $10 per million for. Keep max for the planning or debugging turns where you actually want the model to think longer.
Which Kimi K3.1 Pro API endpoint and model ID to use
Moonshot sells K3.1 Pro through two services that look alike from inside a coding agent but bill differently and name the model differently. Pick one before you touch a config file, because the base URL and the model ID have to come from the same row:
| Item | Kimi API Platform | Kimi Code subscription |
|---|---|---|
| Billing | Pay per token, unlocked after a $1 top-up | Monthly plan quota (K3.1 Pro on Plus and above, 1M context on Pro and above) |
| OpenAI-compatible base URL | https://api.moonshot.ai/v1 | https://api.kimi.ai/coding/v1 |
| Anthropic-compatible base URL | https://api.moonshot.ai/anthropic | https://api.kimi.ai/coding/ |
| Model IDs | kimi-k3.1-pro, kimi-k3.1-pro-highspeed, kimi-k3 | k3.1-pro, k3.1-pro-highspeed, k3, k3-256k, kimi-for-coding, kimi-for-coding-highspeed |
| Default effort | max | high |
| Mistyped model ID | Expected to error (our test hit the 401 first) | Falls back to K2.8 Preview without thinking |
Moonshot prints the last row as a warning on its Kimi Code model page: “A mistyped model ID falls back to K2.8 Preview without thinking.” Nothing errors and the agent keeps working. You only notice when the answers get worse. Pasting a Platform ID such as kimi-k3.1-pro into a tool that points at the subscription URL is the most likely way to trigger it, because the two ID schemes differ by a prefix. Use the subscription when you already pay for Kimi Code and want flat monthly costs; use the Platform API when you need per-request billing that tracks exactly what each request used. Users in mainland China swap the subscription hosts for api.kimi.com/coding. Everything below uses the Platform API.
How to check a Moonshot API key before an agent uses it
Create the key in the API Keys page of the Kimi API Platform console and add at least $1 of credit, because K3.1 Pro stays locked until the first top-up. Then test the key with curl before any agent sees it. Curl answers in under half a second, while one of the agents below takes three minutes to report the same problem. Export the key once so every later command reads it from the environment instead of the command line:
export MOONSHOT_API_KEY="your-moonshot-api-key"
Then send the smallest useful request: a chat completion against kimi-k3.1-pro at low effort, with curl printing the HTTP status and the round-trip time after the body:
curl -s https://api.moonshot.ai/v1/chat/completions \
-H "Authorization: Bearer $MOONSHOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"kimi-k3.1-pro","reasoning_effort":"low","messages":[{"role":"user","content":"pong?"}]}' \
-w "\nHTTP %{http_code} time %{time_total}s\n"
With our invalid key, the endpoint refused the request in 0.44 seconds:
{"error":{"message":"Invalid Authentication","type":"invalid_authentication_error"}}
HTTP 401 time 0.440644s
Two details in that test are worth knowing. A request sent with no Authorization header at all gets a different message, Incorrect API key provided with type incorrect_api_key_error, so the wording tells you whether the key was missing or wrong. And the endpoint checks the key before it looks at the model: the same request with the typo kimi-k3.1pro returned the identical 401. A bad key therefore hides a bad model ID, which is why the key check comes first. With a funded key, the same command returns a normal chat completion and HTTP 200; we could not capture that response for this guide.
How Kimi Code CLI talks to K3.1 Pro
Kimi Code CLI is Moonshot’s own terminal agent, and it is now a single native binary rather than the Python package. The old kimi-cli on PyPI is archived and points to Kimi Code, so if you followed our earlier Kimi CLI with OpenRouter walkthrough, the new binary ships a kimi migrate command that imports data from the legacy install. Both tools install a command named kimi. Install it as your normal user:
curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash
Kimi’s installer resolves the latest release, verifies a checksum and drops the binary in your home directory, so it needs no Node.js and no root:
==> Detected target: linux-x64
==> Resolving latest version from https://code.kimi.com/kimi-code/latest
==> Latest version: 2.3.2
==> Fetching manifest https://code.kimi.com/kimi-code/binaries/2.3.2/manifest.json
==> Downloading https://code.kimi.com/kimi-code/binaries/2.3.2/kimi-code-linux-x64.tar.gz
==> Extracting tarball
==> Verifying checksum
==> Installed to /home/gedion/.kimi-code/bin/kimi
==> Added /home/gedion/.kimi-code/bin to PATH in /home/gedion/.bashrc
==> Done. Run: kimi --version
==> If `kimi` is not found, restart your shell or run: source /home/gedion/.bashrc
Kimi’s installer writes the PATH line to ~/.bashrc, which only interactive shells read. Scripts and bash -lc calls will not find kimi until you either source that file or call the binary by its full path. Reload the current shell:
source ~/.bashrc
Kimi Code’s own /login flow is built around the subscription. For the Platform API, a provider entry in the config file is cleaner, because it keeps the key out of the file and pins the exact model ID. Kimi Code reads ~/.kimi-code/config.toml, which the CLI creates on its first run, so replace the whole contents rather than appending to it (a second default_model line breaks the TOML):
vim ~/.kimi-code/config.toml
This is the exact file we validated and ran:
default_model = "kimi-k3.1-pro"
[providers.moonshot]
type = "kimi"
base_url = "https://api.moonshot.ai/v1"
api_key_env = "MOONSHOT_API_KEY"
[models."kimi-k3.1-pro"]
provider = "moonshot"
model = "kimi-k3.1-pro"
max_context_size = 1048576
capabilities = ["thinking", "always_thinking", "image_in", "video_in", "tool_use"]
display_name = "Kimi K3.1 Pro"
support_efforts = ["low", "high", "max"]
default_effort = "high"
Each part of that file has a job, and two of them trip people up:
type = "kimi": the OpenAI-compatible provider type; its default base URL is alreadyhttps://api.moonshot.ai/v1, so the line is there for clarity.api_key_env: the CLI never reads keys from your shell on its own, so this line is what links it toMOONSHOT_API_KEY, re-read on every request.[models."kimi-k3.1-pro"]: the quotes are required, because a bare dot in a TOML table name starts a nested table.always_thinkinganddefault_effort: the first tells the CLI it cannot turn thinking off for this model, and the second is the effort Kimi Code asks for instead of the Platform API’smaxdefault. Kimi Code’s docs warn that a managed model refresh may rewritedefault_effort, and a[models."kimi-k3.1-pro".overrides]table pins it if that happens.
The section name after models. is the alias you pass to -m and see in /model, and model is the ID sent to the API. We kept them identical so there is only one string to get right. Check the file before you run anything against the API:
kimi doctor config
A clean file prints a single OK line and exits 0:
Kimi doctor
OK config.toml /home/gedion/.kimi-code/config.toml
All checked config files are valid.
Kimi doctor only checks the file’s structure, not whether the key or the model ID works. For that, kimi -p runs one prompt without opening the interactive interface. We ran it with the invalid key exported, then with a typo in the model alias:

Kimi Code fails fast and says why. The bad key came back as provider.auth_error: 401 Invalid Authentication in 3.7 seconds. The typo never left the machine: the CLI rejected kimi-k3.1pro in 2.3 seconds because no model with that alias exists in config.toml, which is the opposite of the silent fallback on the subscription endpoint. Once your real key is exported, the same kimi -p call should print the model’s reply, and plain kimi opens the interactive agent in the current directory. Our installer run also wrote mainland-cn to ~/.kimi-code/region; the provider block sets the base URL explicitly, so that marker made no difference to this setup.
Error: “declares api_key_env = “MOONSHOT_API_KEY” in config.toml, but the environment variable is not set or is empty”
Kimi Code printed this when we ran kimi -p from a shell where the variable had not been exported. It is common after a reboot or inside a cron job or systemd unit, which don’t inherit your interactive environment. Export MOONSHOT_API_KEY in that context, or set it in your shell profile, then rerun the command.
How Claude Code reaches K3.1 Pro through the Anthropic-compatible endpoint
Claude Code speaks the Anthropic Messages API, and Moonshot serves that protocol at https://api.moonshot.ai/anthropic, so the whole setup is a handful of environment variables. Moonshot documents this path in its Claude Code guide, and the same docs also cover OpenCode and Codex. If Claude Code is not installed yet, our Claude Code install guide for Ubuntu 26.04 covers it; the native installer is a single command:
curl -fsSL https://claude.ai/install.sh | bash
Claude Code’s binary goes to ~/.local/bin/claude, and the installer warns when that directory is missing from your PATH. Add it and reload the shell:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc
On a VM, check the CPU type first, because Claude Code is a Bun binary and Bun needs SSE4.2. Our Proxmox VM used the kvm64 CPU type, and both the native installer and the npm package died with this error:
error: this CPU is missing SSE4.2 support, which Bun requires.
If this is a VM, enable host CPU passthrough (e.g. -cpu host for QEMU/KVM).
Setting the VM’s CPU type to host, then powering the VM off and starting it again, fixed it, and grep -o -m1 sse4_2 /proc/cpuinfo confirms the flag before you retry. Claude Code reads its environment overrides from ~/.claude/settings.json, and Moonshot’s guide notes that this env block wins over variables exported in your terminal. If the file already exists, merge the env keys into it instead of replacing your other settings:
vim ~/.claude/settings.json
This is the settings file from our run, with the key replaced by a placeholder. Paste your real key into ANTHROPIC_AUTH_TOKEN, because the file does not expand shell variables such as $MOONSHOT_API_KEY, and keep it out of any repository since the key sits there in plain text:
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.moonshot.ai/anthropic",
"ANTHROPIC_AUTH_TOKEN": "your-moonshot-api-key",
"ANTHROPIC_MODEL": "kimi-k3.1-pro[1m]",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "kimi-k3.1-pro[1m]",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "kimi-k3.1-pro[1m]",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "kimi-k3.1-pro-highspeed[1m]",
"ANTHROPIC_DEFAULT_FABLE_MODEL": "kimi-k3.1-pro[1m]",
"CLAUDE_CODE_SUBAGENT_MODEL": "kimi-k3.1-pro-highspeed[1m]",
"CLAUDE_CODE_AUTO_COMPACT_WINDOW": "1000000",
"CLAUDE_CODE_EFFORT_LEVEL": "high"
}
}
Moonshot’s published block still targets K3. It sets kimi-k3[1m] for every tier, kimi-k2.7-code for Haiku and max for the effort level, and only its verification request uses kimi-k3.1-pro. We kept its [1m] pattern on the K3.1 Pro IDs, because Claude Code does not recognize Moonshot model names. Without the suffix it assumes a 200K window and caps CLAUDE_CODE_AUTO_COMPACT_WINDOW there. Per the Claude Code model configuration docs, the suffix declares the 1M context and is stripped before the ID is sent. The Highspeed variant goes on the Haiku tier and on subagents, where short background calls benefit from speed. That doubles the per-token price of all subagent traffic, so use the plain ID there if cost matters more than wait time.
We also wanted to know whether Claude Code passes the effort level to a model it does not recognize, so we pointed ANTHROPIC_BASE_URL at a small local listener on the VM that logged each request body. With the file above, the request carried the bare model ID, a 32,000-token output cap, adaptive thinking and the effort setting (metadata and context-management fields trimmed):
{"model": "kimi-k3.1-pro", "max_tokens": 32000, "thinking": {"type": "adaptive", "display": "omitted"}, "output_config": {"effort": "high"}, "stream": true}
So the [1m] suffix never reaches Moonshot, and high does leave Claude Code as output_config.effort. Moonshot does not document how its Anthropic-compatible endpoint maps that field onto reasoning_effort. We could not see a real response either, so treat the effort as requested rather than confirmed. Moonshot’s guide also warns that an old ANTHROPIC_API_KEY left in your shell conflicts with ANTHROPIC_AUTH_TOKEN, so clear it before the first run:
unset ANTHROPIC_API_KEY
We validated the file with python3 -m json.tool, then ran a one-shot prompt against Moonshot with the invalid key:

The error is correct, but it took 190 seconds to appear. Claude Code treats a 401 as retryable, and an earlier run of the same prompt with --debug (the same settings without the [1m] suffix) shows the pattern in its log:
grep 'API error (attempt' ~/.claude/debug/latest | cut -c12-58
Eleven attempts, each answered by Moonshot with the same 401, with the gap growing from about one second to almost 40:
08:47:59.665Z [ERROR] API error (attempt 1/11):
08:48:00.737Z [ERROR] API error (attempt 2/11):
08:48:02.290Z [ERROR] API error (attempt 3/11):
08:48:04.857Z [ERROR] API error (attempt 4/11):
08:48:10.157Z [ERROR] API error (attempt 5/11):
08:48:19.808Z [ERROR] API error (attempt 6/11):
08:48:37.579Z [ERROR] API error (attempt 7/11):
08:49:13.653Z [ERROR] API error (attempt 8/11):
08:49:48.115Z [ERROR] API error (attempt 9/11):
08:50:25.109Z [ERROR] API error (attempt 10/11)
08:51:04.693Z [ERROR] API error (attempt 11/11)
That debug run gave up after 185 seconds, and the same log confirms each request went to /anthropic/v1/messages with model=kimi-k3.1-pro. Those three minutes are what the curl check saves you. If you test through the agent anyway, Claude Code’s CLAUDE_CODE_MAX_RETRIES variable (default 10) cuts the wait; our capture runs set it to 0 and failed on the first attempt. The [claude-code:unrecognized_model] line is not a typo detector either. Claude Code printed it for the correct ID, since it flags model names it does not recognize, so expect it on every Moonshot model unless you map the ID in Claude Code’s modelOverrides setting, and don’t read it as a verdict on your spelling.
With a working key, claude starts the usual interactive session and every request goes to K3.1 Pro; the commands and flags in our Claude Code cheat sheet work the same against Moonshot’s endpoint. Moonshot’s Kimi Code docs recommend its native APIs for K3.1 Pro and warn that protocol translation through proxy tools can change model behavior, so point Claude Code straight at the Anthropic-compatible URL rather than through a local proxy. If you’d rather keep one key for several providers, the OpenCode setup with an OpenAI-compatible key is the other route.
What happens when the model ID is wrong on each path
Putting the lab runs next to Moonshot’s documented behavior shows where a typo is caught and where it slips through. Every row except the last was run on our VM:
| Path | What we sent | What came back | Time |
|---|---|---|---|
| curl, Platform API | Invalid key, model kimi-k3.1pro | 401 invalid_authentication_error | 0.53 s |
| Kimi Code CLI | -m kimi-k3.1pro | Model “kimi-k3.1pro” is not configured in config.toml | 2.3 s, no network call |
| Kimi Code CLI | Invalid key, correct model | provider.auth_error: 401 Invalid Authentication | 3.7 s |
| Claude Code | Invalid key, correct model | Failed to authenticate. API Error: 401 (11 attempts in the debug log) | 182 to 190 s across our runs |
| Kimi Code subscription endpoint | Mistyped model ID | Served by K2.8 Preview without thinking (Moonshot docs, not tested) | No error |
A safe pattern follows from that table. Kimi Code CLI is the strictest, because a model has to exist in your own config before the CLI will send anything. Raw API calls and Claude Code pass the ID through untouched, and on the Platform API the key check happens first, so test the key alone and then the model. On the subscription endpoint nothing protects you, so copy the ID from Moonshot’s model table rather than typing it, and if K3.1 Pro starts answering quickly with no reasoning, suspect the fallback before you suspect the model.
Common misconceptions about Kimi K3.1 Pro
Most of the confusion around the launch comes from early coverage and from K3-era configs copied forward:
- “You can download it today”: not yet. Moonshot promises the weights by November 4, 2026, and until then only the API and Kimi’s own apps serve it. If you want to self-host now, our guide to running Kimi K3 locally covers the hardware for the 2.8T base, which K3.1 Pro shares.
- “Highspeed is a smaller model”: Moonshot says it has the same capabilities, returns output about 2 to 3 times faster and costs twice as much per token, except for cached input.
- “Cheaper tokens means cheaper tasks”: only if the token count holds. Artificial Analysis rates K3.1 Pro very verbose, and in our DeepSeek V4 versus Kimi K3 test reasoning effort moved K3’s cost per task more than the rate card did.
- “You can turn thinking off to save money”: K3.1 Pro always thinks, and the subscription endpoint rejects thinking-off requests. Use
loweffort instead.
Artificial Analysis gives the first hint of whether the price cut reaches your invoice: its index run cost $2.11 per task on K3.1 Pro against $2.00 on K3, with 150M and 160M output tokens. The K3 page is marked deprecated with historical results, so treat that as a rough comparison, but it says the same thing as our K3 tests: token volume decides the bill. Until you have numbers from your own workload, set the effort explicitly on the Platform API and watch the usage block in the responses for the first few days.