# Call a model

Momor’s own request: typed messages in, typed blocks out, whole or streamed. Reasoning, answer text and tool calls stay separate, and the same body reaches every provider. Every property is camelCase.

`POST https://api.momor.ai/models`

`/models/chat` and `/models/two` answer the same way; each reaches chat models only. Decision models answer at [/models/decision](/docs/gateway/reference/decision/) and transcription models at [/models/transcribe](/docs/gateway/reference/transcribe/). The route is stateless: there is no conversation id, so send the full message list every time.

## Headers

- `Authorization` (string, required): Bearer and your API key.
- `Content-Type` (string, required): application/json. Anything else is refused with 415.
- `Accept` (string): Must allow application/json for a whole answer, or text/event-stream for a stream; otherwise the call is refused with 406. It never changes which one you get.

## Body

- `systemPrompt` (string, required): The instructions binding the whole turn. Not a message: it sits outside the array, and every string is literal prompt text.
- `messages` (Message[], required): The conversation so far, at least one message and at most 256. A union on type; the same shape comes back in a reply, so a turn you receive can be appended and sent again, to any provider.
  - `type` (string, required): Who said it: what the caller said, what a model said, a model’s reasoning, a call the model made, or the answer to one call. Values: `user`, `content`, `thinking`, `toolCall`, `toolResult`.
  - `value` (string): For user, content and thinking: the text.
  - `files` (File[]): For user: anything attached. See Files and file processing.
    - `type` (string, required): An absolute http or https address, or base64 bytes. Handles are refused. Values: `url`, `bytes`.
    - `value` (string, required): The address, or the base64 bytes.
    - `name` (string, required): The file’s name.
    - `contentType` (string, required): A valid media type, such as application/pdf.
  - `data` (object): For content and thinking: the provider state that lets reasoning replay natively. Keep it when you store a turn.
  - `call` (object): For toolCall: id, name, arguments and data. arguments is a JSON string, not an object.
  - `result` (object): For toolResult: id, name, content, documents and failure. id pairs it with an earlier call.
- `model` (string | object, default `auto`): Which models may answer. A string is a selector such as claude-sonnet-5, anthropic/claude-sonnet-5 or tier/high; auto and * mean every model. A tier, auto or * leaves out deprecated models and models released on or before the cut-off, unless prioritization lets them in. Send model or models, not both.
  - `name` (string, default `auto`): The model’s canonical name.
  - `tier` (string): Any model in that tier. Left out, any tier. A model not yet classified is never served. Values: `free`, `low`, `medium`, `high`, `xhigh`, `tierless`.
  - `publisher` (string): The catalog’s ownedBy, or * for any publisher.
  - `provider` (string): The catalog’s provider: the service that runs the call. Never *.
  - `except` ((string | object)[]): Selectors whose models this one leaves out.
- `models` ((string | object)[]): Several selectors, tried in the order given.
- `prioritization` (object, default `{}`): Which providers serve first and which never do.
  - `order` (string[]): Providers that lead, in this order, ahead of price: a root such as azure, or a region as name@region, such as azure@eu.
  - `ignore` (string[]): Providers that serve nothing on this call. A root leaves out the root alone; name@region leaves out that region alone.
  - `sort` (string, default `price`): After order, the cheapest offering first. Values: `price`.
  - `zdr` (boolean, default `false`): Run the call under zero data retention: only on saved keys marked zdr and on Momor’s keys its own agreements cover, never on keys sent with the call. Where your organization holds every call to it, false here does not turn it off.
  - `deprecated` (boolean): Let deprecated models serve a tier, auto or * selector. Left out, your organization’s default, else false. A selector naming one exact model is served by it either way.
  - `maxAge` (string): How old a model may be, as ISO 8601 such as P6M, P1Y or P2Y, or a TimeSpan such as 180.00:00:00: a tier, auto or * selector is served only by models released no longer ago than this. A month counts thirty days and a year 365. Left out, your organization’s default, else no model is left out for its age. A selector naming one exact model is served by it whatever its age.
