> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirobody.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Backbone Mode

> Run the Agent API as a bare LLM backend: mode:"model", the builtin_tools allowlist, and the full tool_choice contract.

Before copying a `curl` example, choose your Cloud region. For authenticated calls, it must be **the same region as your key**. The examples below use `MIROBODY_API_BASE`:

```bash theme={null}
export MIROBODY_API_BASE="https://api.mirobody.ai/v1"   # Global account
# export MIROBODY_API_BASE="https://api.mirobody.cn/v1" # China account: use this instead
```

For SDK examples with a literal Global URL, use the matching China URL when your account is in China. See [Regions](/en/api-reference/regions/overview).

**Backbone mode** turns [`POST /v1/responses`](/en/api-reference/responses) into a *bare inference backend* — an OpenAI-compatible LLM with client function tools, but **no** server-side agent runtime, tools, planning, or stored state. Use it when your own agent framework (LangChain, openai-agents, a custom loop) is the orchestrator and Mirobody is "the model."

The default (`mode: "agent"`) is the whole Mirobody agent: server-side runtime, built-in health-data tools, planning, and stored conversations.

<Note>
  Reach for backbone mode only when you own the orchestration. If you want grounded answers over the Subject's real health data, stay on the default agent mode — that's where the [built-in tools](/en/api-reference/function-calling#built-in-server-tools) live.
</Note>

All `/v1` endpoints share one base URL — pick the cluster your account uses:

```text theme={null}
https://api.mirobody.ai/v1   # Global
https://api.mirobody.cn/v1   # China
```

These are the Cloud clusters. A self-hosted deployment does not expose `/v1` — it serves its own `/api/*` routes and an `/mcp` endpoint, described in the [Self-Host Mirobody](/en/self-host).

Japan and EU clusters are in preparation — see [Regions](/en/api-reference/regions/overview). Model providers and pricing can differ by region, so read [`GET /v1/models`](/en/api-reference/models) from the cluster you call.

## `mode`

```jsonc theme={null}
{ "mode": "agent" | "model" }   // default "agent"
```

| | `mode:"agent"` (default) | `mode:"model"` (backbone) |
| - | - | - |
| Runtime | planning, sub-agents, code eval, virtual filesystem | single bare-model inference |
| Server tools | built-in domain tools (trim with `builtin_tools`) | **none** |
| System prompt | full agent base (\~10k tokens) | minimal safety base (\<100 tokens) |
| State | `previous_response_id` / `session_id` threads | **stateless** (both → `400`) |
| Continuation | stateful resume **or** stateless full replay | stateless full replay only |
| Client tools | handoff via `function_call` (server-issued `call_id`) | bound directly to the model (**`call_id` preserved**) |
| MCP tools | supported (server-executed) | `400` (no server tool loop) |
| Server-side thread state | yes (deleted at request end when `store=false`) | none |
| [`text.format`](/en/api-reference/structured-output) | `400` (not supported) | **supported** |

With `store=true`, model mode still persists the response object (`GET /v1/responses/{id}` works), but the conversation is tagged as model-mode: a later `previous_response_id` against it returns an explicit `400` ("replay the transcript to continue") rather than silently resuming an empty thread.

```bash theme={null}
curl "$MIROBODY_API_BASE/responses" \
  -H "Authorization: Bearer $MIROBODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "mirobody-flash",
        "mode": "model",
        "builtin_tools": "none",
        "input": "Summarize the attached lab panel.",
        "user": "alice"
      }'
```

<Note>
  Model mode is **stateless**. Continue a run by resending the full item transcript in `input` (the [stateless full-replay path](/en/api-reference/function-calling) — what openai-agents does by default). `previous_response_id`, `session_id`, and MCP tools each return `400`.
</Note>

## `builtin_tools`

```jsonc theme={null}
{ "builtin_tools": "auto" | "none" | ["query_health_data", ...] }   // default "auto"
```

Controls the server-side **domain-tool family** — the health-data, care-circle, and external-evidence tools:

`query_health_data` · `list_family_members` · `search_medical_evidence` · `read_source`

The external-evidence surface accepts only `search_medical_evidence` and `read_source`. Arbitrary URL fetching is not available: `read_source` accepts refs returned by search (`pmid:`, `pmc:`, `nct:`, or `doi:`), not model-constructed URLs.

| Value | Effect |
| - | - |
| `"auto"` (default) | All domain tools available — current behavior. |
| `"none"` | Domain tools all hidden. **Required when your backbone caller brings its own data or tools** — otherwise the model prefers to query the (empty) Mirobody Subject and skips your client tool. |
| `["name", ...]` | Allowlist. An unknown name returns `400 invalid_value` and lists the available set. |

The server-side orchestration primitives (`write_todos`, filesystem, `task`, `eval`) belong to agent mode itself, **outside** this parameter's scope — they may still appear in `tool_steps`. For a **zero** server-tool trace, use `mode:"model"`.

## `tool_choice`

`tool_choice` follows OpenAI semantics, with model mode adding hard guarantees the agent runtime cannot make:

| `tool_choice` | `mode:"model"` | `mode:"agent"` (default) |
| - | - | - |
| omitted / `"auto"` | Model decides | Model decides |
| `"none"` | Plain text (auto-drops into model mode) | Same, when stateless; with `previous_response_id`/`session_id` → `400` |
| `"required"` | **Guarantees** the output has at least one client `function_call` | `400 unsupported_parameter` (the agent runtime can't force a client-tool call) |
| `{"type":"function","name":X}` | **Guarantees** only `X` is called (stray calls pruned) | Accepted but best-effort (not forced) |
| `required` / named + empty `tools` | `400 invalid_value`, `param="tool_choice"` | Same |

<Note>
  **`tool_choice:"none"` disables *all* tools**, including the built-in ones (OpenAI semantics), and internally degrades to model-mode plain-text generation. The old behavior — clearing only client tools while the built-ins ran on — is gone.
</Note>

### Guarantees for forced tool calls

`required` / a named tool is a hard guarantee, not a hint — if it can't be honored you get a `502`, never a silent downgrade. In streaming, a forced call is synthesized into the standard event sequence (`response.output_item.added` → `response.function_call_arguments.delta`/`.done` → `response.output_item.done`), identical to the non-streaming behavior.

This works with LangChain `create_agent` under both `ToolStrategy(...)` (which auto-sends `tool_choice:"required"`) and `ProviderStrategy(...)`.

## Provider error classification (model mode)

In model mode, provider exceptions are classified by retryability instead of a blanket `502`:

| Provider side | Returned | Meaning |
| - | - | - |
| `400` / `404` / `413` / `422` (params, over-length) | **`400`** `invalid_request_error` | The provider's actionable message is passed through (truncated). **Do not retry.** |
| `429` | **`429`** `rate_limit_error` | `Retry-After` passed through or synthesized. |
| `401` / `403` (platform-side credentials / quota) | **`502`** `upstream_error` | A platform fault, not your request — no internal detail leaked. |
| `5xx` / timeout / transport | **`502`** `upstream_error` | Error type only; full text is logged with an `X-Request-Id`. |

## See also

* [Structured output](/en/api-reference/structured-output) — `text.format` (model mode only).
* [Function calling](/en/api-reference/function-calling) — declaring client tools and the two continuation paths.
* [Streaming](/en/api-reference/streaming) — `response.*` events, including the server-tool side-channel.
* [Rate Limits & Quota](/en/api-reference/rate-limits) — per-key rate limit and the monthly account quota.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.