DocsAPI keys

Providers

Provider failover

A provider that fails before it answers is passed over without you noticing. One that fails mid-answer is your call, fixed before the request is sent. Either way the answer names who gave it.

Failure before the model speaks

Invisible. A provider that refuses or breaks before producing output is stepped over, the next candidate is tried, and you are never told, under either streaming policy. What reaches you is the answer, from whoever gave it, named in the reply.

"model": { "name": "kimi-k3", "tier": "xhigh", "publisher": "MoonshotAi", "provider": "TogetherAi" }

This is why you read model back rather than assuming it echoes your request. The call record lists every provider tried, in order, with the status each ended on.

Failure after the model has started

On POST /models it is your call, set in streamFailureBehavior and fixed before dispatch: changing it requires a new request. Momor will not silently stitch two providers' half-answers together in either mode.

streamFailureBehavior Behaviour
"stop" (default) The break is the ending. No second provider speaks into a stream the first was already answering. No stop, no usage record.
"rollover" The next rung finishes what the first started, on the same connection, and the frames say where that happened.
# stop
streamStart:Anthropic → contentStart → content:"It is " → contentEnd
  → streamError:Anthropic → error:502:The provider closed the connection mid-answer.

# rollover
streamStart:Anthropic → contentStart → content:"The three causes were " → contentEnd
  → streamError:Anthropic → error:502:…
  → streamStart:Groq → contentStart → content:"a stale cache, a retry storm, and a bad deploy." → contentEnd
  → stop:stop

The frames name both sides streamError names who stopped; the second streamStart names who took over. If you render partial answers, that pair is your cue to show the handover rather than splice the text.

A Chat Completions stream always stops: a failure after output ends the stream on one error chunk, with no [DONE], and the call is never moved to another provider once output has begun.

What this means for a UI

A design that renders a stream as one undifferentiated column of text cannot show a handover. Give the answer a provider-attributed structure from the start: each streamStart opens a segment stamped with the model and provider that produced it, and the streamError between segments is a visible seam, not a swallowed retry.

The usage on stop reports the provider that finished. Tokens spent before the break were spent with the first provider.

Moving a conversation between providers

A conversation is not tied to the model that started it. Send a turn back as history and route it anywhere. Reasoning, open tool calls, tool results and files all travel; what a destination can carry natively it carries, and what it cannot is adapted and labelled rather than dropped.

{
  "model": "gemini-3.6-flash",
  "systemPrompt": "Answer in one sentence.",
  "messages": [
    { "type": "user",     "value": "What is the capital of France?" },
    { "type": "thinking", "value": "Recall the capitals of Europe.", "data": { "anthropic.signature": "…" } },
    { "type": "content",  "value": "Checking the almanac." },
    { "type": "toolCall", "call": { "id": "toolu_01", "name": "almanac", "arguments": "{\"q\":\"capital\"}" } },
    { "type": "toolResult", "result": { "id": "toolu_01", "name": "almanac", "content": "Paris" } }
  ]
}
Destination What happens to reasoning
gemini, vertex Becomes a thought part carrying the text. Another family's signature is not sent, because Gemini cannot verify it.
Groq, TogetherAi, MoonshotAi, Fireworks, DeepInfra Rides the host's own reasoning field on the assistant message.
azure Rides Kimi's reasoning field for the Kimi models, and goes back as the assistant's text for every other model.
Mistral Becomes a thinking part ahead of the answer in the assistant's content, carrying the signature Mistral issued where it issued one.
Anthropic Replayed as its own signed thinking block where Anthropic issued the signature. Otherwise sent as text prefixed [reasoning], so the model cannot read a predecessor's working as something it already said aloud.

Tool identities survive the crossing. Your history keeps every id as you received it, and each destination is handed the ids in the form it takes:

Destination The ids it is sent
Anthropic Yours, with any character other than a letter, a digit, _ or - written as _. Gemini's functions.almanac:1 becomes functions_almanac_1.
OpenAI Yours, with any id longer than 64 characters shortened to 64.
Mistral's models, on every host Nine letters and digits: an id already in that form as it is, any other as a stable hash of itself.
Kimi K2.5 and K2.6 functions.{name}:{index}, the form the model was trained on, numbered across the conversation.
Every other model Yours, as they are.

Every rewritten id is made the same way on every turn, so a call and its result stay paired and a provider's prompt cache still matches the conversation. You never normalise an id before sending it, and the ids in an answer are the serving provider's own. A completed tool is never re-executed because history was adapted.

What crossing costs

No provider can verify another's signed reasoning state, so what crosses is the readable text plus whatever state the destination can carry. Reasoning that started on Anthropic and moves to Gemini arrives without Anthropic's signature; moving back, it arrives as labelled text rather than a signed block.

If exact reasoning fidelity matters more than provider independence for a conversation, pin the provider for it.

Updated Oct 22, 2026
Esc