---
title: "POST /v1/pools"
method: POST
path: "/v1/pools"
tags: ["pools"]
---

# POST /v1/pools

`POST /v1/pools`

## Request body

- union
  - object
    - `gpus` object, required
    - `bundle` string, nullable
    - `gpu_caps` object
    - `minimum_worker_count` integer — Per-pool warm floor (minimum machines kept warm via KEDA). Default 0 keeps scale-from-zero. See `PoolSpec::minimum_worker_count`.
    - `name` string, required — Pool name used in gpu="pool/machine_profile" routing. Names are stored and routed in lowercase. Only ASCII letters, digits, '_' and '-' are allowed; '_default' is reserved.
    - `pinned_models` string[] — Per-pool pinned-model set. Each id is validated against the models the gateway already tracks and stored canonicalized; ids may be profile-qualified (`model-name:profile_name`). Default empty leaves lazy-loading unchanged. See `PoolSpec::pinned_models`.
    - `queue_pool` string, nullable — Physical Helm/NATS queue namespace to draw workers from. Omit for normal dynamic logical pools; they use `default`. Set only to an operator-provisioned Helm queue pool declared under `queueRouting.staticQueuePools` for dedicated capacity.
    - `ttl_seconds` integer, nullable
  - object
    - `gpu_caps` object, required
    - `bundle` string, nullable
    - `gpus` object
    - `minimum_worker_count` integer — Per-pool warm floor (minimum machines kept warm via KEDA). Default 0 keeps scale-from-zero. See `PoolSpec::minimum_worker_count`.
    - `name` string, required — Pool name used in gpu="pool/machine_profile" routing. Names are stored and routed in lowercase. Only ASCII letters, digits, '_' and '-' are allowed; '_default' is reserved.
    - `pinned_models` string[] — Per-pool pinned-model set. Each id is validated against the models the gateway already tracks and stored canonicalized; ids may be profile-qualified (`model-name:profile_name`). Default empty leaves lazy-loading unchanged. See `PoolSpec::pinned_models`.
    - `queue_pool` string, nullable — Physical Helm/NATS queue namespace to draw workers from. Omit for normal dynamic logical pools; they use `default`. Set only to an operator-provisioned Helm queue pool declared under `queueRouting.staticQueuePools` for dedicated capacity.
    - `ttl_seconds` integer, nullable

## Response `201`

Pool created, renewed, or updated

- Pool
  - `spec` PoolSpec, required
    - `bundle` string, nullable
    - `gpu_caps` object
    - `gpus` object
    - `minimum_worker_count` integer — Per-pool warm floor: the minimum number of machines the gateway keeps warm (via KEDA) so the first request to the pool never hits a cold VM. The gateway publishes it as `sie.gateway.pool.warm_floor`; the collector translates it for KEDA's Prometheus query. Default 0 leaves scale-from-zero unchanged.
    - `name` string, required
    - `pinned_models` string[] — Per-pool pinned-model set: models the gateway keeps loaded so the first request to them pays no cold model-load. Chosen from the models the gateway already tracks (see `GET /v1/configs/models`); ids may be profile-qualified (`model-name:profile_name`). Default empty leaves lazy-loading unchanged.
    - `queue_pool` string — Physical Helm/NATS queue namespace backing this logical API pool. API-created pools default to the Helm `default` queue pool. Pool `name` is user/dynamic; a non-default `queue_pool` is infra/admin and must match a Helm worker queue declared under `queueRouting.staticQueuePools`.
    - `ttl_seconds` integer, nullable
  - `status` PoolStatus, required
    - `assigned_workers` AssignedWorker[]
      - `bundle` string
      - `gpu` string, required
      - `name` string, required
      - `url` string, required
    - `created_at` number, double
    - `last_renewed` number, double
    - `state` 'pending' | 'active' | 'expired', required

## Other responses

- `400` — Invalid pool request
- `401` — Missing or invalid bearer token (inference token)
- `403` — Valid bearer token but admin token required for this mutation (or admin token not configured)
- `500` — Gateway auth enabled but no tokens configured

## Changes

> 41 revisions in range; 2 could not be searched.

- **2026-06-23** `3bf82f56646f` — 2 info
  - added the new optional request property `queue_pool`
  - added the optional property `spec/queue_pool` to the response with the `201` status
- **2026-06-19** `d419699fe3d3` — 2 info
  - added the new optional request property `pinned_models`
  - added the optional property `spec/pinned_models` to the response with the `201` status
- **2026-06-13** `a7b0c412cdd4` — 2 breaking, 1 warning
  - the `name` request property's minLength was increased from `0` to `1`
  - added the pattern `^(?!_[dD][eE][fF][aA][uU][lL][tT]$)[A-Za-z0-9_-]+$` to the request property `name`
  - the `name` request property's maxLength was set to `128`
- **2026-06-07** `202ed23bc7dd` — 1 info
  - added the optional property `status/assigned_workers/items/bundle` to the response with the `201` status
- **2026-05-27** `d145a90eb76e` — 4 info
  - added the new optional request property `gpu_caps`
  - added `subschema #1, subschema #2` to the request body `anyOf` list
  - the request property `gpus` became optional
  - added the optional property `spec/gpu_caps` to the response with the `201` status

[Full history](https://skmtc.dev/superlinked/apis/sie-gateway/changes/v1/pools/post.md)

---

[API](https://skmtc.dev/superlinked/apis/sie-gateway.md) · [All operations](https://skmtc.dev/superlinked/apis/sie-gateway/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/superlinked/sie-gateway/revisions/78eeecd83405/schema)
