> This page is for Model APIs.

> Sarvam Voice Agents (Samvaad) is a voice AI agent platform for Indian languages: build, test and deploy AI calling agents on your own phone numbers, from ₹3 a minute. Start here: https://docs.sarvam.ai/voice-agents/why-voice-agents.
> For clean Markdown of any page, append `.md` to the page URL.
> For a complete documentation index, see https://docs.sarvam.ai/llms.txt. For a section index, append `/llms.txt` to any section URL (for example https://docs.sarvam.ai/voice-agents/llms.txt).
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sarvam.ai/_mcp/server.

# Kimi K3

> Kimi K3 is an open-weight reasoning model with text, image, and video input, a 1,048,576-token context window, and tool calling.

Kimi K3 is a general-purpose [open-weight model](/api/token-factory/models)
served on Sarvam infrastructure. It accepts **text, images, and video** and has a
**1,048,576-token context window**.

> **Note**
>
> Kimi K3 is in **beta**. Its behaviour, limits, and availability may change before general availability. Beta models must be enabled for your API key; without access, requests return `400 invalid_request_error` ("This model is currently in beta"). [Contact us](/api/getting-started/help) to request access. See [Beta models](/api-reference/beta-apis).

## At a glance

|                    |                                                                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| **Model ID**       | `kimi-k3`                                                                                                                            |
| **Best for**       | Agentic workflows and reasoning over images and video                                                                                |
| **Context window** | 1,048,576 tokens                                                                                                                     |
| **Input → output** | Text + image + video (beta, short clips only) → text                                                                                 |
| **Reasoning**      | Always on: **`low`**, **`high`**, or **`max`** (default). See [Reasoning](#reasoning)                                                |
| **Tool calling**   | Supported, including parallel tool calls                                                                                             |
| **APIs**           | [`POST /v2/chat/completions`](/api-reference/chat/chat-completions-v2) and [`POST /v2/responses`](/api-reference/responses/create)   |
| **Pricing**        | ₹270 input · ₹27 cached input · ₹1,350 output per 1M tokens; reasoning is billed as output ([Pricing](/api/getting-started/pricing)) |

## Key capabilities

#### Long context

Process up to 1,048,576 tokens across the prompt, reasoning, and generated output.

#### Image and video input

Send base64 images and short base64 video clips alongside text.

#### Reasoning

Receive reasoning in `reasoning_content` separately from the final answer in `content`.

#### Tool calling

Use OpenAI-compatible `tools` and `tool_choice` for agentic workflows.

#### Structured output

Constrain answers with `response_format` JSON schemas.

#### Log probabilities

Request `logprobs` and `top_logprobs`, and `n` > 1 choices.

> **Tip**
>
> Moving from [OpenRouter](/api/token-factory/migrations/from-openrouter/overview), [Fireworks AI](/api/token-factory/migrations/from-fireworks/overview), or [Together AI](/api/token-factory/migrations/from-together/overview)? The migration guides map model IDs and request fields to Sarvam.

## Quickstart

#### Python

```python
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

response = client.chat.completions_v2(
    model="kimi-k3",
    messages=[
        {
            "role": "user",
            "content": "Plan a three-step approach to migrate a monolith to microservices.",
        }
    ],
    max_tokens=4000,
)

print(response.choices[0].message.content)
```

#### JavaScript

```javascript
import { SarvamAIClient } from "sarvamai";

const client = new SarvamAIClient({
    apiSubscriptionKey: "YOUR_SARVAM_API_KEY",
});

async function main() {
    const response = await client.chat.completionsV2({
        model: "kimi-k3",
        messages: [
            {
                role: "user",
                content: "Plan a three-step approach to migrate a monolith to microservices.",
            },
        ],
        max_tokens: 4000,
    });

    console.log(response.choices[0].message.content);
}

main();
```

#### cURL

```bash
curl -X POST https://api.sarvam.ai/v2/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "messages": [
      {
        "role": "user",
        "content": "Plan a three-step approach to migrate a monolith to microservices."
      }
    ],
    "max_tokens": 4000
  }'
```

## Supported parameters

`model: "kimi-k3"` on [Chat Completion V2](/api-reference/chat/chat-completions-v2)
and [Responses](/api-reference/responses/create). Full request/response schemas live on
those API reference pages; this table covers what's actually accepted for this model.

| Parameter                                             |                   Chat Completion V2                  |                                               Responses                                               |
| ----------------------------------------------------- | :---------------------------------------------------: | :---------------------------------------------------------------------------------------------------: |
| Streaming (`stream`)                                  |                                                       |                                                                                                       |
| Image input (base64)                                  |                       `image_url`                     |                                              `input_image`                                            |
| Video input (base64, beta)                            |              `video_url`, short clips only            |                                                  `400`                                                |
| Audio input                                           |                          `400`                        |                                                  `400`                                                |
| Tool calling (`tools`, `tool_choice`)                 |                                                       |                                                                                                       |
| `parallel_tool_calls: false` enforced                 |                                                       |                                                                                                       |
| Structured output (`response_format` / `text.format`) |                                                       |                                                                                                       |
| Log probabilities (`logprobs`, `top_logprobs`)        |                                                       |  send `top_logprobs` with `include: ["message.output_text.logprobs"]`; `logprobs: true` returns `400` |
| Multiple choices (`n` > 1)                            |              requires `temperature` > `0`             |                                       N/A — Responses has no `n`                                      |
| Reasoning control                                     | `reasoning_effort`: `low`, `high`, or `max` (default) |                                    `reasoning.effort`: same values                                    |
| Turn reasoning off                                    |                      always thinks                    |                                              always thinks                                            |

> **Warning**
>
> On `POST /v2/responses`, `logprobs` is only populated when the request includes
> `"include": ["message.output_text.logprobs"]`. Without it, `output[].content[].logprobs`
> is always an empty array even if `top_logprobs` is set. Verified against the live API on
> 2026-10-22.

## Reasoning

Thinking is always on and can't be turned off. Effort levels: `low`, `high`, `max` (default
`max`). Set them with `reasoning_effort` on chat or `reasoning.effort` on Responses.

