# Servers

## Server Model

### Fields

- **`object`** `"server"`

- **`id`** `string`

- **`project_id`** `string`

- **`project_name`** `string`

   Display name of that project.

- **`team_id`** `string`

- **`name`** `string | null`

   Generated friendly name, for example `swift-hawk`.

- **`sku`** `string`

   The server's size, as a named bundle of CPU and memory, for example `v1-1cpu-2gb`.

- **`status`** [`ServerStatus`](/api/servers#server-status)

   Lifecycle state: `provisioning` until the server first comes up, then `active`. A paused
   free-trial server is `draining` while it finishes the data it accepted, then `idle`. A server
   removed by scaling down is `terminating` until it has finished that data and been deleted.

- **`provisioning_phase`** [`ServerProvisioningPhase | null`](/api/servers#server-provisioning-phase)

   Why provisioning is still in flight (e.g. "awaiting_capacity"); null once active.

- **`ordinal`** `number`

   The server's stable position in the project's fleet, starting at 0.

- **`created_at`** [`ISODateString`](/api/servers#iso-date-string)

- **`updated_at`** [`ISODateString`](/api/servers#iso-date-string)

- **`heartbeat_at`** [`ISODateString | null`](/api/servers#iso-date-string)

   When the server last reported its vitals. Servers report every 30 seconds; null means it has
   never reported.

- **`cpu_percent`** `number`

   CPU usage the server last reported, from 0 to 100. Zero until the first report.

- **`memory_percent`** `number`

   Memory usage the server last reported, from 0 to 100. Zero until the first report.

- **`spool_percent`** `number | null`

   Actual PVC fullness 0-100, derived as max(bytes, inodes), or null before the first heartbeat.

- **`spool_bytes_percent`** `number | null`

   Actual PVC byte fullness 0-100, or null before the first heartbeat.

- **`spool_inodes_percent`** `number | null`

   Actual PVC inode (file-count) fullness 0-100, or null before the first heartbeat.

### Referenced Types

#### ISODateString

`ISODateString`

An ISO 8601 date-time string returned at the JSON API boundary.

#### ServerStatus

`"provisioning" | "active" | "upgrading" | "draining" | "idle" | "terminating"`

#### ServerProvisioningPhase

`"allocating" | "awaiting_capacity" | "attaching_storage" | "pulling_image" | "starting"`

## Server Event Model

### Fields

- **`object`** `"server_rollout_event"`

- **`id`** `string`

- **`project_id`** `string`

- **`started_at`** [`ISODateString`](/api/servers#iso-date-string)

   When the deploy of the project's servers began.

- **`completed_at`** [`ISODateString | null`](/api/servers#iso-date-string)

   When the deploy finished; null while it is still in progress.

- **`image_tag`** `string | null`

   Version tag the deploy moves the project's servers to.

- **`phase`** `string | null`

   The most recent step the deploy reached; null before the first step is recorded.

### Referenced Types

#### ISODateString

`ISODateString`

An ISO 8601 date-time string returned at the JSON API boundary.

## List Servers

### Endpoint

Retrieve a list of servers in a project.

```http
GET /v1/projects/:project_id/servers
```

**Scope:** `servers:read`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

### Query Parameters

- **`order_by`** `string`
  Field used to order the servers. Optional. Defaults to `"created_at"`. Allowed values: `"created_at"`, `"status"`.

- **`status`** [`ServerStatus`](/api/servers#server-status)
  Filter by server status. Optional.

- **`limit`** `number`
  Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.

- **`after`** `string`
  Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.

- **`before`** `string`
  Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.

- **`sort`** `string`
  Sort direction for the result set. Optional. Defaults to `"desc"`. Allowed values: `"asc"`, `"desc"`.

### Response

```ts
{
  message: string;
  data: Server[];
  status: 200;
  error: null;
  pagination: Pagination;
  endpoint: string;
}
```

### Comments

- A server is a dedicated machine that receives and processes the project's data. Every project runs its own fleet.
- A server that is still coming up is returned with a status of `provisioning`, and a server on its way out with a status of `terminating`.
- `after` and `before` are mutually exclusive.

## Retrieve Server

### Endpoint

Retrieve a single server.

```http
GET /v1/projects/:project_id/servers/:server_id
```

**Scope:** `servers:read`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

- **`server_id`** `string` -- **Required**
  Unique identifier of the server.

### Response

Server retrieved

```ts
{
  message: string;
  data: Server;
  status: 200;
  error: null;
  pagination: null;
  endpoint: string;
}
```

## Scale Servers

### Endpoint

Scale a project's fleet to a desired total number of servers.

```http
POST /v1/projects/:project_id/servers
```

**Scope:** `servers:write`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

### Request Body

- **`count`** `integer` -- **Required**
  Total number of servers the project should run after this request. This is the desired total, not the number of servers to add or remove. The maximum is the team's per-project server limit, which is set by its plan. Minimum: `0`.

### Response 200

```ts
{
  message: string;
  data: Server[];
  status: 200;
  error: null;
  pagination: Pagination;
  endpoint: string;
}
```

### Response 202

```ts
{
  message: string;
  data: Server[];
  status: 202;
  error: null;
  pagination: Pagination;
  endpoint: string;
}
```

### Comments

- `count` is the total number of servers the project should end up running, not the number to add. A project already running two servers reaches three by sending `count: 3`.
- Scaling down is the same call with a lower `count`, and `count: 0` takes the whole fleet down. Tailglow chooses which servers to retire and drains them first, so they stay in the response with a status of `terminating` until they finish.
- There is no endpoint that deletes an individual server. Removing capacity is always a scale request with a lower `count`.
- Scaling up requires the team to have a payment method, and `count` must stay within the team's per-project server limit.
- The response is the project's whole fleet after the request, not only the servers that changed.
- Requesting the count the project already runs, with nothing in flight, returns a `409`.
- During a platform update, a scale request is queued and answered with a `202`; it is applied once the update finishes, and the project's `queued_server_count` shows it meanwhile. A project that has no servers yet still gets its first server immediately.
- Adding servers to a project that has not finished moving to the current platform version is queued the same way, even with no update in progress. Removing servers is not held back by it.
- Requesting the count the project currently runs while a change is queued cancels the queued change, or returns a `409` if that change has already started. A newer request replaces an older queued one.

## Update Server

### Endpoint

Rename a server.

```http
POST /v1/projects/:project_id/servers/:server_id
```

**Scope:** `servers:write`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

- **`server_id`** `string` -- **Required**
  Unique identifier of the server.

### Request Body

- **`name`** `string` -- **Required**
  Display name for the server. Minimum length: `1`. Maximum length: `64`.

### Response

Server updated

```ts
{
  message: string;
  data: Server;
  status: 200;
  error: null;
  pagination: null;
  endpoint: string;
}
```

### Comments

- `name` is the only editable field on a server. It is a display label and does not change how data is routed or how much capacity the server has.
- Renaming never adds or removes servers. Use `POST /v1/projects/:project_id/servers` to change how many servers the project runs.

## Retrieve Server Vitals

### Endpoint

Retrieve CPU, memory, and buffer usage for a server over a time range.

```http
GET /v1/projects/:project_id/servers/:server_id/vitals
```

**Scope:** `servers:read`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

- **`server_id`** `string` -- **Required**
  Unique identifier of the server.

### Query Parameters

- **`start_at`** [`ISODateString`](/api/servers#iso-date-string)
  Start time (ISO format, default: 12 hours ago). Optional.

- **`end_at`** [`ISODateString`](/api/servers#iso-date-string)
  End time (ISO format, default: now). Optional.

- **`interval`** `string`
  Aggregation interval. Optional. Defaults to `"minute"`. Allowed values: `"minute"`, `"hour"`.

### Response

Vitals retrieved

```ts
{
  message: string;
  data: TimeseriesAggregation;
  status: 200;
  error: null;
  pagination: null;
  endpoint: string;
}
```

### Comments

- The response carries Worker CPU, Worker Memory, Buffer, Bytes, and Inodes series, plus ingress CPU and memory when available, bucketed by `interval`.
- Older points come from archived data and recent points come from the running server, stitched into one continuous timeline. A server replaced by a platform deploy does not break the series.
- Without `start_at` and `end_at` the range is the last 12 hours.

## Retrieve Server Pipeline

### Endpoint

Retrieve queue depth, throughput, and error counts for a server over a time range.

```http
GET /v1/projects/:project_id/servers/:server_id/pipeline
```

**Scope:** `servers:read`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

- **`server_id`** `string` -- **Required**
  Unique identifier of the server.

### Query Parameters

- **`start_at`** [`ISODateString`](/api/servers#iso-date-string)
  Start time (ISO format, default: 12 hours ago). Optional.

- **`end_at`** [`ISODateString`](/api/servers#iso-date-string)
  End time (ISO format, default: now). Optional.

- **`interval`** `string`
  Aggregation interval. Optional. Defaults to `"minute"`. Allowed values: `"minute"`, `"hour"`.

### Response

Pipeline retrieved

```ts
{
  message: string;
  data: TimeseriesAggregation;
  status: 200;
  error: null;
  pagination: null;
  endpoint: string;
}
```

### Comments

- Pending averages valid queued records, Throughput counts drained records, and Errors counts rejected requests and dropped frames. Older pending history without record counts is unknown.
- Takes the same range and interval parameters as the vitals endpoint, so the two can be read over the same window.
- Without `start_at` and `end_at` the range is the last 12 hours.

## List Server Events

### Endpoint

Retrieve the platform events recorded for a server's project over a time range.

```http
GET /v1/projects/:project_id/servers/:server_id/events
```

**Scope:** `servers:read`

### Path Parameters

- **`project_id`** `string` -- **Required**
  Unique identifier of the project.

- **`server_id`** `string` -- **Required**
  Unique identifier of the server.

### Query Parameters

- **`start_at`** [`ISODateString`](/api/servers#iso-date-string) -- **Required**
  Earliest event date and time to return (ISO format).

- **`end_at`** [`ISODateString`](/api/servers#iso-date-string) -- **Required**
  Latest event date and time to return (ISO format).

- **`type`** `string`
  Filter by event type. Optional. Allowed values: `"rollout"`.

- **`limit`** `number`
  Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.

- **`after`** `string`
  Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.

- **`before`** `string`
  Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.

- **`sort`** `string`
  Sort direction for the result set. Optional. Defaults to `"desc"`. Allowed values: `"asc"`, `"desc"`.

### Response

```ts
{
  message: string;
  data: ServerRolloutEvent[];
  status: 200;
  error: null;
  pagination: Pagination;
  endpoint: string;
}
```

### Comments

- An event is a Tailglow deploy of the project's servers. Requesting events over the same window as the vitals and pipeline endpoints shows whether a change in those charts lines up with a deploy.
- `start_at` and `end_at` are both required.
- An event whose `completed_at` is `null` is still in progress.
- Events belong to the project, so every server in the project returns the same list.
- `after` and `before` are mutually exclusive.

