kimik3.io/Errors/Empty response
Why Kimi K3 returns an empty response
Your call succeeds with HTTP 200. content is an empty string. Your invoice is not. Here is exactly why, reproduced at six budgets on 2026-07-16.
The short answer: your max_completion_tokens is too low. K3 always reasons before answering, and that reasoning is drawn from the same token budget as your answer. Set the ceiling below what K3 wants to think, and thinking consumes all of it — leaving nothing for content. You get finish_reason: "length", an empty string, and a bill for every reasoning token. Fix: raise max_completion_tokens, or just leave it at its 131,072 default.
Measured against api.moonshot.ai with model kimi-k3 on 2026-07-16 — how we measured.
The six runs
We asked K3 one short question — "Explain why the sky is blue" — at six budgets, changing nothing else:
Reasoning fills whatever budget you give it
Output tokens per run · answer appears only at 2,048 · measured 2026-07-16
api.moonshot.ai. Below 2,048 the entire budget is consumed by reasoning — you pay for every token of it and receive an empty string. Full numbers in the table below.| max_completion_tokens | finish_reason | Reasoning tokens | Content returned | Billed as output |
|---|---|---|---|---|
| 64 | length | 61 | nothing | 61 |
| 128 | length | 125 | nothing | 125 |
| 256 | length | 253 | nothing | 253 |
| 512 | length | 509 | nothing | 509 |
| 1024 | length | 1021 | nothing | 1021 |
| 2048 | stop | 1308 | 1,954 characters | 2048 |
Read the pattern. At every budget below 2048, reasoning consumed within three tokens of the entire ceiling and the answer never started. The last row shows why: this one short question spent 1,308 tokens thinking before writing a word. Any ceiling under that is a receipt for nothing.
Note also that the failure is silent. No error, no warning — HTTP 200 with a well-formed response body whose content happens to be "". If your code does response.choices[0].message.content.strip() and moves on, you will ship this.
Why it happens
On most APIs, a token limit caps the answer. On K3 it caps thinking plus answer, and thinking goes first.
K3 has no reasoning off-switch — it is not a mode you enable, it is how the model works. Every response carries a reasoning_content field, and every one of those tokens bills at the $15.00 per 1M output rate, exactly like the answer. So the budget you set is spent on deliberation before a single character of your answer exists.
That makes the trap specific to porting. Code that works fine against another API — where max_tokens: 512 means "give me a short answer" — means something entirely different here: "think for at most 512 tokens, then stop, whether or not you have said anything."
The fix
Leave max_completion_tokens at its default of 131,072 unless you have a concrete reason not to. K3 stops when it is done; the ceiling is a safety limit, not a length control.
If you genuinely need to cap spend, budget for reasoning plus answer — and assert on the failure signature rather than trusting the response:
choice = response.choices[0]
if choice.finish_reason == "length" and not choice.message.content:
raise RuntimeError(
f"Reasoning consumed the whole budget "
f"({response.usage.completion_tokens_details.reasoning_tokens} reasoning tokens). "
f"Raise max_completion_tokens."
)
If what you actually want is a short answer, ask for one in the prompt. Do not use the token ceiling to get it — on K3 that controls how long the model may think, not how long it may talk.
How much headroom?
We measured reasoning at 43–77% of total output tokens across three prompts, and 1,308 tokens on the single short question above. We have not characterised the upper tail, and we are not going to invent a rule from three data points. The honest guidance: the default exists for a reason, and any cap you set should be several times what you think the answer needs. See the reasoning-cost breakdown for what that means for your bill.
The streaming version of the same bug
It also bites while streaming, and it looks worse — the stream simply ends without ever emitting a content delta. In five streaming runs on a trivial prompt with a 128-token ceiling, three produced no content token at all. The reasoning deltas arrive, the stream closes, and a naive consumer that only watches delta.content sees an empty result with no explanation.
If you are streaming, watch finish_reason on the final chunk, and pass stream_options: {"include_usage": true} so you can see the reasoning tokens you were charged for. Details in the API guide.
Related failure modes
Two more ways K3 fails without erroring, both measured: reasoning_effort: "low" is silently accepted with HTTP 200 despite only max being supported, and max_completion_tokens: 2000000 — double the context window — also returns 200. The full set of real error bodies is in the error reference.
Try it yourself
Every number on this page is reproducible in about a minute. EvoLink carries kimi-k3 on an OpenAI-compatible endpoint — 10 free credits, sign up from anywhere — no Chinese phone number.