> 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 full documentation content in one file, see https://docs.sarvam.ai/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sarvam.ai/_mcp/server.

# Chat Completions Overview

> Get started with Sarvam AI LLM models for conversational AI. Build intelligent chat applications with native Indian language support and deep contextual reasoning capabilities.

Sarvam AI provides powerful chat completion APIs designed to build intelligent conversational AI experiences, with native support for Indian languages and deep contextual reasoning.

<p>
  Our Chat Completion APIs support the following chat models:
</p>

30B parameter model with strong reasoning and Indic language support. Balanced performance-to-cost ratio for production workloads.

105B parameter flagship model. Highest quality outputs for complex reasoning, coding, and generation tasks.

### Choosing a Model

|                    | `sarvam-30b`                                                                          | `sarvam-105b`                                                                       |
| ------------------ | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Context length** | 64K tokens                                                                            | 128K tokens                                                                         |
| **Latency**        | Lower — faster time-to-first-token, well suited for voice agents and interactive chat | Higher — prioritizes output quality over speed                                      |
| **Cost**           | Lower per token                                                                       | Higher per token                                                                    |
| **Quality**        | Strong reasoning and Indic language support for everyday tasks                        | Highest quality for complex reasoning, coding, and long-form generation             |
| **Best for**       | Standard conversations, Q\&A, voice-agent pipelines, high-throughput workloads        | Complex multi-step reasoning, code generation, document analysis over long contexts |

Simply pass the model name as the `model` parameter (e.g., `model="sarvam-105b"`).

**Token budgeting:** the context length covers *everything* — your messages, any `reasoning_content` the model produces in think mode, and the generated reply (capped by `max_tokens`, default 2048). Reasoning tokens are billed as completion tokens, so high `reasoning_effort` increases both latency and cost. For long conversations, trim or summarize older turns instead of resending the full history.

**Authentication:** like every Sarvam API, this endpoint uses the `api-subscription-key` header. It additionally accepts `Authorization: Bearer <key>` for OpenAI-compatible tooling — see [Authentication](/api-reference/authentication) for details.

**Sarvam-M (24B)** has been deprecated and is no longer available through the Chat Completions API. Please migrate to **Sarvam-30B** or **Sarvam-105B** for improved performance.

## Features

<ul>
  <li>
    Supports both "think" and "non-think" modes
  </li>

  <li>
    Think mode for complex logical reasoning
  </li>

  <li>
    Non-think mode for efficient conversations
  </li>

  <li>
    Ideal for mathematical and coding tasks
  </li>
</ul>

{" "}

<ul>
  <li>
    Post-trained on Indian languages
  </li>

  <li>
    Native English proficiency
  </li>

  <li>
    Authentic Indian cultural values
  </li>

  <li>
    Rich understanding of local context
  </li>
</ul>

{" "}

<ul>
  <li>
    Outperforms similar-sized models
  </li>

  <li>
    Strong performance on coding tasks
  </li>

  <li>
    Excellent mathematical reasoning
  </li>

  <li>
    Advanced problem-solving abilities
  </li>
</ul>

<ul>
  <li>
    Full Indic script support
  </li>

  <li>
    Romanized language support
  </li>

  <li>
    Multilingual conversation handling
  </li>

  <li>
    Natural language understanding
  </li>
</ul>

## Code Examples

```python
from sarvamai import SarvamAI

client = SarvamAI(
    api_subscription_key="YOUR_SARVAM_API_KEY",
)
response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {"role": "user", "content": "Hey, what is the capital of India?"}
    ],
)
print(response)
```

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

// Initialize the SarvamAI client with your API key
const client = new SarvamAIClient({
  apiSubscriptionKey: "YOUR_SARVAM_API_KEY",
});

