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

# Pools

> Route and fail over LLM traffic across model connections

export const modelPool = "A pool groups multiple model connections behind one name. Agents request the pool by name. Dome routes, load-balances, and fails over across members.";

<p>
  {modelPool}
</p>

## Overview

A pool contains one or more [models](/connect/resources/models). When an agent puts the pool name in a request's `model` field, Dome orders the members according to the routing strategy. Dome sends the request to the first eligible member. If that attempt fails, Dome can try the remaining eligible members.

The typical workflow is:

1. [Connect the models](/connect/resources/models#add-model) that can serve the traffic.
2. [Create a pool](#create-pool).
3. [Add the models as members](#add-member).
4. Configure the pool's [routing strategy](#routing-strategies) and [failover](#failover).
5. [Attach the pool to a Gateway](#attach-to-a-gateway).
6. Allow the Gateway on the [agent](/connect/agents#allowed-resources).
7. [Verify the pool](#verify-pool) with that agent's API key.

### Members

Each member represents one model connection in the pool. With priority-weighted routing, the priority places the member in a failover tier. The weight determines how often Dome selects the member within that tier. Round-robin and least-loaded routing treat every member equally, so they ignore priority and weight.

A model can belong to more than one pool. Removing a member changes only that pool and leaves the model connection available elsewhere.

<Warning>
  The management interfaces store an `enabled` value, but the current gateway routes to members regardless of that value. To stop sending traffic to a member, remove it from the pool.
</Warning>

### Routing strategies

The routing strategy chooses the primary model and orders any failover candidates.

| Strategy            | Primary selection                                                              | Member fields it uses |
| ------------------- | ------------------------------------------------------------------------------ | --------------------- |
| `priority_weighted` | Chooses by weight from the lowest priority tier                                | Priority and weight   |
| `round_robin`       | Rotates through all members in order                                           | Neither               |
| `least_loaded`      | Chooses the member with the fewest in-flight requests and breaks ties randomly | Neither               |

Use `priority_weighted` when some models should take traffic before others. Use `round_robin` or `least_loaded` when members are peers. The `strategy_scope` setting determines whether round-robin rotation and least-loaded request counts are shared across the workspace or tracked per agent. Priority-weighted routing does not use this setting.

You can choose a strategy when you [create a pool](#create-pool) or [change it later](#change-routing).

### Failover

The failover limit controls how many additional members Dome may try when the request to the primary member fails.

| Value             | Runtime behavior                                 |
| ----------------- | ------------------------------------------------ |
| No limit or `all` | Try every eligible member until one succeeds     |
| `0`               | Try only the primary                             |
| `N`               | Try the primary and up to `N` additional members |

Dome authorizes the primary before sending the request. If the primary fails, Dome authorizes each remaining member before trying it and skips any member that rules deny. A streaming request can fail over only before Dome sends the first response data to the caller. An error after streaming begins terminates the response.

You can set failover when you [create a pool](#create-pool) or [change it later](#change-failover).

### Pool resolution

When a request reaches a Gateway, Dome resolves its `model` value in this order:

1. A pool with that exact name
2. A direct model connection with that exact name
3. A direct connection whose upstream model identifier matches
4. The first pool in the configured order whose `match_when` predicate matches
5. The workspace default pool

An exact pool or model name takes precedence over conditional routing. When the requested name does not match directly, a `match_when` condition can select a pool based on the request or verified identity (for example `prompt_tokens.gt`). The full `match_when` dialect is on the [Pools](/reference/resources/model-pools#pool-resolution) reference. You can set a condition when you [create a pool](#create-pool), [change it later](#change-request-routing), and [move the pool](#move-pool) to control evaluation order.

### Response caching

Pool records store a cache TTL and cache scope for reusing responses to identical requests.

<Warning>
  The gateway does not read these settings during model dispatch. Setting `cache_ttl_secs` or `cache_scope` does not cache responses.
</Warning>

## Requirements

Before you begin:

* Authenticate to Dome and select a workspace
* Connect at least one [model](/connect/resources/models)
* Have a [Gateway](/connect/gateways) ready when you want the pool reachable

### Permissions

Pool operations require platform permissions. Each operation states its required permission inline.

| Default roles       | Permission       | Grants                                       |
| ------------------- | ---------------- | -------------------------------------------- |
| All workspace roles | `gateway.view`   | List and inspect pools                       |
| `admin`, `operator` | `gateway.manage` | Create, update, and remove pools and members |

## Create pool

Create a pool with a name that clients can put in the request's `model` field. A new pool has no members until you add them.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool create production \
      --routing-strategy priority_weighted \
      --failover-max all \
      --gateway prod-llms
    ```

    By default, the CLI uses priority-weighted routing and shares routing state across the workspace. It sets the cache TTL to `0` and allows Dome to try every eligible member after a failure.

    <Callout icon="terminal">Reference: [`dome model pool create`](/cli/connect/models#pool-create)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_create`

    ```json theme={"system"}
    {
      "name": "production",
      "routing_strategy": "priority_weighted",
      "failover_max": "all",
      "gateways": ["prod-llms"]
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_create`](/reference/mcp/models#dome_model_pool_create)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/CreateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "name": "production",
      "routing_strategy": "priority_weighted",
      "strategy_scope": "workspace"
    }
    ```

    Omit `failover_max` to let Dome try every eligible member after a failure. The endpoint returns the pool's UUID. The other management endpoints use this UUID to identify the pool. Attach the pool to a Gateway in a separate operation.

    <Callout icon="code">Reference: [`CreateLLMPool`](/api/management/create-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Create a model pool" theme={"system"}
    Create a model pool named "production" with priority-weighted routing and no failover limit. Attach it to the "prod-llms" Gateway.
    ```
  </Tab>
</Tabs>

Agents cannot call a pool until it has at least one model member and belongs to a Gateway.

## Update pool

Update a pool to change its name, description, routing strategy, conditional routing criteria, cache settings, or failover limit. Setting a different default pool and changing the order of conditional routes are separate operations.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool update production \
      --description "Production chat routing"
    ```

    Only the flags you pass change.

    <Callout icon="terminal">Reference: [`dome model pool update`](/cli/connect/models#pool-update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_update`

    ```json theme={"system"}
    {
      "name": "production",
      "description": "Production chat routing"
    }
    ```

    Only the parameters you send change.

    <Callout icon="cpu">Reference: [`dome_model_pool_update`](/reference/mcp/models#dome_model_pool_update)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "description": "Production chat routing"
    }
    ```

    Omitted fields keep their stored values. An empty description does not clear the existing description. To clear `match_when`, set `match_when_provided` to `true`. To set the cache TTL to `0`, set `cache_ttl_secs_provided` to `true`. To let Dome retry every eligible member, set `failover_max_clear` to `true`.

    <Callout icon="code">Reference: [`UpdateLLMPool`](/api/management/update-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Update a model pool" theme={"system"}
    Change the description of "production" to "Production chat routing". Keep its members and routing configuration unchanged.
    ```
  </Tab>
</Tabs>

### Change routing

You can change how the pool selects its primary member. Refer to [Routing strategies](#routing-strategies) for when to use each strategy. When switching away from priority-weighted routing, existing priorities and weights remain stored but no longer affect selection.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool update production \
      --routing-strategy round_robin \
      --strategy-scope caller
    ```

    <Callout icon="terminal">Reference: [`dome model pool update`](/cli/connect/models#pool-update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_update`

    ```json theme={"system"}
    {
      "name": "production",
      "routing_strategy": "round_robin",
      "strategy_scope": "caller"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_update`](/reference/mcp/models#dome_model_pool_update)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "routing_strategy": "round_robin",
      "strategy_scope": "caller"
    }
    ```

    <Callout icon="code">Reference: [`UpdateLLMPool`](/api/management/update-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Change pool routing" theme={"system"}
    Change "production" to caller-scoped round-robin routing.
    ```
  </Tab>
</Tabs>

### Change request routing

You can replace the conditions that select this pool during conditional routing. Send an empty `match_when` object to remove those conditions.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool update long-context \
      --match-when '{"prompt_tokens":{"gt":50000}}'
    ```

    <Callout icon="terminal">Reference: [`dome model pool update`](/cli/connect/models#pool-update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_update`

    ```json theme={"system"}
    {
      "name": "long-context",
      "match_when": {
        "prompt_tokens": {
          "gt": 50000
        }
      }
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_update`](/reference/mcp/models#dome_model_pool_update)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "match_when": {
        "prompt_tokens": {
          "gt": 50000
        }
      },
      "match_when_provided": true
    }
    ```

    <Callout icon="code">Reference: [`UpdateLLMPool`](/api/management/update-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Change conditional routing" theme={"system"}
    Route prompts over 50,000 tokens through the "long-context" pool.
    ```
  </Tab>
</Tabs>

### Change failover

You can change how many additional members Dome may try after the primary fails. Refer to [Failover](#failover) for limit values and streaming behavior. After setting a numeric limit, you can use the API to let Dome try every eligible member again.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool update production \
      --failover-max 2
    ```

    <Callout icon="terminal">Reference: [`dome model pool update`](/cli/connect/models#pool-update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_update`

    ```json theme={"system"}
    {
      "name": "production",
      "failover_max": "2"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_update`](/reference/mcp/models#dome_model_pool_update)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "failover_max": 2
    }
    ```

    To let Dome try every eligible member, send a separate update with `failover_max_clear`.

    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "failover_max_clear": true
    }
    ```

    <Callout icon="code">Reference: [`UpdateLLMPool`](/api/management/update-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Change pool failover" theme={"system"}
    Allow the "production" pool to retry up to two additional models.
    ```
  </Tab>
</Tabs>

## Get pool

Retrieve a pool with its routing configuration and members. Check this information before an update or when you need to determine which models can serve requests to the pool.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool get production
    ```

    <Callout icon="terminal">Reference: [`dome model pool get`](/cli/connect/models#pool-get)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_get`

    ```json theme={"system"}
    {
      "name": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_get`](/reference/mcp/models#dome_model_pool_get)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/GetLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}"
    }
    ```

    The API returns the pool and its members.

    <Callout icon="code">Reference: [`GetLLMPool`](/api/management/get-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Get a model pool" theme={"system"}
    Get the "production" pool with its routing configuration and members.
    ```
  </Tab>
</Tabs>

## List pools

Retrieve the pools in a workspace with their routing strategies, conditional routing criteria, and default status. Use the list to find a pool to inspect, reorder, update, or remove.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool list
    ```

    <Callout icon="terminal">Reference: [`dome model pool list`](/cli/connect/models#pool-list)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_list`

    ```json theme={"system"}
    {}
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_list`](/reference/mcp/models#dome_model_pool_list)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/ListLLMPools
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`ListLLMPools`](/api/management/list-llm-pools)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="List model pools" theme={"system"}
    List the model pools in this workspace with their routing strategy, predicate, and default state.
    ```
  </Tab>
</Tabs>

## Set default pool

Set a pool as the workspace default. Dome uses the default only when a request does not match an exact model name, exact pool name, or conditional route. Setting a new default removes the previous default.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool set-default production
    ```

    <Callout icon="terminal">Reference: [`dome model pool set-default`](/cli/connect/models#pool-set-default)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_set_default`

    ```json theme={"system"}
    {
      "name": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_set_default`](/reference/mcp/models#dome_model_pool_set_default)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/SetDefaultLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}"
    }
    ```

    Send an empty `pool_id` to clear the default without setting another pool.

    <Callout icon="code">Reference: [`SetDefaultLLMPool`](/api/management/set-default-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Set the default model pool" theme={"system"}
    Set "production" as the default model pool for this workspace.
    ```
  </Tab>
</Tabs>

## Move pool

Move a conditional pool earlier or later in the order Dome checks `match_when` predicates. This order affects only conditional routing and does not change routes that use an exact model or pool name.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool move long-context \
      --before production
    ```

    Pass exactly one of `--before` or `--after`.

    <Callout icon="terminal">Reference: [`dome model pool move`](/cli/connect/models#pool-move)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_move`

    ```json theme={"system"}
    {
      "name": "long-context",
      "before": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_move`](/reference/mcp/models#dome_model_pool_move)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Move a conditional pool" theme={"system"}
    Evaluate "long-context" immediately before "production".
    ```
  </Tab>
</Tabs>

## Manage members

Pool members are the model connections that Dome can select to serve requests to the pool.

### Add member

Add a model to a pool. For a priority-weighted pool, priority defaults to `0` and weight defaults to `1`. Round-robin and least-loaded pools reject explicit priority or weight values.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool member add production claude-prod \
      --priority 0 \
      --weight 4
    ```

    Run a separate command for each model because each member can have a different priority and weight.

    <Callout icon="terminal">Reference: [`dome model pool member add`](/cli/connect/models#pool-member-add)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_member_add`

    ```json theme={"system"}
    {
      "pool": "production",
      "connection": "claude-prod",
      "priority": 0,
      "weight": 4
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_member_add`](/reference/mcp/models#dome_model_pool_member_add)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/CreateLLMPoolMember
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "llm_model_connection_id": "{{CONNECTION_ID}}",
      "priority": 0,
      "weight": 4,
      "enabled": true
    }
    ```

    <Callout icon="code">Reference: [`CreateLLMPoolMember`](/api/management/create-llm-pool-member)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Add a pool member" theme={"system"}
    Add "claude-prod" to "production" at priority zero with weight four.
    ```
  </Tab>
</Tabs>

### List members

Retrieve the models in a pool with each member's priority, weight, and stored `enabled` value.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool member list production
    ```

    <Callout icon="terminal">Reference: [`dome model pool member list`](/cli/connect/models#pool-member-list)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_member_list`

    ```json theme={"system"}
    {
      "pool": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_member_list`](/reference/mcp/models#dome_model_pool_member_list)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/ListLLMPoolMembers
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`ListLLMPoolMembers`](/api/management/list-llm-pool-members)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="List pool members" theme={"system"}
    List the members of "production" with their priority and weight.
    ```
  </Tab>
</Tabs>

### Update member

Update the priority or weight of a member in a priority-weighted pool. To move a model to another pool, remove it from the current pool and add it to the destination pool.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool member update production claude-prod \
      --priority 1 \
      --weight 1
    ```

    <Callout icon="terminal">Reference: [`dome model pool member update`](/cli/connect/models#pool-member-update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_member_update`

    ```json theme={"system"}
    {
      "pool": "production",
      "connection": "claude-prod",
      "priority": 1,
      "weight": 1
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_member_update`](/reference/mcp/models#dome_model_pool_member_update)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/UpdateLLMPoolMember
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "member_id": "{{MEMBER_ID}}",
      "priority": 1,
      "weight": 1
    }
    ```

    <Callout icon="code">Reference: [`UpdateLLMPoolMember`](/api/management/update-llm-pool-member)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Update a pool member" theme={"system"}
    Change "claude-prod" in "production" to priority one and weight one.
    ```
  </Tab>
</Tabs>

### Remove member

Remove a model from a pool to stop the pool from sending requests to that model. Removing the member does not delete the model connection, so other pools and direct Gateway routes can still use it.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool member rm production claude-prod
    ```

    <Callout icon="terminal">Reference: [`dome model pool member rm`](/cli/connect/models#pool-member-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_member_remove`

    ```json theme={"system"}
    {
      "pool": "production",
      "connection": "claude-prod"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_member_remove`](/reference/mcp/models#dome_model_pool_member_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/DeleteLLMPoolMember
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}",
      "member_id": "{{MEMBER_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`DeleteLLMPoolMember`](/api/management/delete-llm-pool-member)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a pool member" theme={"system"}
    Remove "claude-prod" from "production" without deleting the model.
    ```
  </Tab>
</Tabs>

## Remove pool

Remove a pool to delete its routing configuration and memberships. Removing the pool does not delete its model connections.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Warning>
  Removing a pool also removes it from every Gateway. Requests that use the deleted pool name fail unless a conditional route or the workspace default selects another pool.
</Warning>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool rm production
    ```

    <Callout icon="terminal">Reference: [`dome model pool rm`](/cli/connect/models#pool-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_model_pool_remove`

    ```json theme={"system"}
    {
      "name": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_model_pool_remove`](/reference/mcp/models#dome_model_pool_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/DeleteLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "pool_id": "{{POOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`DeleteLLMPool`](/api/management/delete-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a model pool" theme={"system"}
    Remove the "production" pool after confirming no clients still use its name.
    ```
  </Tab>
</Tabs>

## Attach to a Gateway

Attach a pool to a Gateway so agents can request the pool by name at that gateway's model endpoints. The attachment makes the pool reachable but does not authorize an agent to call it. The agent must allow the Gateway, and rules must permit both the pool and selected model.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome model pool gateways add production prod-llms
    ```

    <Callout icon="terminal">Reference: [`dome model pool gateways add`](/cli/connect/models#pool-gateways)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_model_pool_add`

    ```json theme={"system"}
    {
      "gateway": "prod-llms",
      "pool": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_model_pool_add`](/reference/mcp/gateway#dome_gateway_model_pool_add)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Publish a model pool" theme={"system"}
    Add the "production" model pool to the "prod-llms" Gateway.
    ```
  </Tab>
</Tabs>

### Verify pool

Call the pool through the Gateway with an agent API key. A successful response confirms the pool is reachable, rules permit the route, and at least one member can serve the request.

```python title="OpenAI-compatible client" theme={"system"}
from openai import OpenAI

client = OpenAI(
    api_key="{{DOME_AGENT_KEY}}",
    base_url="https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}/v1",
)

response = client.chat.completions.create(
    model="production",
    messages=[{"role": "user", "content": "Return OK."}],
)
```

If Dome cannot find the pool for the request, check the pool's Gateway membership and model members. If Dome denies the request, check the agent's allowed resources and rules. Audit events record which model served the request and whether Dome attempted failover.

## Next steps

* [Pools](/concepts/resources/model-pools) concept for how routing and failover work and [Pools](/reference/resources/model-pools) reference for strategies and `match_when`
* [Connect more models](/connect/resources/models) to add providers or failover capacity
* Manage membership and grants in [Gateways](/connect/gateways)
* Configure model and pool spend limits in [Cost Quotas](/govern/quotas)