- `keys` (object, default `{}`): Your own provider keys for this call, by provider name: a string, or an object holding key and the values the provider needs. Never recorded or logged.
- `parameters` (object, default `{}`): Sampling and ceilings. Each goes to the provider under its own name; see How parameters reach providers below.
  - `maxTokens` (integer): Output ceiling. Anthropic requires one.
  - `temperature` (number): Provider default when left out.
  - `topP` (number): Provider default when left out.
  - `reasoningEffort` (string, default `none`): none, also what leaving it out sends, asks the model not to reason. Values: `none`, `low`, `medium`, `high`.
  - `toolUse` (object, default `{ "type": "auto" }`): Whether the model may call a tool, must call one, must call the named one, or must not. Values: `auto`, `none`, `any`, `use`.
  - `strict` (boolean): Hold the provider to responseSchema where it has a strict mode.
  - `stop` (string[]): Sequences at which the model stops.
  - `seed` (integer): The sampling seed.
  - `frequencyPenalty` (number): Penalizes a token for each time it has appeared.
  - `presencePenalty` (number): Penalizes a token that has appeared at all.
  - `parallelToolCalls` (boolean, default `true`): false holds the model to one tool call a turn where the offering can.
  - `topK` (integer): How many of the likeliest tokens each step samples from.
  - `serviceTier` (string): The capacity the call is served from, sent as each provider’s own word. Values: `auto`, `standard`, `default`, `flex`, `priority`, `scale`.
  - `user` (string): A stable id for your own end user.
  - `metadata` (object): Labels, as strings, the provider stores against the call.
  - `logprobs` (boolean): Return each answer token’s log probability.
  - `topLogprobs` (integer): How many alternatives come back beside each token.
  - `caching` (string, default `auto`): What the provider is asked to cache of the request’s prefix, several joined by commas. Values: `auto`, `tools`, `system`, `messages`, `custom`, `none`.
  - `networkTimeout` (string): The longest one network operation of the call may take, as ISO 8601 such as PT30S or a TimeSpan such as 00:00:30, longer than zero and at most 100 seconds. It only ever shortens a call; on Anthropic it bounds the wait for the reply to begin. Never sent to the provider; left out, the provider’s client keeps its own.
- `tools` (Tool[], default `[]`): Tools the model may call, at most 128, each named once. The declaration is translated into each provider’s format.
  - `name` (string, required): The name the model calls.
  - `description` (string, required): What it does.
  - `parameters` (JSON Schema, required): The argument shape.
- `responseSchema` (JSON Schema): Holds the answer to a schema. Needs a model whose structuredOutput is jsonSchema.
- `streaming` (boolean, default `false`): Return server-sent events instead of one assembled turn. See Streaming.
- `streamFailureBehavior` (string, default `stop`): What a failure does once output has begun: end the stream, or let the next candidate finish it. See Provider failover. Values: `stop`, `rollover`.
- `fileProcessing` (object, default `{ "type": "none" }`): Whether a file is converted before the model sees it. Never changes which model answers. Under zero data retention, anything but none is refused with 400.
  - `type` (string, required): none sends files as they are; auto converts what the model can’t read; directed uses the processors in types. Values: `none`, `auto`, `directed`.
  - `types` (object): For directed: media type, or a prefix ending in *, to a processor or model name.

The body may be at most 30 MiB. Inline files may be at most 10 MiB each and 20 MiB together, and the serialized schemas, tools’ and `responseSchema` together, at most 256 KiB. These are the defaults; a deployment can lower them.

## Response

- `type` (string): monolith, for a whole answer.
- `model` (object): What actually served the call, after selector resolution and failover. Read it back rather than assuming it echoes your request.
  - `name` (string): The canonical name.
  - `tier` (string): The model’s tier.
  - `publisher` (string): Who made it.
  - `provider` (string): Who served it.
- `messages` (Message[]): The output in the order it was given: thinking, content and toolCall messages, the same union you send.
- `usage` (object): As the provider reported it, not estimated.
  - `provider` (string): The provider the tokens were spent with.
  - `inputTokens` (integer): Input tokens.
  - `outputTokens` (integer): Output tokens.
  - `cacheReadTokens` (integer): Input read from the provider’s cache.
  - `cacheWriteTokens` (integer): Input written to the provider’s cache.
  - `thoughtTokens` (integer): Reasoning tokens, where the provider counts them apart.
  - `reasoningTokens` (integer): The part of outputTokens spent reasoning, where the provider counts it inside the output.
  - `finishReason` (string): The provider’s own reason, as it gave it.
  - `fingerprint` (string): The provider’s id for the backend that served the turn, where it gives one.

