> 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.

# Migrating the Responses API from Fireworks AI to Sarvam

> Moving from Fireworks' stored Responses API to Sarvam's stateless /v2/responses: conversation history, reasoning, function tools, server-side tools, and fields to change.

*Last updated: October 23, 2026*

This guide covers moving Fireworks AI [Responses API](https://docs.fireworks.ai/guides/response-api)
calls to Sarvam's [`POST /v2/responses`](/api/token-factory/responses-api).
For Chat Completions, see [Migrating Chat Completion](/api/token-factory/migrations/from-fireworks/chat-completion).

> **Tip**
>
> **In short:** Fireworks stores responses and lets you chain calls with
> `previous_response_id`. Sarvam's Responses API is **stateless**: keep the conversation in
> your app and send it in `input` on every call. Change `base_url`, `api_key`, and `model`, and
> replace server-side tools (`web_search`, `mcp`, `python`) with function tools you run yourself.

## Migration checklist

1. Change `base_url` to `https://api.sarvam.ai/v2` and `api_key` to your Sarvam key.
2. Replace each model ID using the [model ID table](/api/token-factory/migrations/from-fireworks/overview#model-ids).
3. Replace `previous_response_id` chaining with a history list sent in `input` ([Conversation history](#conversation-history)).
4. Remove `store`, `background`, and calls to retrieve stored responses ([list](#fields-to-remove)).
5. Replace server-side tools with function tools ([Tools](#tools)).
6. On `glm5.3` and `glm5.3-flash`, don't send `"max"`; omitting `reasoning.effort` gives `max` on `glm5.3` and `high` on `glm5.3-flash` ([Reasoning](#reasoning)).
7. Set `max_output_tokens`: it has no default cap on Sarvam.

## Quick start

#### Before (Fireworks)

#### Python (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_FIREWORKS_API_KEY",
    base_url="https://api.fireworks.ai/inference/v1",
)

response = client.responses.create(
    model="accounts/fireworks/models/kimi-k3",
    instructions="You are a helpful assistant.",
    input="Explain database indexing in three short points.",
    reasoning={"effort": "low"},
    max_output_tokens=3000,
)

print(response.output_text)
```

#### JavaScript (OpenAI SDK)

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "YOUR_FIREWORKS_API_KEY",
  baseURL: "https://api.fireworks.ai/inference/v1",
});

const response = await client.responses.create({
  model: "accounts/fireworks/models/kimi-k3",
  instructions: "You are a helpful assistant.",
  input: "Explain database indexing in three short points.",
  reasoning: { effort: "low" },
  max_output_tokens: 3000,
});

console.log(response.output_text);
```

#### cURL

```bash
curl https://api.fireworks.ai/inference/v1/responses \
  -H "Authorization: Bearer YOUR_FIREWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "accounts/fireworks/models/kimi-k3",
    "input": "Explain database indexing in three short points.",
    "reasoning": {"effort": "low"},
    "max_output_tokens": 3000
  }'
```

#### After (Sarvam)

#### Python (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_SARVAM_API_KEY",
    base_url="https://api.sarvam.ai/v2",
)

response = client.responses.create(
    model="kimi-k3",
    instructions="You are a helpful assistant.",
    input="Explain database indexing in three short points.",
    reasoning={"effort": "low"},
    max_output_tokens=3000,
)

print(response.output_text)
```

#### JavaScript (OpenAI SDK)

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "YOUR_SARVAM_API_KEY",
  baseURL: "https://api.sarvam.ai/v2",
});

const response = await client.responses.create({
  model: "kimi-k3",
  instructions: "You are a helpful assistant.",
  input: "Explain database indexing in three short points.",
  reasoning: { effort: "low" },
  max_output_tokens: 3000,
});

console.log(response.output_text);
```

#### Python (Sarvam SDK)

```python
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

response = client.responses.create(
    model="kimi-k3",
    instructions="You are a helpful assistant.",
    input="Explain database indexing in three short points.",
    reasoning={"effort": "low"},
    max_output_tokens=3000,
)

# The Sarvam SDK has no output_text shortcut; read the message item.
message = next(item for item in response.output if item.type == "message")
print(message.content[0].text)
```

#### JavaScript (Sarvam SDK)

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

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

const response = await client.responses.create({
  model: "kimi-k3",
  instructions: "You are a helpful assistant.",
  input: "Explain database indexing in three short points.",
  reasoning: { effort: "low" },
  max_output_tokens: 3000,
});

const message = response.output.find((item) => item.type === "message");
console.log(message.content[0].text);
```

#### cURL

```bash
curl https://api.sarvam.ai/v2/responses \
  -H "api-subscription-key: YOUR_SARVAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "input": "Explain database indexing in three short points.",
    "reasoning": {"effort": "low"},
    "max_output_tokens": 3000
  }'
```

## Conversation history

On Fireworks, each response is stored and the next call can point at it with
`previous_response_id`. On Sarvam, nothing is stored: keep the turns in a list and send the
whole list in `input`. `previous_response_id`, `store: true`, `conversation`, and
`background: true` return `400`, and `GET /v2/responses/{id}` returns `404`.

#### Before (Fireworks)

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_FIREWORKS_API_KEY",
    base_url="https://api.fireworks.ai/inference/v1",
)

first = client.responses.create(
    model="accounts/fireworks/models/glm-5p3",
    input="My name is Asha.",
)

second = client.responses.create(
    model="accounts/fireworks/models/glm-5p3",
    input="What's my name?",
    previous_response_id=first.id,
)

print(second.output_text)
```

#### After (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_SARVAM_API_KEY",
    base_url="https://api.sarvam.ai/v2",
)

history = [{"role": "user", "content": "My name is Asha."}]
first = client.responses.create(model="glm5.3", input=history)

history += [
    {"role": "assistant", "content": first.output_text},
    {"role": "user", "content": "What's my name?"},
]
second = client.responses.create(model="glm5.3", input=history)

print(second.output_text)
```

#### After (Sarvam SDK)

```python
from sarvamai import SarvamAI

client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")

def reply_text(response):
    message = next(item for item in response.output if item.type == "message")
    return message.content[0].text

history = [{"role": "user", "content": "My name is Asha."}]
first = client.responses.create(model="glm5.3", input=history)

history += [
    {"role": "assistant", "content": reply_text(first)},
    {"role": "user", "content": "What's my name?"},
]
second = client.responses.create(model="glm5.3", input=history)

print(reply_text(second))
```

Long conversations grow `input` on every turn. Trim or summarize older turns yourself to stay
within the model's context window.

## Reasoning

| Fireworks                                 | Sarvam                            | Note                                                                                                                            |
| ----------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `reasoning.effort` (`low`, `high`, `max`) | Same                              | On `glm5.3` and `glm5.3-flash`, `"max"` returns `400`; omitting the field gives `max` on `glm5.3` and `high` on `glm5.3-flash`. |
| `reasoning.effort: "medium"` / `"xhigh"`  | Use `"low"`, `"high"`, or `"max"` | Accepted on some models and returns `400` on others.                                                                            |
| `reasoning.effort: "none"`                | Same                              | Turns thinking off on `deepseekv4-pro`, `mimo-v2.6-flash`, and `mimo-v2.6-pro`.                                                 |
| Reasoning item in `output`                | Same                              | Read the trace from the item's `content[0].text`. `summary` is filled only when you set `reasoning.summary`.                    |

Reasoning tokens count toward `max_output_tokens`, which has no default cap on Sarvam.

## Tools

Sarvam's Responses API supports **function tools** only, in the flat Responses format:
`{"type": "function", "name": ..., "parameters": ...}`.

| Fireworks tool | On Sarvam                                                                                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `function`     | Same                                                                                                                                                                  |
| `web_search`   | Returns `400` on most models; `gemma4` and `sarvam-105b` accept it and never call it. Call a search service yourself and expose it as a function tool.                |
| `mcp`, `sse`   | Returns `400` on most models; `gemma4` and `sarvam-105b` accept it and never call it. Call your MCP server from your own code and expose its tools as function tools. |
| `python`       | Returns `400`. Run code in your own sandbox and return the result as a function call output.                                                                          |

The function call round trip is the same as on Fireworks, except that you resend the history
instead of passing `previous_response_id`: send the `function_call` item and a
`function_call_output` item in the next request's `input`. See the
[OpenRouter Responses guide's full example](/api/token-factory/migrations/from-openrouter/responses-api#full-example),
which works the same way for any stateless client.

`tool_choice` accepts `"auto"`, `"none"`, `"required"`, or a named function.
`parallel_tool_calls: false` limits a turn to one tool call on every open-weight model, and `max_tool_calls` returns `400`.

## Fields to remove

| Fireworks field or call                                                            | What to do on Sarvam                                                      |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `previous_response_id`, `conversation`                                             | Send the full history in `input`.                                         |
| `store`                                                                            | Remove, or set it to `false`. `true` returns `400`.                       |
| `background`                                                                       | Remove. Make a normal (or streaming) request.                             |
| `GET /responses/{id}`, `GET /responses/{id}/input_items`, `DELETE /responses/{id}` | Not available. Keep responses in your own storage if you need them later. |
| `stop`                                                                             | Remove. Not a Responses parameter on Sarvam.                              |
| `max_tool_calls`                                                                   | Remove. Stop the tool loop in your own code.                              |

## Parameter concept map

| Fireworks                                    | Sarvam                   | Note                                                                                                |
| -------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------- |
| `input` (string or items), `instructions`    | Same                     |                                                                                                     |
| `max_output_tokens`, `temperature`, `top_p`  | Same                     | Set `max_output_tokens`: there's no default cap.                                                    |
| `text.format` (`json_schema`, `json_object`) | Same                     |                                                                                                     |
| `input_image` content parts                  | Same                     | Inline base64 data URIs only, on models with image input.                                           |
| `input_audio` content parts                  | Same, on the MiMo models | `wav` or `mp3` only on the Responses API.                                                           |
| Video input                                  | Not supported            | Send video on Chat Completions.                                                                     |
| `stream: true`                               | Same                     | Standard events: `response.created`, `response.output_text.delta`, `response.completed`, and so on. |
| `response.output_text` (OpenAI SDK)          | Same                     | The `sarvamai` SDK doesn't have this shortcut; read the `message` item in `output`.                 |

## Common mistakes

#### Passing previous_response_id

Sarvam returns `400`. Keep the history in your app and send it in `input`, as in
[Conversation history](#conversation-history).

#### Fetching a stored response by id

Nothing is stored, so `GET /v2/responses/{id}` returns `404`. Save what you need from each
response when you receive it.

#### Using server-side tools

`web_search`, `mcp`, and `python` tools aren't run on Sarvam. Most models return `400`;
`gemma4` and `sarvam-105b` accept `web_search` and `mcp` but never call them. Run them
yourself and expose them as function tools.

#### Sending reasoning.effort: max to glm5.3

`glm5.3` and `glm5.3-flash` return `400` for the literal string `"max"`. Omit the field: that gives `max` on `glm5.3` and `high` on `glm5.3-flash`.

## See also

* [Migration overview](/api/token-factory/migrations/from-fireworks/overview): base URL, auth, and model IDs
* [Migrating Chat Completion from Fireworks](/api/token-factory/migrations/from-fireworks/chat-completion)
* [Responses API guide](/api/token-factory/responses-api)
* [Responses API reference](/api-reference/responses/create)