---
title: "Reserve ports."
method: POST
path: "/api/ports/reservations"
tags: ["ports"]
---

# Reserve ports.

`POST /api/ports/reservations`

## Request

- The document declares no server URL.
- Auth: none declared

Reserves ports for `owner_id` until `ttl_secs` after the last request or renewal. The call is idempotent per owner: an owner that already holds a reservation gets it back, renewed, with a 200 instead of a 201, and its existing ports are never moved. A `count` larger than it holds adds ports, preferring ones that continue the block it already has; equal or smaller changes nothing but the expiry, since ports are given back by deleting the reservation rather than by shrinking it. `ports` is an explicit list and callers must not assume it is contiguous.

## Request body

- CreateReservationRequest: Ask for ports.
  - `count` integer, required: How many ports the owner wants to hold in total. Larger than it holds now adds ports; equal or smaller leaves them alone.
  - `owner_id` string, required: Stable name of the owner, such as a production or instance id. A repeat request under the same name renews and returns the existing reservation rather than allocating a second one.
  - `ttl_secs` integer, nullable: Lifetime in seconds. Defaults to the server's configured TTL.

## Response `200`

The owner's existing reservation, renewed

- PortReservation: Ports held by one owner. `ports` is an explicit list, ascending. Allocation prefers a contiguous run and growth prefers extending the existing one, but neither is guaranteed — a port the operator left out of the pool, one another owner holds, or one found blocked can put a hole anywhere. Callers must not assume contiguity.
  - `created_at` string, required: When the reservation was first granted (RFC 3339, UTC).
  - `expires_at` string, required: When it lapses unless renewed (RFC 3339, UTC).
  - `id` string, uuid, required: Reservation identifier, used to renew, release and assign.
  - `in_use` PortInUse[]: Which of `ports` the owner has told the pool are used by a flow.
    - `flow_id` string, uuid, required: The flow the owner says uses it.
    - `port` integer, required: The port.
  - `owner_id` string, required: The owner's stable name. One reservation per owner; asking again returns it.
  - `ports` integer[], required: The ports held, ascending.

## Other responses

- `201`: A new reservation was granted
- `400`: Invalid owner_id, count or ttl_secs
- `409`: Not enough free ports
- `500`: Reservation could not be persisted
- `503`: No port pool is configured on this server

## Changes

- **2026-09-28** `fd671a19e55a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/eyevinn/apis/strom-api/changes/api/ports/reservations/post.md)

---

[API](https://skmtc.dev/eyevinn/apis/strom-api.md) - [All operations](https://skmtc.dev/eyevinn/apis/strom-api/llms.txt) - [OpenAPI document](https://skmtc.dev/eyevinn/apis/strom-api/revisions/8cd4dbc44175?raw)