Read the reasoning trace from `choices[].message.reasoning_content` on chat. On Responses,
`output` starts with a `reasoning` item; read its `content[0].text` (`summary` is empty).
Reasoning tokens are billed as output tokens and count against `max_tokens` /
`max_output_tokens`.

On Responses, when the model calls tools, `output` has one `reasoning` item followed by the
`function_call` items for that turn (sometimes with a `message` item between them).

## Image input

Send images **inline as base64 data URIs** in an `image_url` content part on chat, or an
`input_image` part on Responses. Supported formats are PNG, JPEG, WebP, GIF, BMP, and TIFF.
Images sent by `file_id` are not supported.

```python
import base64

with open("chart.png", "rb") as f:
    data_uri = "data:image/png;base64," + base64.b64encode(f.read()).decode()

response = client.chat.completions_v2(
    model="kimi-k3",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Summarise this chart."},
                {"type": "image_url", "image_url": {"url": data_uri}},
            ],
        }
    ],
    max_tokens=2000,
)
```

Images are resized to about 12.8 megapixels. Images above about 179 megapixels are rejected.

## Video input (beta)

Send a video **inline as a base64 data URI** in a `video_url` content part on Chat Completion
V2. Remote video URLs return `400`, and the Responses API doesn't accept video.

> **Warning**
>
> Kimi K3 understands only **very short clips**, about four frames. Longer clips can come back
> as blank or repeated frames, and the answer describes only part of the video. For longer
> videos, use [MiMo V2.6 Flash](/api/token-factory/models/mimo-v2.6-flash) or
> [MiMo V2.6 Pro](/api/token-factory/models/mimo-v2.6-pro).

```python
import base64

with open("clip.mp4", "rb") as f:
    video_uri = "data:video/mp4;base64," + base64.b64encode(f.read()).decode()

response = client.chat.completions_v2(
    model="kimi-k3",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Describe what happens in this clip."},
                {"type": "video_url", "video_url": {"url": video_uri}},
            ],
        }
    ],
    max_tokens=2000,
)
```

Audio input is not supported and returns `400`.

## Tool calling

Pass OpenAI-compatible `tools`. `tool_choice` accepts `"auto"`, `"none"`, `"required"`, or a
named function (`{"type": "function", "function": {"name": "..."}}`). The model
can return several tool calls in one turn; set `parallel_tool_calls: false` to get at most one.

## Multiple choices

`n` > 1 needs `temperature` greater than `0`. Sending `n` > 1 with `temperature: 0` returns `400`.

## Known limitations

* Video input is beta and reliable only for very short clips (see [Video input](#video-input-beta)).
* Reasoning and the final answer share the **`max_tokens`** / **`max_output_tokens`** budget.
* A `stop` string can match inside the thinking, which ends the response early with
  `content: null`. Use stop strings that won't appear in reasoning.
* Set **`max_tokens`** explicitly. When it's omitted, generation isn't capped at a small
  default and long answers can run to tens of thousands of tokens.

## Limits and errors

| Area           | Limit or condition                                   | API response                                               | Recommended action                                                                          |
| -------------- | ---------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| Output         | `max_tokens` exceeds 1,048,576                       | `400 invalid_request_error`                                | Set `max_tokens` within the context window.                                                 |
| Request size   | Request body exceeds 40 MiB (41,943,040 bytes)       | `413 invalid_request_error`, with the limit in the message | Send smaller or fewer media files. Base64 adds about 33%, so about 30 MB of raw media fits. |
| Media URL      | An image, audio, or video part uses an `http(s)` URL | `400 invalid_request_error`                                | Send the file inline as a base64 data URI.                                                  |
| Media count    | More than 999 images or 999 videos in one request    | `400 invalid_request_error`                                | Split the request.                                                                          |
| Image size     | Image above about 179 megapixels                     | `400 invalid_request_error`                                | Downscale the image.                                                                        |
| Modality       | Request includes audio input                         | `400 invalid_request_error`                                | Send text, image, or video input.                                                           |
| Choices        | `n` > 1 with `temperature: 0`                        | `400 invalid_request_error`                                | Set `temperature` above `0`.                                                                |
| Reasoning      | Reasoning consumes the full `max_tokens` budget      | `200` with `finish_reason: "length"`                       | Raise `max_tokens` or lower the reasoning effort.                                           |
| Authentication | API key is missing or invalid                        | `403 invalid_api_key_error`                                | Check the `api-subscription-key` header.                                                    |
| Model          | Model ID is unknown or unavailable                   | `404 not_found_error`                                      | Check the spelling; model IDs are case-sensitive.                                           |
| Quota          | No credits remain                                    | `402 insufficient_quota_error`                             | Add credits in the [dashboard](https://indus.sarvam.ai/billing?ref=docs).                   |
| Rate limit     | Request or concurrency limit is exceeded             | `429 rate_limit_exceeded_error`                            | Back off and retry.                                                                         |
| Availability   | Model remains overloaded after retries               | `503 model_overloaded`                                     | Retry later.                                                                                |