Getting started

Quickstart

Create an API key, choose a plan and a datacenter, order a bare metal server, pay its invoice and install an operating system on it through the API.

Seven requests take a new API key to a server running the operating system you picked. Each request is written out in cURL, Node.js, Python, Go, PHP, Ruby, Java, C# and PowerShell, and the language you pick on one of them applies to all the others, here and on the API reference pages.

Create an API key

In the cloud console, open your organization's settings and choose Create an API Key under Manage API Keys. The console shows the key once, when it is created, so copy it before closing the dialog.

Every request in the docs shows it as <api-key> in the Authorization: Bearer header. Put your key in its place, and the values each step returns in place of the other <...> values and {serviceId}.

Pick a plan and a datacenter

List the bare metal plans:

curl --request GET \
  --url https://api.serverside.com/v1/baremetal/plans \
  --header 'Authorization: Bearer <api-key>'

The list is paged, 25 plans to a page unless pageSize asks for more, up to 1000. Every plan in data carries its id and slug, its hardware under specs, and two fields that decide the order:

  • availability has one entry per datacenter, with the datacenter's code (such as ams1), its city and facility, and the quantity in stock there.
  • pricing gives the currency and, under rates, one entry for each billing cycle the plan is sold on. An entry's priceMillicents is the price of one period of that cycle and effectiveMonthlyMillicents the same price per month, both in thousandths of a cent (Money).

Choose a plan and a datacenter whose quantity is above zero, and keep the plan's slug and the datacenter's code. To start from a location instead, List regions names every datacenter you can order in, with its code, city and facility.

Order the server

Create an order for the plan in that datacenter, on the billing cycle you will pay by:

curl --request POST \
  --url https://api.serverside.com/v1/billing/orders \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Idempotency-Key: <idempotency-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "cycle": "MONTHLY",
  "items": [
    {
      "type": "BAREMETAL",
      "plan": "<plan-slug>",
      "datacenter": "<datacenter-code>",
      "name": "<hostname>"
    }
  ]
}
'

plan and datacenter take ids as well as the slug and the code. name is optional, 2 to 64 characters, and the deployment turns it into the operating system's hostname, so a name such as web1.example.com sets both.

cycle is required and takes HOURLY, MONTHLY, QUARTERLY, SEMI_ANNUALLY or ANNUALLY. What comes next depends on which you chose:

  • A term (MONTHLY to ANNUALLY): the order is saved with an invoice and nothing is provisioned yet. The answer is 201; keep data.order.id and data.invoiceId for the next step.
  • HOURLY: the server is provisioned within the request and no invoice is raised. data.provisionedItems[0].provisionedId is the server's id, the {serviceId} of the last two steps, so skip to choosing an operating system. Hourly billing needs billing.isUsageBased to read true on Get entitlements, which a new organization does not have; for now it is granted on request through support in the cloud console, and without it the order answers 422 USAGE_BILLING_DISABLED.

The server gets an IPv4 /30 and an IPv6 /120, both included in the plan's price; IPv6 is left off when the datacenter has no IPv6 space to give. Billing covers a larger IPv4 prefix and leaving a family out.

The Idempotency-Key header is optional. Generate one value per order and send the same value again if you retry after a timeout, so the retry returns the first order instead of placing a second one; Idempotency has the rules.

Pay the invoice

A server on a term is provisioned once its invoice is paid in full, and nothing pays an order's invoice automatically. An order left unpaid is cancelled within 24 hours. From a script, Pay invoice settles it from account credit:

curl --request POST \
  --url https://api.serverside.com/v1/billing/invoices/{invoiceId}/pay \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "providerType": "ACCOUNT_CREDIT"
}
'

The payment takes what the credit balance holds, up to the amount due, and reads status SUCCEEDED. A short balance leaves part of the invoice due and the server waits for the rest; get the invoice and read amountDue, in cents. With no credit at all the call answers 422 PAYMENT_FAILED.

providerType STRIPE with a saved card's id in methodId charges that card instead. The API lists saved cards only on the organization's settings, which take a console session, so a key has no call that finds the id. Without a methodId, STRIPE starts a payment that a browser has to confirm (Billing).

Then get the order every 20 seconds or so until its item in items reads status COMPLETED:

curl --request GET \
  --url https://api.serverside.com/v1/billing/orders/{orderId} \
  --header 'Authorization: Bearer <api-key>'

The order itself reads UNPAID until provisioning has run, then COMPLETE. The item's provisionedId is the new server's id, the {serviceId} every later call takes. An item that reads FAILED will not come up by itself: the order reads FAILED as well, and support needs the order's id to finish it.

Choose an operating system

List the images that fit the new server:

curl --request GET \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/deploy/images \
  --header 'Authorization: Bearer <api-key>'

Each image has an id, a name, a slug such as ubuntu-24.04, a platform (LINUX or WINDOWS), the defaultUser it creates and the raidVariants it supports.

Deploy it

Start the deployment. image takes the image's id or its slug, and sshKeyIds takes ids from List SSH keys.

curl --request POST \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/deploy \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "image": "<image-id>",
  "sshKeyIds": [
    "<ssh-key-id>"
  ],
  "raidVariant": "RAID1"
}
'

A Linux deployment needs a way to log in: an SSH key, a password or your own cloudInit. A Windows one needs a password. username defaults to the image's defaultUser; on Linux, username and password apply alongside the keys, and a user named there gets passwordless sudo. raidVariant defaults to NONE, and any other value must be one the image lists.

The answer is 201 with the operation that is now running, of type DEPLOYMENT. Get the service status to follow it:

curl --request GET \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/status \
  --header 'Authorization: Bearer <api-key>'

operation holds the running deployment with its progress and lastProgressMessage, and lastOperation.state reads COMPLETED or FAILED once it ends. A deployment only starts while the service's state is ACTIVE; with another operation still running, the API answers 409 and the code OPERATION_IN_PROGRESS. Once it reads COMPLETED, log in at the primaryIpv4 that Get bare metal service returns.

Where to go next

  • Deploy your first server: the same flow with an SSH key, a first-boot configuration, polling for the result and what to read when a deployment fails.
  • Managing IP addresses: extra addresses and reverse DNS for the new server.
  • Billing: billing cycles, orders, invoices, account credit and cards.
  • API conventions: naming, money units, the success and error shapes, pagination, error codes, rate limits and idempotency.