Get API key

Updated

Kimi API Rate Limit: Our Limits and Context Window

The kimi api rate limit on this service has two parts: requests per minute and requests at the same time. A full key allows 300 per minute and 8 at once, with a 100,000-token context window.

Key points

  • Full key: 8 concurrent requests and 300 requests per minute. Trial key: 2 and 60.
  • Context window is 100,000 tokens for prompt plus completion; the request body is capped at 8 MB.
  • A 429 with code rate_limited means too many per minute; concurrency means too many at once.
  • A streamed request keeps its concurrency slot until the stream ends.
Isometric illustration of data cubes queuing at eight gates, representing API concurrency and rate limits

The limits at a glance

If you are checking the kimi api rate limit before you build, here are the numbers for this service. They apply per key.

LimitFull keyTrial key
Requests per minute30060
Concurrent requests82
Context window (prompt plus completion)100,000 tokens100,000 tokens
Maximum request body8 MB8 MB

This is an independent hosted API for one open-weight model, so the limits above belong to this service only. They are not the limits of Moonshot AI or any other vendor. If you plan to compare, read the other vendor's current documentation, since limits change over time.

The trial key comes from the one-click $0.50 trial credit on the API key page. It is meant for testing, so the lower limits are enough for a first script but not for a batch job.

Per minute and at once are separate limits

The two limits protect against different things, and you can hit either one first.

The per-minute limit counts how many requests you start in a rolling minute. At 300 per minute you can average five requests per second. Go over it and the API answers with HTTP 429 and the error code rate_limited.

The concurrency limit counts how many requests are in flight right now. With 8 slots, a ninth request that arrives while eight are still running is rejected with HTTP 429 and the code concurrency. A streamed request holds its slot until the stream ends, not until the first token arrives. If you stream long answers to many users, the slots are what run out, long before the per-minute counter does.

Some arithmetic shows how the two interact. With 8 slots and 300 requests per minute, you would need every request to finish in 1.6 seconds on average to reach the per-minute ceiling (8 x 60 / 300 = 1.6). If your average request lasts 30 seconds, 8 slots give you 8 x 60 / 30 = 16 requests per minute, and concurrency is the limit you will feel. For the trial key, 2 slots and 60 per minute meet at 2 seconds per request (2 x 60 / 60 = 2). These durations are examples, not measurements: time your own calls.

Reading a 429 correctly

There are three situations, and the response tells them apart.

  • rate_limited: too many requests in the last minute. Wait for the window to move and send fewer calls per minute.
  • concurrency: too many running at once. Wait for one of your requests to finish, or lower the number you run in parallel.
  • Temporary overload: the service returns 429 with a Retry-After: 5 header. Wait five seconds and try again. This is not caused by your usage.

Treat Retry-After as the minimum wait when it is present. When it is absent, back off with a growing delay and a little random jitter, so that parallel workers do not all retry at the same instant. The function below does both. It sets max_retries=0 on the client so the SDK's own automatic retries do not hide what is happening.

import random
import time
from openai import OpenAI, RateLimitError

client = OpenAI(
    base_url="https://api.kimiapi.top/v1",
    api_key="YOUR_API_KEY",
    max_retries=0,
)

def ask(messages, attempts=6):
    for n in range(attempts):
        try:
            r = client.chat.completions.create(model="uncensored", messages=messages)
            return r.choices[0].message.content
        except RateLimitError as e:
            header = e.response.headers.get("Retry-After")
            wait = float(header) if header else min(2 ** n, 30)
            print("429:", getattr(e, "code", None), "waiting", wait)
            time.sleep(wait + random.random())
    raise RuntimeError("still rate limited after retries")

print(ask([{"role": "user", "content": "Say ok."}]))

Retrying makes sense for 429 only. A refused or failed request is not charged, so a retry loop does not double your bill, but an endless loop can still burn your time and your quota, which is why the number of attempts is capped.

Stay under the limit instead of bouncing off it

