Skip to navigation

Migrating the Responses API from OpenRouter to Sarvam

View as Markdown

Last updated: October 23, 2026

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

In short: both Responses APIs are stateless, so your history handling carries over. Change base_url, api_key, and model, remove OpenRouter-only fields such as provider, models, and plugins, and replace server tools like openrouter:web_search with your own function tools.

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. Remove OpenRouter-only fields: provider, models, plugins, and stop (list).
  4. Replace OpenRouter server tools with function tools you run yourself (Tools).
  5. 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).
  6. Set max_output_tokens: it has no default cap on Sarvam.
  7. If you use the sarvamai SDK, read the reply from the message item in output (quick start).

Quick start

from openai import OpenAI
client = OpenAI(
api_key="YOUR_OPENROUTER_API_KEY",
base_url="https://openrouter.ai/api/v1",
)
response = client.responses.create(
model="deepseek/deepseek-v4-pro-0813",
instructions="You are a helpful assistant.",
input="Explain database indexing in three short points.",
reasoning={"effort": "high"},
max_output_tokens=3000,
extra_body={"provider": {"sort": "throughput"}},
)
print(response.output_text)

Conversation history

Both APIs are stateless: send the whole conversation in input on every call. Code that already does this for OpenRouter works unchanged. previous_response_id, store: true, conversation, and background: true return 400 on Sarvam, as on OpenRouter.

Reasoning

OpenRouterSarvamNote
reasoning.effortreasoning.effortlow, high, or max. 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: "none"SameTurns thinking off on deepseekv4-pro, mimo-v2.6-flash, and mimo-v2.6-pro.
reasoning.max_tokens, reasoning.excludeNot supportedChoose an effort level, and size max_output_tokens for reasoning plus the answer.
reasoning.summarySameWith "auto" or "detailed", the reasoning item’s summary is filled.
Reasoning item in outputSameRead the trace from the item’s content[0].text. summary is empty unless 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 same flat Responses format: {"type": "function", "name": ..., "parameters": ...}. OpenRouter server tools, such as openrouter:web_search, return 400. Run those services from your own code and expose them as function tools.

The function call round trip is the same as on OpenRouter: the model returns a function_call item, you run the function, and you send back the call plus a function_call_output item in the next request’s input. See the full example.

Sarvam
tool_choice"auto", "none", "required", or a named function
parallel_tool_calls: falseLimits a turn to one tool call on every open-weight model; sarvam-105b ignores it on this route
max_tool_callsReturns 400

Fields to remove

Sarvam returns 400 with the field named for request fields it doesn’t support.

OpenRouter fieldWhat to do on Sarvam
provider, modelsRemove. Retry on 429 and 503 yourself.
plugins, openrouter:* server toolsRemove. Use function tools.
stopRemove. Not a Responses parameter on Sarvam.
max_tool_callsRemove. Stop the tool loop in your own code.
previous_response_id, store: true, conversation, backgroundRemove. Send the full history in input.

Parameter concept map

OpenRouterSarvamNote
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.
include, truncation, text.verbosityAccepted
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.

Full example

A function-calling loop that sends the call and its result back in input:

import json
from openai import OpenAI
client = OpenAI(
api_key="YOUR_SARVAM_API_KEY",
base_url="https://api.sarvam.ai/v2",
)
tools = [{
"type": "function",
"name": "get_weather",
"description": "Get the weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}]
def get_weather(city: str) -> str:
return f"31°C and sunny in {city}" # call your real service here
history = [{"role": "user", "content": "What's the weather in Delhi?"}]
response = client.responses.create(model="kimi-k3", input=history, tools=tools, max_output_tokens=3000)
for item in response.output:
if item.type == "function_call":
result = get_weather(**json.loads(item.arguments))
history += [
{"type": "function_call", "call_id": item.call_id, "name": item.name, "arguments": item.arguments},
{"type": "function_call_output", "call_id": item.call_id, "output": result},
]
final = client.responses.create(model="kimi-k3", input=history, tools=tools, max_output_tokens=3000)
print(final.output_text)

Common mistakes

glm5.3 and glm5.3-flash return 400 for the literal string "max" on the Responses API. Omit reasoning.effort instead: that gives max on glm5.3 and high on glm5.3-flash.

Sarvam doesn’t cap output by default, so a reasoning model can generate for a long time. Set max_output_tokens.

The shortcut exists in the openai package only. With sarvamai, read the message item in output.

Server tools such as openrouter:web_search return 400. Call the service yourself and expose it as a function tool.

See also