async function main() {
  const response = await client.chat.completions({
    model: "sarvam-105b",
    messages: [
      {
        role: "user",
        content: "What is the capital of India?",
      },
    ],
  });

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

main();
```

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "What is the capital of India?"}
    ],
    "model": "sarvam-105b"
  }'
```

```python
from sarvamai import SarvamAI

client = SarvamAI(
    api_subscription_key="YOUR_SARVAM_API_KEY",
)

response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me about Indian classical music."},
        {"role": "assistant", "content": "Indian classical music is one of the oldest musical traditions in the world..."},
        {"role": "user", "content": "What are the two main styles?"}
    ],
    temperature=0.7,
    reasoning_effort="high"
)
print(response.choices[0].message.content)
```

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

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

async function main() {
    const response = await client.chat.completions({
        model: "sarvam-105b",
        messages: [
            { role: "system", content: "You are a helpful assistant." },
            { role: "user", content: "Tell me about Indian classical music." },
            { role: "assistant", content: "Indian classical music is one of the oldest musical traditions in the world..." },
            { role: "user", content: "What are the two main styles?" }
        ],
        temperature: 0.7,
        reasoning_effort: "high"
    });
    console.log(response.choices[0].message.content);
}

main();
```

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Tell me about Indian classical music."},
      {"role": "assistant", "content": "Indian classical music is one of the oldest musical traditions in the world..."},
      {"role": "user", "content": "What are the two main styles?"}
    ],
    "model": "sarvam-105b",
    "temperature": 0.7,
    "reasoning_effort": "high"
  }'
```

```python
from sarvamai import SarvamAI

client = SarvamAI(
    api_subscription_key="YOUR_SARVAM_API_KEY",
)

response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {"role": "system", "content": "आप एक सहायक हैं जो हिंदी में जवाब देता है।"},
        {"role": "user", "content": "भारत की राजधानी क्या है?"}
    ],
    temperature=0.3
)
print(response.choices[0].message.content)
```

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

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

async function main() {
    const response = await client.chat.completions({
        model: "sarvam-105b",
        messages: [
            { role: "system", content: "आप एक सहायक हैं जो हिंदी में जवाब देता है।" },
            { role: "user", content: "भारत की राजधानी क्या है?" }
        ],
        temperature: 0.3
    });
    console.log(response.choices[0].message.content);
}

main();
```

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "system", "content": "आप एक सहायक हैं जो हिंदी में जवाब देता है।"},
      {"role": "user", "content": "भारत की राजधानी क्या है?"}
    ],
    "model": "sarvam-105b",
    "temperature": 0.3
  }'
```

<ul>
  <li>
    Reasoning effort options: low, medium, high

    <ul>
      <li>
        Thinking mode is 

        <strong>on by default</strong>

         (

        <code>low</code>

        ); pass 

        <code>reasoning_effort=None</code>

         (Python) / 

        <code>reasoning_effort: null</code>

         (JS, cURL) to disable it
      </li>

      <li>
        Higher values increase reasoning depth
      </li>

      <li>
        Reasoning tokens (returned as 

        <code>reasoning_content</code>

        ) count toward your completion tokens and bill — use lower effort or disable reasoning for latency- and cost-sensitive paths
      </li>
    </ul>
  </li>

  <li>
    Output length is capped by <code>max\_tokens</code> (default 2048) — raise it for long-form generation
  </li>
</ul>

Because thinking mode is on by default, a low `max_tokens` (e.g. under a few hundred) can be consumed entirely by reasoning — you'll get `finish_reason: "length"` with an empty `content` and only `reasoning_content` populated. Either keep `max_tokens` generous or disable reasoning with `reasoning_effort=None` for short replies.

## Streaming

Set `stream: true` to receive the response incrementally over [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) instead of waiting for the full completion. This is essential for responsive chat UIs and voice-agent pipelines, where you want to start rendering (or speaking) the reply as soon as the first tokens arrive.

Both SDKs return an iterator of `chat.completion.chunk` objects. Each chunk carries a `delta` with the new portion of the message — `delta.content` for the reply text and, when reasoning is enabled, `delta.reasoning_content` for thinking tokens.

```python
from sarvamai import SarvamAI

client = SarvamAI(
    api_subscription_key="YOUR_SARVAM_API_KEY",
)

stream = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {"role": "user", "content": "Write a short poem about the monsoon."}
    ],
    stream=True,
)

for chunk in stream:
    # The final chunk reports usage and has no choices — guard before indexing
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

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

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

async function main() {
  const stream = await client.chat.completions({
    model: "sarvam-105b",
    messages: [
      { role: "user", content: "Write a short poem about the monsoon." },
    ],
    stream: true,
  });

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta;
    if (delta?.content) {
      process.stdout.write(delta.content);
    }
  }
}

main();
```

```bash
curl -N -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "Write a short poem about the monsoon."}
    ],
    "model": "sarvam-105b",
    "stream": true
  }'
```

Over raw HTTP, each event is a `data:` line containing a `chat.completion.chunk` JSON object. The final data chunk carries `usage` (with an empty `choices` array), and the stream ends with `data: [DONE]`:

```text
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1699000000,"model":"sarvam-105b","choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1699000000,"model":"sarvam-105b","choices":[{"index":0,"delta":{"content":" rains"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1699000000,"model":"sarvam-105b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1699000000,"model":"sarvam-105b","choices":[],"usage":{"prompt_tokens":19,"completion_tokens":3,"total_tokens":22}}

data: [DONE]
```

When `reasoning_effort` is set, thinking tokens stream first via `delta.reasoning_content`, followed by the reply via `delta.content`. Check both fields if you display reasoning to users.

## Tool Calling (Function Calling)

Describe functions your application exposes with the `tools` parameter, and the model will decide when to call them — returning the function name and JSON arguments instead of (or alongside) a text reply. You execute the function yourself, append the result as a `tool` message, and call the API again so the model can produce its final answer.

The flow is:

1. Send the conversation plus `tools` definitions.
2. If the model wants a tool, the response has `finish_reason: "tool_calls"` and `message.tool_calls` with the function name and stringified JSON `arguments`.
3. Run the function, append the assistant message and a `{"role": "tool", "tool_call_id": ..., "content": ...}` message with the result.
4. Call the API again — the model answers using the tool output.

```python
import json
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for an Indian city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name, e.g. Mumbai"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["city"],
            },
        },
    }
]

messages = [{"role": "user", "content": "What's the weather in Mumbai right now?"}]

response = client.chat.completions(
    model="sarvam-105b",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

message = response.choices[0].message

if message.tool_calls:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)

    # Run your actual function here
    weather = {"city": args["city"], "temperature": 31, "condition": "Humid"}

    messages.append(
        {
            "role": "assistant",
            "tool_calls": [
                {
                    "id": tool_call.id,
                    "type": "function",
                    "function": {
                        "name": tool_call.function.name,
                        "arguments": tool_call.function.arguments,
                    },
                }
            ],
        }
    )
    messages.append(
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(weather),
        }
    )

    final = client.chat.completions(
        model="sarvam-105b",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)
```

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

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

const tools = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "Get the current weather for an Indian city",
      parameters: {
        type: "object",
        properties: {
          city: { type: "string", description: "City name, e.g. Mumbai" },
          unit: { type: "string", enum: ["celsius", "fahrenheit"] },
        },
        required: ["city"],
      },
    },
  },
];