Every answer the route gives, a routing refusal included, carries the call’s id in `X-Momor-Request-Id`. Who was tried and what each attempt cost are on the call record: read it with [Get a generation](/docs/gateway/reference/generation/). A stream’s frames are described in [Streaming](/docs/gateway/streaming/).

## Errors

A failure before a stream opens is a problem document, `{ "status", "detail" }`. Once a stream is open, a failure is an `error` frame inside it.

| Status | Code | What happened |
| --- | --- | --- |
| `400` | `—` | The body is invalid: no systemPrompt or message, both model and models, too many messages or tools, schemas over 256 KiB, a malformed selector, a provider this deployment does not serve, a tool result that names no earlier call, a networkTimeout that is not longer than zero or is over 100 seconds, or fileProcessing other than none under zero data retention. |
| `401` | `—` | The key is missing, revoked, expired or not a Momor key. |
| `404` | `—` | No configured model answers to <name>: nothing matches. |
| `404` | `—` | No configured model answering to <name> runs on a key the caller or Momor holds: models match, but none runs on your own key or on a key Momor resells. Under zero data retention, that is a saved key marked zdr or a Momor key its own agreements cover. |
| `406` | `—` | Accept does not allow the response streaming selects. |
| `413` | `—` | The body, an inline file or the inline files together are over their limits. |
| `415` | `—` | The body is not application/json. |
| `422` | `—` | Models matched, and every one refused the call: tools, a schema, streaming or a file type none of them can take. |
| `429` | `—` | Too many requests, or a provider is limiting your own key. Wait for Retry-After. |
| `502` | `—` | A provider refused your own key, or a stream opened and produced nothing or ended without a terminal event. |
| `503` | `—` | Every candidate failed upstream or was unavailable. |
| `504` | `—` | The provider did not answer within the call’s network timeout, or within the gateway’s own limit. |
| `Provider’s own` | `—` | Every candidate was tried, and the last provider’s status and message are passed through. |

Every message `detail` can carry, and which failures are worth retrying, are on [Errors](/docs/gateway/errors/).

## How parameters reach providers

Nothing is refused because a provider would not take it. An optional parameter goes only to an offering whose catalog entry says it honours it; anywhere else it is left off and the provider applies its own default. Values are not checked: a provider that refuses one moves the call to the next candidate.

| Parameter | Where it goes |
| --- | --- |
| `maxTokens · temperature · topP · reasoningEffort · toolUse · strict` | Every offering whose provider’s API has it, under that provider’s own name. Gemini and Vertex are sent neither temperature nor topP, and an offering that does not reason is asked for no reasoningEffort. |
| `stop · seed · frequencyPenalty · presencePenalty · parallelToolCalls · topK · serviceTier · user · metadata · logprobs · topLogprobs` | Only an offering that honours it. |
| `caching` | Only an offering whose entry declares caching, and only in the form its provider takes. |
| Anything else in parameters | As you wrote it, under that name, to every provider whose request can carry a field Momor has no name for: the OpenAI-compatible providers, OpenAI and Anthropic. Gemini and Vertex leave it off. A name Momor writes itself keeps Momor’s value. |

`serviceTier` takes Momor’s words, and each provider is sent its own. An OpenAI-compatible provider is sent the word as you wrote it; any other word is left off everywhere.

| serviceTier | OpenAI | Anthropic | Google |
| --- | --- | --- | --- |
| `auto` | `auto` | `auto` | Left off |
| `standard · default` | `default` | `standard_only` | `standard` |
| `flex` | `flex` | Left off | `flex` |
| `priority` | `priority` | auto, which reaches its priority tier where your account holds some | `priority` |
| `scale` | `scale` | Left off | Left off |

## Prompt caching

Most of a call’s input repeats from one turn to the next. A provider that caches that prefix bills it at a fraction of its input price on the next call that starts the same way. Momor caches by default: `caching` is `auto` unless you set it. Values combine with commas, as in `"tools, system"`, and `custom` sets aside every other value.

| caching | Asks for |
| --- | --- |
| `auto` | The provider places the cache breakpoint itself and moves it forward as the conversation grows. |
| `tools` | A breakpoint at the end of the tools. |
| `system` | A breakpoint at the end of the system prompt, which takes in the tools ahead of it. |
| `messages` | A breakpoint at the end of the conversation. |
| `custom` | Nothing of Momor’s own. The provider’s own caching fields, sent as other members of parameters, decide what is cached and for how long. |
| `none` | Nothing. A provider that caches on its own still does. |

