Skip to navigation

Migrating the Responses API from Fireworks AI to Sarvam

View as Markdown

Last updated: October 23, 2026

This guide covers moving Fireworks AI Responses API calls to Sarvam’s POST /v2/responses. For Chat Completions, see Migrating Chat Completion.

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.
  3. Replace previous_response_id chaining with a history list sent in input (Conversation history).
  4. Remove store, background, and calls to retrieve stored responses (list).
  5. Replace server-side tools with function 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).
  7. Set max_output_tokens: it has no default cap on Sarvam.

Quick start

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)

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.

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)

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

Reasoning

FireworksSarvamNote
reasoning.effort (low, high, max)SameOn 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"SameTurns thinking off on deepseekv4-pro, mimo-v2.6-flash, and mimo-v2.6-pro.
Reasoning item in outputSameRead 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 toolOn Sarvam
functionSame
web_searchReturns 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, sseReturns 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.
pythonReturns 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, 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 callWhat to do on Sarvam
previous_response_id, conversationSend the full history in input.
storeRemove, or set it to false. true returns 400.
backgroundRemove. 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.
stopRemove. Not a Responses parameter on Sarvam.
max_tool_callsRemove. Stop the tool loop in your own code.

Parameter concept map

FireworksSarvamNote
input (string or items), instructionsSame
max_output_tokens, temperature, top_pSameSet max_output_tokens: there’s no default cap.
text.format (json_schema, json_object)Same
input_image content partsSameInline base64 data URIs only, on models with image input.
input_audio content partsSame, on the MiMo modelswav or mp3 only on the Responses API.
Video inputNot supportedSend video on Chat Completions.
stream: trueSameStandard events: response.created, response.output_text.delta, response.completed, and so on.
response.output_text (OpenAI SDK)SameThe sarvamai SDK doesn’t have this shortcut; read the message item in output.

Common mistakes

Sarvam returns 400. Keep the history in your app and send it in input, as in Conversation history.

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

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.

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