async function main() {
  const messages = [
    { role: "user", content: "What's the weather in Mumbai right now?" },
  ];

  const response = await client.chat.completions({
    model: "sarvam-105b",
    messages,
    tools,
    tool_choice: "auto",
  });

  const message = response.choices[0].message;

  if (message.tool_calls?.length) {
    const toolCall = message.tool_calls[0];
    const args = JSON.parse(toolCall.function.arguments);

    // Run your actual function here
    const weather = { city: args.city, temperature: 31, condition: "Humid" };

    messages.push({ role: "assistant", tool_calls: [toolCall] });
    messages.push({
      role: "tool",
      tool_call_id: toolCall.id,
      content: JSON.stringify(weather),
    });

    const final = await client.chat.completions({
      model: "sarvam-105b",
      messages,
      tools,
    });
    console.log(final.choices[0].message.content);
  }
}

main();
```

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sarvam-105b",
    "messages": [
      {"role": "user", "content": "What'\''s the weather in Mumbai right now?"}
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather for an Indian city",
          "parameters": {
            "type": "object",
            "properties": {
              "city": {"type": "string", "description": "City name, e.g. Mumbai"},
              "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["city"]
          }
        }
      }
    ],
    "tool_choice": "auto"
  }'
```

A tool-call response looks like:

```json
{
  "choices": [
    {
      "index": 0,
      "finish_reason": "tool_calls",
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Mumbai\", \"unit\": \"celsius\"}"
            }
          }
        ]
      }
    }
  ]
}
```

### Controlling tool use with `tool_choice`

| Value                                                       | Behavior                                                   |
| ----------------------------------------------------------- | ---------------------------------------------------------- |
| `"auto"` (default when tools are provided)                  | The model decides whether to call a tool or reply directly |
| `"none"`                                                    | The model never calls a tool — tools are ignored           |
| `"required"`                                                | The model must call at least one tool                      |
| `{"type": "function", "function": {"name": "get_weather"}}` | Forces the model to call the named function                |

`function.arguments` is a **JSON string**, not an object — always parse it (and validate against your schema) before executing the function.

## Structured Outputs (JSON)

The Chat Completions API supports the OpenAI-compatible `response_format` parameter for getting reliably structured JSON:

| `response_format`                               | Behavior                                                                                         |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `{"type": "json_schema", "json_schema": {...}}` | **Structured Outputs** — output is constrained to match the JSON Schema you supply (recommended) |
| `{"type": "json_object"}`                       | **JSON mode** — output is guaranteed to be valid JSON, but not a specific schema                 |
| `{"type": "text"}` (default)                    | Plain text output                                                                                |

### Structured Outputs with `json_schema`

Pass a JSON Schema under `json_schema.schema`, and set `"strict": true` to enforce adherence. The structured reply arrives as a JSON **string** in `message.content` — parse it before use.

```python
import json
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {
            "role": "user",
            "content": "Order: 2 masala dosas and 1 filter coffee to Koramangala, Bengaluru.",
        }
    ],
    request_options={
        "additional_body_parameters": {
            "response_format": {
                "type": "json_schema",
                "json_schema": {
                    "name": "food_order",
                    "strict": True,
                    "schema": {
                        "type": "object",
                        "properties": {
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "name": {"type": "string"},
                                        "quantity": {"type": "integer"},
                                    },
                                    "required": ["name", "quantity"],
                                    "additionalProperties": False,
                                },
                            },
                            "city": {"type": "string"},
                        },
                        "required": ["items", "city"],
                        "additionalProperties": False,
                    },
                },
            }
        }
    },
)

order = json.loads(response.choices[0].message.content)
print(order)
# {'items': [{'name': 'masala dosa', 'quantity': 2}, {'name': 'filter coffee', 'quantity': 1}], 'city': 'Bengaluru'}
```

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

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

async function main() {
  const response = await client.chat.completions({
    model: "sarvam-105b",
    messages: [
      {
        role: "user",
        content: "Order: 2 masala dosas and 1 filter coffee to Koramangala, Bengaluru.",
      },
    ],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "food_order",
        strict: true,
        schema: {
          type: "object",
          properties: {
            items: {
              type: "array",
              items: {
                type: "object",
                properties: {
                  name: { type: "string" },
                  quantity: { type: "integer" },
                },
                required: ["name", "quantity"],
                additionalProperties: false,
              },
            },
            city: { type: "string" },
          },
          required: ["items", "city"],
          additionalProperties: false,
        },
      },
    },
  });

  const order = JSON.parse(response.choices[0].message.content);
  console.log(order);
}

main();
```

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sarvam-105b",
    "messages": [
      {"role": "user", "content": "Order: 2 masala dosas and 1 filter coffee to Koramangala, Bengaluru."}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "food_order",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {"type": "string"},
                  "quantity": {"type": "integer"}
                },
                "required": ["name", "quantity"],
                "additionalProperties": false
              }
            },
            "city": {"type": "string"}
          },
          "required": ["items", "city"],
          "additionalProperties": false
        }
      }
    }
  }'
```

In the current Python SDK, pass `response_format` through `request_options={"additional_body_parameters": {...}}` as shown above. The JavaScript SDK forwards `response_format` from the request object as-is.

The `json_schema` object accepts:

