Servers
Your servers: the list, one server in detail, its traffic, and renaming it. Reading needs read; renaming needs manage.
List servers
GET /servers returns the account's servers, newest first. Cancelled and terminated servers are not listed.
| Query parameter | Meaning |
|---|---|
limit | 1 to 100. Default 50. |
cursor | The next_cursor of the previous page, such as srv_120. |
curl -sS "https://api.redswitches.com/v1/servers?limit=2" \
-H "Authorization: Bearer $REDSWITCHES_API_KEY"let cursor: string | undefined;
do {
const page = await rs.servers.list({ limit: 100, cursor });
for (const s of page.data) console.log(s.id, s.status, s.primary_ip);
cursor = page.next_cursor ?? undefined;
} while (cursor);cursor = None
while True:
page = client.servers.list(limit=100, cursor=cursor)
for s in page.data:
print(s.id, s.status, s.primary_ip)
cursor = page.next_cursor
if not cursor:
breakopts := &redswitches.ListOptions{Limit: 100}
for {
page, err := client.Servers.List(ctx, opts)
if err != nil {
log.Fatal(err)
}
for _, s := range page.Data {
fmt.Println(s.ID, s.Status, s.PrimaryIP)
}
if page.NextCursor == nil {
break
}
opts.Cursor = *page.NextCursor
}{
"data": [
{
"id": "srv_123",
"label": "web-1",
"product": "Instant Dedicated Server E-2388G",
"location": { "city": "Amsterdam", "country": "NL" },
"status": "active",
"primary_ip": "203.0.113.10",
"billing_cycle": "monthly",
"next_due_date": "2026-12-15",
"recurring_amount": "129.00",
"currency": "USD",
"created": "2026-11-15"
},
{
"id": "srv_121",
"label": null,
"product": "Dedicated Server 2x Xeon Gold 6230",
"location": { "city": "New York", "country": "US" },
"status": "suspended",
"primary_ip": "203.0.113.24",
"billing_cycle": "annually",
"next_due_date": "2027-03-01",
"recurring_amount": "2280.00",
"currency": "USD",
"created": "2026-03-01"
}
],
"next_cursor": "srv_121"
}
next_cursor is the id of the last server on the page, or null when there are no more. A cursor of the wrong kind (not srv_…) is 400 invalid_parameter.
| Field | Type | Meaning |
|---|---|---|
id | string | srv_<n>. |
label | string or null | Your own name for the server. |
product | string | The plan name. |
location | object or null | city and country (two-letter code or null). |
status | string | pending, active or suspended. |
primary_ip | string or null | The main IP address. |
billing_cycle | string or null | monthly, quarterly, semiannually, annually, biennially, triennially, one_time or free. |
next_due_date | string or null | The next renewal date (YYYY-MM-DD). |
recurring_amount | string | The renewal price as a decimal string. |
currency | string | The account's currency. |
created | string or null | The date the server was ordered (YYYY-MM-DD). |
Passwords, management (IPMI) details and staff notes never appear in the API.
Get a server
GET /servers/{id} returns the list fields plus the server's IP addresses, operating system, hardware and delivery state.
curl -sS https://api.redswitches.com/v1/servers/srv_123 \
-H "Authorization: Bearer $REDSWITCHES_API_KEY"const server = await rs.servers.get("srv_123");
if (server.ips !== "unavailable") {
for (const a of server.ips.addresses) console.log(a.ip, a.primary);
}server = client.servers.get("srv_123")
if server.ips != "unavailable":
for a in server.ips.addresses:
print(a.ip, a.primary)server, err := client.Servers.Get(ctx, "srv_123")
if err != nil {
log.Fatal(err)
}
fmt.Println(server.Status, server.Delivery){
"id": "srv_123",
"label": "web-1",
"product": "Instant Dedicated Server E-2388G",
"location": { "city": "Amsterdam", "country": "NL" },
"status": "active",
"primary_ip": "203.0.113.10",
"billing_cycle": "monthly",
"next_due_date": "2026-12-15",
"recurring_amount": "129.00",
"currency": "USD",
"created": "2026-11-15",
"ips": {
"as_of": "2026-11-15T09:20:00Z",
"addresses": [
{ "ip": "203.0.113.10", "primary": true },
{ "ip": "2001:db8::10", "primary": false }
]
},
"os": {
"ordered": "Ubuntu 24.04",
"installed": { "as_of": "2026-11-15T09:20:00Z", "name": "Ubuntu 24.04", "installing": false }
},
"hardware": {
"as_of": "2026-11-15T09:20:00Z",
"cpu": "Intel Xeon E-2388G",
"ram": "64 GB",
"disks": "2 x 960 GB NVMe"
},
"delivery": "ready",
"rescue": false
}
The extra blocks are collected from the server on a schedule, never live during your request. Each block carries its own as_of. When nothing current is known, the block is the string "unavailable", never an empty list or zero:
{ "ips": "unavailable", "hardware": "unavailable", "os": { "ordered": "Debian 12", "installed": "unavailable" } }
| Field | Type | Meaning |
|---|---|---|
ips | object or "unavailable" | as_of and addresses: each ip and whether it is the primary. |
os.ordered | string or null | The OS chosen when the server was ordered. |
os.installed | object or "unavailable" | as_of, name (string or null) of what the server reports, and installing (true while an install runs). |
hardware | object or "unavailable" | as_of, cpu, ram, disks as text (each may be null). |
delivery | string or null | For instant servers: awaiting_payment, assigning, installing, ready, attention or closed. Null for other servers. |
rescue | boolean | true while the server is in rescue mode (false when not known). See Rescue. |
A server that does not exist and a server of another account give the same 404 not_found.
Traffic
GET /servers/{id}/traffic returns data used in the current period and the allowance.
curl -sS https://api.redswitches.com/v1/servers/srv_123/traffic \
-H "Authorization: Bearer $REDSWITCHES_API_KEY"const t = await rs.servers.traffic("srv_123");
if (t.used_bytes !== "unavailable" && t.allowance_bytes) {
console.log(`${((t.used_bytes / t.allowance_bytes) * 100).toFixed(1)}% used`);
}t = client.servers.traffic("srv_123")
if t.used_bytes != "unavailable" and t.allowance_bytes:
print(f"{t.used_bytes / t.allowance_bytes:.1%} used")t, err := client.Servers.Traffic(ctx, "srv_123")
if err != nil {
log.Fatal(err)
}
fmt.Println(t.UsedBytes, t.AllowanceBytes, t.Unmetered){
"id": "srv_123",
"used_bytes": 1840000000000,
"unavailable_reason": null,
"period_start": "2026-10-16T00:00:00Z",
"period_end": "2026-11-15T00:00:00Z",
"basis": "last_30_days",
"as_of": "2026-11-15T09:00:00Z",
"allowance_bytes": 50000000000000,
"unmetered": false
}
| Field | Type | Meaning |
|---|---|---|
used_bytes | integer or "unavailable" | Bytes used in the period. |
unavailable_reason | string or null | When used_bytes is unavailable: not_collected (no current figure) or ownership_changed_in_window (the measured period started before you held the server, so it would include someone else's use). |
period_start, period_end | string or null | The measured period (UTC). Null when unavailable. |
basis | string or null | billing_period (the server's billing month) or last_30_days (a rolling 30-day total). Which one depends on the server's network. |
as_of | string or null | When the figure was collected. |
allowance_bytes | integer or null | The traffic included in the plan. Null when unmetered or unknown. |
unmetered | boolean | True when traffic is not metered. |
When unavailable, the answer looks like this:
{
"id": "srv_123",
"used_bytes": "unavailable",
"unavailable_reason": "ownership_changed_in_window",
"period_start": null,
"period_end": null,
"basis": null,
"as_of": null,
"allowance_bytes": 50000000000000,
"unmetered": false
}
When the period started before you held the server, traffic is counted from the moment you took it over, with basis: "since_ownership", wherever a starting figure was recorded. Only where none exists does it stay unavailable. Another customer's use is never shown.
Rename a server
POST /servers/{id}/label sets your own name for a server. Needs manage and an Idempotency-Key. The label is only a name in the client area and the API; it does not change the server's hostname.
| Body field | Rule |
|---|---|
label | Up to 60 characters: letters, digits, spaces, ., -, _. Runs of spaces become one. Control characters are refused. "" clears the label. |
curl -sS -X POST https://api.redswitches.com/v1/servers/srv_123/label \
-H "Authorization: Bearer $REDSWITCHES_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"label":"web-1"}'await rs.servers.setLabel("srv_123", { label: "web-1" });client.servers.set_label("srv_123", label="web-1")_, err := client.Servers.SetLabel(ctx, "srv_123", &redswitches.LabelRequest{Label: "web-1"}){ "id": "srv_123", "label": "web-1" }
After clearing, label is null. Errors: 400 invalid_body (bad label), 404 not_found.