← All guides AI Release
RU Subscribe to @ai_release1

How to Connect Kimi K3.1 Pro via API: Keys, Pricing and OpenAI-Compatible Setup

Updated: 24.10.2026 · AI Release · @ai_release1
How to Connect Kimi K3.1 Pro via API: Keys, Pricing and OpenAI-Compatible Setup

TL;DR

- Python 3.10+ with the openai SDK 1.x, or curl 7.68+

- An account on the Kimi API platform and an API key created in its console

- Any OpenAI-compatible client (LibreChat, Open WebUI, n8n, curl, the openai SDK)

- The exact model ID and base URL from the provider's model list — this guide uses placeholders (<model-id>, <provider-domain>) because those strings change between releases

Requirements and setup

Illustration: Requirements and setup
Illustration: Requirements and setup

Checklist before you start:

<provider-domain> is the hostname from the provider's API documentation, for example the host shown next to the "OpenAI-compatible endpoint" section. Replace it everywhere it appears.

Step 1. Create an API key and export it as an environment variable

What to do: Sign in to the provider console, open API Keys → Create new secret key, name it kimi-k3-prod, and copy the value. Then export it in your shell instead of pasting it into source files:

export KIMI_API_KEY="<paste-key-here>"
mkdir -p ~/.config/kimi && printf 'KIMI_API_KEY=%s\n' "$KIMI_API_KEY" > ~/.config/kimi/.env
chmod 600 ~/.config/kimi/.env
printf '%s\n' ".env" "*.key" >> .gitignore

On PowerShell: $env:KIMI_API_KEY = "<paste-key-here>".

Why: Every request is authenticated with a bearer token — an HTTP header Authorization: Bearer <key> sent with each call. Keeping the key in an environment variable means it never lands in a commit, and rotating it later touches one file.

How to check: Confirm the variable exists without printing the whole secret, then ask the API which models your key can see:

printf '%s\n' "${KIMI_API_KEY:0:6}…"   # prints e.g. sk-abc…
curl -s -H "Authorization: Bearer $KIMI_API_KEY" \
  https://api.<provider-domain>/v1/models | head -c 400

Expected output is JSON beginning with {"object":"list","data":[{"id":"... — an array of model objects. Copy the id of the K3.1 Pro entry; that exact string is your <model-id> for the rest of this guide.

Step 2. Point an OpenAI-compatible client at the Kimi endpoint

Illustration: Step 2. Point an OpenAI-compatible client at the Kimi endpoint
Illustration: Step 2. Point an OpenAI-compatible client at the Kimi endpoint

What to do: An OpenAI-compatible API means the request and response bodies follow OpenAI's wire format (POST /v1/chat/completions, bearer auth, choices[].message.content). So you keep your client and change only two values:

Client settingValueWhere to find it
`base_url``https://api.<provider-domain>/v1`provider docs, "API endpoint"
`api_key`value of `KIMI_API_KEY`your console
`model``<model-id>`the `/v1/models` reply from Step 1
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["KIMI_API_KEY"],
    base_url="https://api.<provider-domain>/v1",
)

resp = client.chat.completions.create(
    model="<model-id>",              # exact id from /v1/models, e.g. what the console lists
    messages=[
        {"role": "system", "content": "Answer in one sentence."},
        {"role": "user", "content": "What does an OpenAI-compatible endpoint change in my code?"},
    ],
    temperature=0.3,
    max_tokens=200,
)
print(resp.choices[0].message.content)
print(resp.usage)

For GUI clients that take a JSON config rather than code (LibreChat, Open WebUI, n8n's OpenAI node), use the same three fields:

{
  "provider": "openai-compatible",
  "baseURL": "https://api.<provider-domain>/v1",
  "apiKey": "${KIMI_API_KEY}",
  "model": "<model-id>",
  "stream": true
}

Why: Your SDK or tool already speaks that format, so the only difference between calling OpenAI and calling Kimi is the host in base_url and the model string. If you later want to keep a second provider in the same client, put a router in front instead of hardcoding hosts — see How to combine multiple AI providers behind one OpenAI-compatible router. The same swap-the-base-URL pattern applied to a self-hosted server is documented in How to connect a local LLM to Claude Code: llama-server and an OpenAI-compatible API.

How to check: Save the snippet as kimi_test.py and run python3 kimi_test.py. You should see one sentence of plain text, then a usage object of the form CompletionUsage(completion_tokens=42, prompt_tokens=38, total_tokens=80). If the token counts are non-zero, the request reached the model and was billed.

Step 3. Verify the connection end to end

Illustration: Step 3. Verify the connection end to end
Illustration: Step 3. Verify the connection end to end

What to do: Test the raw HTTP layer, then streaming, then the client. Start with curl so you can see the untouched response:

curl -s https://api.<provider-domain>/v1/chat/completions \
  -H "Authorization: Bearer $KIMI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"<model-id>","messages":[{"role":"user","content":"Reply with the word OK"}],"max_tokens":10}'

Why: The HTTP layer tells you which side is broken. A raw curl that returns "object":"chat.completion" proves the key, host, and model ID are all correct, so any later failure is in your client configuration, not in the account.

Then check streaming, which is what interactive UIs use:

curl -N -s https://api.<provider-domain>/v1/chat/completions \
  -H "Authorization: Bearer $KIMI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"<model-id>","messages":[{"role":"user","content":"Count to five"}],"stream":true}'

How to check: Success looks like this, in this order:

Troubleshooting

Problem. Every request fails immediately with 401.

Problem. Authentication succeeds but the completion call returns 404.

Problem. Requests start failing under load with 429.

Summary and next steps

You now have a working key, a verified /v1/chat/completions call, and a client configured with three values: base URL, key, model ID. Next, move the key into your orchestrator's secret store and add a second provider behind a router so a quota error on one does not stop your pipeline.

FAQ

What exactly is an "OpenAI-compatible API"?

It is a service that accepts the same HTTP request format as OpenAI's API — same paths, same JSON fields, same bearer-token header — so existing SDKs and tools work after you change only the base URL and model name.

Do I need a different SDK for Kimi?

No. Use the official openai Python or Node SDK with base_url pointed at the provider's endpoint, or use curl. Only clients that hardcode api.openai.com cannot be reconfigured — most support a custom base URL field.

How much does Kimi K3.1 Pro cost per million tokens?

Rates are set by the provider and change over time, so check the pricing page in the console before you commit. This guide deliberately avoids quoting a number that may already be stale; watch the usage object in every response to measure real spend.

Why do I get a model_not_found error when the model name looks right?

Model IDs are exact strings, and some are gated by account tier or region. Copy the id value straight from the /v1/models response rather than typing it, and if the model is absent from that list, request access in the console.

🤖 AI summary