| Field         | Type              | Description                                                                         |
| ------------- | ----------------- | ----------------------------------------------------------------------------------- |
| `name`        | string (required) | Name of the response format. Alphanumeric characters, underscores and dashes only   |
| `schema`      | object            | The output structure, described as a [JSON Schema](https://json-schema.org/) object |
| `strict`      | boolean           | Enable strict schema adherence when generating the output (default `false`)         |
| `description` | string            | What the format is for — helps the model decide how to respond                      |

### JSON mode with `json_object`

When you only need valid JSON without enforcing a specific structure, use `{"type": "json_object"}` and describe the desired shape in your prompt:

```bash
curl -X POST https://api.sarvam.ai/v1/chat/completions \
  -H "api-subscription-key: $SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sarvam-105b",
    "messages": [
      {"role": "system", "content": "Reply with a JSON object: {\"sentiment\": \"positive\" | \"negative\" | \"neutral\", \"confidence\": number}"},
      {"role": "user", "content": "यह फिल्म शानदार थी!"}
    ],
    "response_format": {"type": "json_object"}
  }'
```

Even with Structured Outputs, validate the parsed JSON against your expected schema (e.g. with `pydantic` or `zod`) before acting on it — the schema constrains the model's output shape, but your application logic may have stricter requirements (value ranges, business rules, etc.).

### Alternative: Tool calling as a JSON schema

If your workflow is already built around [tool calling](#tool-calling-function-calling), you can also get structured output by defining a single tool whose `parameters` schema describes the structure you want, and forcing it with `tool_choice`. The model's `arguments` are then constrained to the schema.

```python
import json
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {
            "role": "user",
            "content": "Order: 2 masala dosas and 1 filter coffee to Koramangala, Bengaluru.",
        }
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "extract_order",
                "description": "Extract a structured food order",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "items": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "name": {"type": "string"},
                                    "quantity": {"type": "integer"},
                                },
                                "required": ["name", "quantity"],
                            },
                        },
                        "delivery_area": {"type": "string"},
                        "city": {"type": "string"},
                    },
                    "required": ["items", "city"],
                },
            },
        }
    ],
    tool_choice={"type": "function", "function": {"name": "extract_order"}},
)

arguments = response.choices[0].message.tool_calls[0].function.arguments
order = json.loads(arguments)
print(order)
# {'items': [{'name': 'masala dosa', 'quantity': 2}, {'name': 'filter coffee', 'quantity': 1}], 'delivery_area': 'Koramangala', 'city': 'Bengaluru'}
```

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

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

async function main() {
  const response = await client.chat.completions({
    model: "sarvam-105b",
    messages: [
      {
        role: "user",
        content: "Order: 2 masala dosas and 1 filter coffee to Koramangala, Bengaluru.",
      },
    ],
    tools: [
      {
        type: "function",
        function: {
          name: "extract_order",
          description: "Extract a structured food order",
          parameters: {
            type: "object",
            properties: {
              items: {
                type: "array",
                items: {
                  type: "object",
                  properties: {
                    name: { type: "string" },
                    quantity: { type: "integer" },
                  },
                  required: ["name", "quantity"],
                },
              },
              delivery_area: { type: "string" },
              city: { type: "string" },
            },
            required: ["items", "city"],
          },
        },
      },
    ],
    tool_choice: { type: "function", function: { name: "extract_order" } },
  });

  const order = JSON.parse(
    response.choices[0].message.tool_calls[0].function.arguments
  );
  console.log(order);
}

main();
```

### Alternative: Prompt-based JSON

For simple cases, you can also instruct the model to reply with JSON only, set a low `temperature`, and validate the output before using it (consider [JSON mode](#json-mode-with-json_object) instead, which guarantees valid JSON):

```python
import json
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

response = client.chat.completions(
    model="sarvam-105b",
    messages=[
        {
            "role": "system",
            "content": (
                "Reply with a single JSON object only — no prose, no markdown fences. "
                'Schema: {"sentiment": "positive" | "negative" | "neutral", "confidence": number}'
            ),
        },
        {"role": "user", "content": "यह फिल्म शानदार थी!"},
    ],
    temperature=0.1,
)

raw = response.choices[0].message.content
try:
    result = json.loads(raw)
except json.JSONDecodeError:
    # Retry, or strip markdown fences / extra text before parsing
    raise
print(result)
```

Always validate model-produced JSON against your expected schema (e.g. with `pydantic` or `zod`) and add a retry path — prompt-based JSON is good, but not guaranteed.

## API Response Format

### Success Response Structure

```json
{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1699000000,
  "model": "sarvam-105b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The capital of India is New Delhi. It has been the capital since 1931."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 25,
    "total_tokens": 40
  }
}
```

### Response Fields

| Field                                 | Type    | Description                                                                                              |
| ------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
| `id`                                  | string  | Unique identifier for the completion request                                                             |
| `object`                              | string  | Always `"chat.completion"`                                                                               |
| `created`                             | integer | Unix timestamp when the completion was created                                                           |
| `model`                               | string  | The model used for completion                                                                            |
| `choices[].index`                     | integer | Index of the choice in the list                                                                          |
| `choices[].message.role`              | string  | Always `"assistant"`                                                                                     |
| `choices[].message.content`           | string  | The generated text response (`null` when the model calls a tool)                                         |
| `choices[].message.reasoning_content` | string  | Thinking steps (only when `reasoning_effort` is set)                                                     |
| `choices[].message.tool_calls`        | array   | Tool invocations requested by the model (only when using [tool calling](#tool-calling-function-calling)) |
| `choices[].finish_reason`             | string  | Why generation stopped: `"stop"`, `"length"`, `"tool_calls"`, `"content_filter"`                         |
| `usage.prompt_tokens`                 | integer | Tokens in the input prompt                                                                               |
| `usage.completion_tokens`             | integer | Tokens in the generated response                                                                         |
| `usage.total_tokens`                  | integer | Total tokens used (prompt + completion)                                                                  |

## Error Responses

All errors return a JSON object with an `error` field (`message`, `code`, `request_id`). The full error-code table, retry guidance, and SDK exception reference live on the central [Errors & Troubleshooting](/api/errors-troubleshooting) page.

Errors specific to this endpoint:

| HTTP Status | Error Code                   | When This Happens                                 | What To Do                                                          |
| ----------- | ---------------------------- | ------------------------------------------------- | ------------------------------------------------------------------- |
| `400`       | `invalid_request_error`      | Missing `messages` array or missing `model` field | Include both `model` and a valid `messages` array with role/content |
| `422`       | `unprocessable_entity_error` | Invalid model name or parameter values            | Check temperature (0-2), model name, etc.                           |

```python
from sarvamai import SarvamAI
from sarvamai.core.api_error import ApiError

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

try:
    response = client.chat.completions(
        model="sarvam-105b",
        messages=[
            {"role": "user", "content": "What is the capital of India?"}
        ],
    )
    print(response.choices[0].message.content)
except ApiError as e:
    if e.status_code == 400:
        print(f"Bad request: {e.body}")
    elif e.status_code == 403:
        print("Invalid API key. Check your credentials.")
    elif e.status_code == 422:
        print(f"Invalid parameters: {e.body}")
    elif e.status_code == 429:
        print("Rate limit exceeded. Wait and retry.")
    else:
        print(f"Error {e.status_code}: {e.body}")
```

## Limits

| Limit                                    | Value                                                                                                                                                                            |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Context window                           | 64K tokens (`sarvam-30b`) / 128K tokens (`sarvam-105b`)                                                                                                                          |
| `max_tokens`                             | **sarvam-30b**: Starter 4096 / Pro 8192 / Business 64000<br />**sarvam-105b**: Starter 4096 / Pro 16384 / Business 128000<br />(reasoning tokens count toward completion tokens) |
| `temperature`                            | 0–2 (default 0.5 when reasoning is enabled — the default — and 0.2 when reasoning is disabled)                                                                                   |
| `top_p`                                  | 0–1                                                                                                                                                                              |
| `n` (completions per request)            | 1–128                                                                                                                                                                            |
| `frequency_penalty` / `presence_penalty` | -2 to 2                                                                                                                                                                          |
| `stop`                                   | Up to 4 sequences                                                                                                                                                                |
| Rate limits                              | See [Rate Limits](/api/ratelimits)                                                                                                                                               |

Check out our detailed [API Reference](/api/chat/chat-completions)
to explore Chat Completion and all available options.