Retries are a safety net. The better design keeps your own concurrency at or below the key's limit, so 429 on concurrency becomes rare. In Python, an asyncio.Semaphore does this in a few lines. Use 8 for a full key and 2 for a trial key.

import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI(base_url="https://api.kimiapi.top/v1", api_key="YOUR_API_KEY")
slots = asyncio.Semaphore(8)  # use 2 on a trial key

async def one(prompt):
    async with slots:
        r = await client.chat.completions.create(
            model="uncensored",
            messages=[{"role": "user", "content": prompt}],
        )
        return r.choices[0].message.content

async def main(prompts):
    return await asyncio.gather(*(one(p) for p in prompts))

answers = asyncio.run(main(["Question one", "Question two", "Question three"]))
print(answers)

The semaphore limits parallelism but not the per-minute count. For a large batch, also spread the calls out. At 300 per minute, a batch of 3,000 requests needs at least 10 minutes (3,000 / 300). Plan for that, and add a small margin so a retry does not push you over.

If you serve many end users from one key, queue requests on your side and give each user a fair share of the 8 slots. A single user who opens many streams can otherwise use every slot and block everyone else.

The 100,000-token context window

The context window is the second kind of limit, and it is about size, not speed. It is 100,000 tokens, and it covers the prompt and the completion together. If your prompt is 90,000 tokens, the answer can use at most the remaining 10,000.

max_tokens is optional. When you leave it out, the completion may use whatever is left of the window. Set it yourself when you want a short reply, or when you want to be sure a runaway answer stays small, since output tokens are billed at $0.50 per 1M.

How much text fits in 100,000 tokens depends on the language and the content. Code and non-English text usually take more tokens per word than plain English prose. Do not guess: send your real input once and read usage.prompt_tokens in the response.

Keeping long chats inside the window

Chat history grows with every turn, so long role-play or companion sessions eventually reach the limit. Three common approaches work:

  1. Drop the oldest messages once the history passes a budget, for example 80,000 tokens, which leaves room for the reply.
  2. Replace old turns with a short summary that you generate with the same model.
  3. Keep a fixed block of facts (character, setting, rules) at the top and cut only the middle of the conversation.

There is also a byte limit: the request body can be 8 MB at most. You will reach the token window long before that with plain text, but base64 data or very large tool payloads can hit the body cap first.

Remember what a full window costs. A call with 98,000 input tokens and 2,000 output tokens is $0.0147 plus $0.001, so $0.0157. That is cheap once, and it adds up if every turn of a long chat sends the whole history. The pricing page has the rest of the numbers.

Watching your limits from the response headers

Every response includes headers that help with monitoring. X-RateLimit-Limit-Requests and X-RateLimit-Limit-Concurrency show the limits that apply to your key, X-Balance-USD shows the credit left, and X-Request-Id identifies the call if you need to ask support about it.

curl -s -D - -o /dev/null https://api.kimiapi.top/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "uncensored", "max_tokens": 5, "messages": [{"role": "user", "content": "Hi"}]}'

Log these values in your application next to each call. When a user reports a failure, the request ID and the balance at that moment answer most questions at once. If the limit headers on your key show 2 and 60, you are on trial limits. For the full request reference, see the API docs.

Questions and answers

What is the rate limit for a full key?

300 requests per minute and 8 concurrent requests. Requests above that return HTTP 429.

What are the trial key limits?

2 concurrent requests and 60 requests per minute, plus the same 100,000-token context window.

Does a streamed request count against concurrency?

Yes. It holds its slot until the stream ends, so long streams use up slots faster than short calls.

What does Retry-After: 5 mean?

The service is temporarily overloaded. Wait five seconds and send the request again.

Is this the Moonshot Kimi rate limit?

No. These limits belong to this independent hosted API, which is not the official API of Moonshot AI or any other vendor.

Your key is one form away

Create an account, copy the key, change the base URL. That is the whole setup.