| Provider | auto · tools · system · messages | With custom, send in parameters |
| --- | --- | --- |
| Anthropic | auto and messages are one top-level cache_control, which Anthropic puts on the last cacheable block. system marks the system prompt and tools the last tool. Each breakpoint holds for five minutes. | cache_control, for example { "type": "ephemeral", "ttl": "1h" }. Only the top-level breakpoint can be set this way. |
| OpenAI | Caches every prefix on its own; nothing is sent. | prompt_cache_key, prompt_cache_retention (in_memory, or 24h on the models that keep a prefix for a day), and prompt_cache_options on GPT-5.6 and later. |
| Gemini · Vertex | Cache every prefix on their own; nothing is sent. | Nothing: their request carries no field Momor has no name for. |
| Kimi (Moonshot) | Caches every prefix on its own for five minutes; nothing is sent. | prompt_cache_options, { "mode": "implicit", "ttl": "5m" } or "1h", which Kimi writes on kimi-k3. |
| DeepInfra | Caches on its own; nothing is sent. | prompt_cache_options, { "mode": "explicit", "ttl": "5m" } or "1h", and prompt_cache_key. |
| Together AI | Caches on its own; nothing is sent. | prompt_cache_key. |
| Mistral | Caches matching prefixes; nothing is sent. | prompt_cache_key. |
| Fireworks | Caches on its own; nothing is sent. | user and prompt_cache_isolation_key. |
| Groq | Caches the gpt-oss models on its own; nothing is sent. | Nothing. |
| Azure AI Foundry | Documents no caching for the models it sells itself; nothing is sent. | Nothing. |

A breakpoint costs more than the input it covers when Anthropic writes it: a five-minute write is billed at 1.25 times the input price and an hour’s at twice it, and a read at a tenth or less. A prefix shorter than the model’s minimum, 512 to 4,096 tokens, is not cached and nothing is refused. Cached tokens come back in `usage` as `cacheReadTokens`, and Anthropic’s writes as `cacheWriteTokens`. A Chat Completions call has no `caching`: it reaches the provider with the caching fields you wrote.

```bash title="Request"
curl https://api.momor.ai/models \
  -H "Authorization: Bearer $MOMOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4-mini",
    "systemPrompt": "Answer in one sentence.",
    "messages": [
      { "type": "user", "value": "What is the capital of France?" }
    ],
    "parameters": { "maxTokens": 1024 }
  }'
```

```python
import os
import requests

response = requests.post(
    "https://api.momor.ai/models",
    headers={"Authorization": f"Bearer {os.environ['MOMOR_API_KEY']}"},
    json={
        "model": "gpt-5.4-mini",
        "systemPrompt": "Answer in one sentence.",
        "messages": [{"type": "user", "value": "What is the capital of France?"}],
        "parameters": {"maxTokens": 1024},
    },
)
turn = response.json()
```

```typescript
const response = await fetch("https://api.momor.ai/models", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MOMOR_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-5.4-mini",
    systemPrompt: "Answer in one sentence.",
    messages: [{ type: "user", value: "What is the capital of France?" }],
    parameters: { maxTokens: 1024 },
  }),
});

const turn = await response.json();
```

```csharp
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

using var http = new HttpClient { BaseAddress = new Uri("https://api.momor.ai") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MOMOR_API_KEY"));

var response = await http.PostAsJsonAsync("/models", new
{
    model = "gpt-5.4-mini",
    systemPrompt = "Answer in one sentence.",
    messages = new object[] { new { type = "user", value = "What is the capital of France?" } },
    parameters = new { maxTokens = 1024 },
});

var turn = await response.Content.ReadFromJsonAsync<JsonElement>();
```

```json title="Response"
{
  "type": "monolith",
  "model": { "name": "gpt-5.4-mini", "tier": "medium", "publisher": "OpenAI", "provider": "openai" },
  "messages": [
    { "type": "content", "value": "The capital of France is Paris.", "data": {} }
  ],
  "usage": {
    "provider": "openai",
    "inputTokens": 22,
    "outputTokens": 11,
    "cacheReadTokens": 0,
    "cacheWriteTokens": 0,
    "thoughtTokens": 0,
    "reasoningTokens": 0,
    "finishReason": "completed"
  }
}
```

```json
{
  "status": 404,
  "detail": "No configured model answers to claud-sonnet-5."
}
```
