Getting started
API conventions
The rules every Serverside.com API endpoint shares, from the base URL and naming to the response envelope, pagination and error codes.
Base URL and versions
https://api.serverside.com
Every path starts with a version segment, /v1. Requests and responses are JSON over HTTPS; send Content-Type: application/json with any request that has a body.
Names and values
The API mixes two naming styles, and which one applies depends on where the value travels:
| Where | Style | Example |
|---|---|---|
| Query parameters | snake_case | ?page_size=50&sort_column=name |
| JSON request and response fields | camelCase | "offeringId", "primaryIpv4" |
| Enum values | UPPER_SNAKE_CASE strings | "GRACEFUL_RESTART", "RAID10" |
IDs are UUIDs. Timestamps are ISO 8601 strings. IP addresses and networks travel as strings, such as "192.0.2.10" and "192.0.2.0/28".
The response envelope
Every JSON response wraps its payload in the same object:
{
"success": true,
"message": null,
"exception": null,
"code": null,
"errors": null,
"traceId": null,
"data": { },
"pagination": null
}
| Field | Meaning |
|---|---|
success | true when the request did what it asked. |
data | The payload: an object, an array for list endpoints, or absent. |
pagination | Page details on list endpoints (Pagination), null on the rest. |
code | A machine-readable error code when success is false. |
message | Human-readable text. On most errors it is a generic sentence; branch on code and the HTTP status instead. |
errors | Field-level problems, keyed by field name, each with a list of messages. |
traceId | The request's trace id on errors. Quote it when you contact support. |
exception | Always null for customer keys. |
Endpoints that answer 204 No Content send no body at all.
Pagination
List endpoints take the same query parameters:
| Parameter | Default | Notes |
|---|---|---|
page | 1 | 1-based. |
page_size | 25 | 1 to 1000. |
sort_column | none | The field to sort by. |
ascending | true | false reverses the sort. |
search | none | Free text; leading and trailing spaces are dropped. |
filter[<field>] | none | One parameter per filtered field. |
The response's pagination object carries totalRecords, currentPage, pageSize and totalPages. To read everything, request pages until currentPage equals totalPages.
curl --request GET \
--url 'https://api.serverside.com/v1/services/baremetal?page=2&page_size=100&sort_column=name' \
--header 'X-API-KEY: <api-key>'sort_column and filter[...] name the stored property, which is not always spelled like the JSON field, and a name the endpoint does not know is ignored without an error. A filter on an enum takes the value's member name, filter[status]=cancellationrequested and not CANCELLATION_REQUESTED; a value that does not parse is dropped as well, so a mistyped filter returns the whole unfiltered list with a 200. Without sort_column the order is not fixed: invoices come back sorted by currency and subscriptions in no set order, so pages can repeat or skip rows. Send sort_column on every list you page through.
Errors
The HTTP status says what kind of failure it was and code says which one:
| Status | code | Cause |
|---|---|---|
400 | VALIDATION_ERROR | The body or a parameter failed validation. errors names each field and message lists them. |
400 | VALIDATION_FAILED | The request was well formed but broke a rule of the resource, such as a firewall rule with ports on an ICMP protocol. message states the rule in a sentence; the code is the same for every rule. |
400 | an operation's own code | Some operations use a specific code, for example RDNS_A_RECORD_MISMATCH when setting reverse DNS. |
401 | none | Missing, wrong or disabled API key, or an operation that takes a console session only; see Authentication. |
403 | NO_PERMISSION_EXCEPTION | The key lacks the permission the endpoint checks. |
403 | SERVICE_NOT_AVAILABLE | The server is locked or suspended, or its management controller is resetting. This response does not use the envelope. |
404 | ENTITY_NOT_FOUND | No resource has that id. |
409 | ENTITY_ALREADY_EXISTS | Another resource already holds the value, a name for example. |
422 | ENTITY_STATE_INVALID | The resource cannot do this now, such as starting a deployment while another operation runs. |
422 | ARGUMENT_OUT_OF_RANGE | A value is outside what the operation accepts. |
422 | OFFERING_NOT_AVAILABLE | The plan is out of stock in that datacenter. |
422 | BILLING_CYCLE_NOT_OFFERED | The plan is not sold on the billing cycle the order asked for. |
422 | USAGE_BILLING_DISABLED | Hourly billing is not enabled for the organization (Quickstart). |
500 | UNHANDLED_EXCEPTION | Something failed on our side. Retry, and send the traceId to support if it persists. |
503 | SERVICE_UNAVAILABLE | A system behind the API did not answer. Retry after a short wait. |
A validation failure has this shape (the trace id is shortened):
{
"success": false,
"message": "Validation failed: Name: The Name field is required.",
"code": "VALIDATION_ERROR",
"errors": {
"Name": ["The Name field is required."]
},
"traceId": "0HN6...:00000002"
}
Idempotency
Five operations accept an Idempotency-Key header of up to 200 characters: creating a bare metal service, creating an IP block, creating an order, and assigning or unassigning a service on a virtual network. Send a fresh value for each new action and the same value when you retry that action.
Rate limits
The API sets no request limit per key.