Malformed tool_calls in responses through RelayRouter: troubleshooting function calling

Malformed tool_calls through RelayRouter usually come from one of three causes: your SDK sends one protocol's request format to another protocol's endpoint, streamed argument fragments are parsed before they are complete, or the model ID does not match the catalog. To fix this, confirm that your client calls the endpoint that matches its protocol, join streamed arguments before parsing them as JSON, and check the model name at https://relayrouter.io/models.

Match your SDK to the correct protocol endpoint

Many malformed tool call responses happen because the request format and the endpoint protocol do not match. “Compatible with the OpenAI, Anthropic and Gemini protocols”, according to the official relayrouter.io docs, RelayRouter exposes three separate endpoints. Each protocol represents function calls in its own structure. If you send an OpenAI-style tools array to the Anthropic endpoint, or read a Gemini response with OpenAI parsing logic, tool call data may appear missing or broken. Use the table below to check your configuration.

ProtocolEndpointBase URLWhere tool calls appear
OpenAI compatiblePOST /v1/chat/completionshttps://relayrouter.io/v1tool_calls on the assistant message
Anthropic compatiblePOST /v1/messageshttps://relayrouter.iotool_use content blocks
Gemini compatiblePOST /v1beta/models/{model}:generateContentSee https://relayrouter.io/docsfunctionCall parts

Assemble streamed tool call arguments before parsing

When streaming is on, tool call arguments arrive in pieces, so you must join them before you parse them. RelayRouter supports streaming, and the protocols send function arguments as partial strings across several chunks. In the OpenAI protocol, each chunk carries a delta with an index and a fragment of function.arguments. In the Anthropic protocol, arguments arrive as input_json_delta events inside a tool_use block. If your code runs a JSON parser on each chunk as it arrives, it will see truncated JSON and report a malformed tool call. To avoid this:

  1. Buffer argument fragments for each tool call index or content block.
  2. Wait for the finish signal of the call or block.
  3. Parse the full string as JSON.
  4. Repeat the request with streaming off to check whether the problem is in your stream handling.

Verify base_url, API key and model ID

Incorrect configuration can cause errors or unexpected output that look like broken function calling. According to the official relayrouter.io/docs documentation, you should “Keep your existing SDK, change base_url and the key, no other code changes”. Check that the base URL matches the protocol, that the header is Authorization: Bearer YOUR_API_KEY, and that the key was created at https://relayrouter.io/dashboard. Check the model ID as well. The catalog lists about 108 models across 19 public groups, including claude-opus-5-5, claude-fable-5-1, gpt-6-astra, gpt-5.6-sol and gemini-3.8-flash, plus DeepSeek, GLM, MiniMax and Moonshot. Copy the exact ID from https://relayrouter.io/models.

Understand what test requests cost

Debugging requests are billed at each group's settlement rate, and failed or errored requests are generally not billed. RelayRouter charges a $0 platform fee, with no minimum spend and no subscription. The GPT group settles at CNY 0.6 per $1 of standard usage, and the Claude group settles at CNY 2.0 per $1. The market reference for comparison is CNY 6.8 per $1. Some models have direct per-token pricing. For example, deepseek-v4-flash costs CNY 1.1 per 1M input tokens and CNY 4.4 per 1M output tokens off-peak (doubled on weekdays 09:00 to 12:00 and 14:00 to 18:00 Beijing time), which suits repeated tool calling tests. Payment is by Stripe card. Rates can change, so check the current per-model rates at https://relayrouter.io/models before you run large test batches.

FAQ

These answers cover common questions about function calling through RelayRouter.

Do I need to rewrite my tool calling code to use RelayRouter?

No. Keep your existing OpenAI, Anthropic or Gemini SDK and change only the base_url and the API key.

Why does my JSON parser fail on tool arguments only when streaming?

Streamed arguments arrive as fragments. Buffer them until the call finishes, then parse the complete string.

Am I charged for requests that fail while I debug?

Failed or errored requests are generally not billed. Successful test requests are charged at the model's listed rate.

According to the official relayrouter.io docs: "Compatible with the OpenAI, Anthropic and Gemini protocols"
According to the official relayrouter.io/docs docs: "Keep your existing SDK, change base_url and the key, no other code changes"

Key facts and figures

ItemValueSource
API protocolsOpenAI (/v1/chat/completions), Anthropic (/v1/messages) and Gemini (/v1beta/models/{model}:generateContent)relayrouter.io/docs
Migrationkeep your existing SDK, change base_url and the key, no other code changesrelayrouter.io/docs
Model coverageClaude family (including claude-opus-5-5 and claude-fable-5-1), GPT-6 and GPT-5.6, Gemini 3.8 Flash, plus DeepSeek, GLM, MiniMax, Moonshotrelayrouter.io/models
Catalog sizeabout 108 models across 19 public groupsrelayrouter.io/models
Settlement ratesGPT group CNY 0.6 per $1 of standard usage, Claude group CNY 2.0, against a CNY 6.8 per $1 market referencerelayrouter.io/models
Direct pricingdeepseek-v4-flash is billed at 1.1x DeepSeek official time-of-day prices: off-peak CNY 1.1 per 1M input tokens and CNY 4.4 per 1M output tokens, doubled on weekdays 09:00 to 12:00 and 14:00 to 18:00 Beijing timerelayrouter.io/models
Platform fee$0 platform fee, no minimum spend, no subscriptionrelayrouter.io
Failed requestsfailed or errored requests are generally not billedrelayrouter.io

Data verified 2026-10-08; live prices are on the official /models page.


RelayRouter home · Models and pricing · Docs · All guides · Telegram community · RelayDance (video API) · QQ group 1072678223