# Getting Started

:::note

This is a preview of our new OpenAPI-based API documentation. It is a work in progress and subject to change without notice, including backwards-incompatible changes.

:::

The UpCloud API lets you create and manage all of your UpCloud resources programmatically. Anything you can do in the [UpCloud Control Panel](https://hub.upcloud.com), from deploying Cloud Servers to configuring Managed Databases, Load Balancers, and networking, you can also do through the API.

The UpCloud API consists of operations used to control resources on UpCloud. The API is a web service interface. HTTPS is used to connect to the API. The API follows the principles of a RESTful web service wherever possible. The base URL for all API operations is https://api.upcloud.com/. All API operations require authentication.

## Create an account and an API token

To make API requests you need an active UpCloud account and a API token.

If you do not already have an UpCloud account, create a new account using our [signup form](https://upcloud.com/signup). New accounts come with trial credits so you can try the API right away.

To start using the API, create a new API token in the [API tokens view](https://hub.upcloud.com/account/api-tokens) of the account settings page. Save this token. The examples on this page assume that the token is available in `$UPCLOUD_TOKEN` environment variable.

## Make your first request

The fastest way to confirm everything works is to fetch your account details. This can be done, for example, by running the `curl` command below in your terminal:

```bash
curl -X GET \
  -H "Authorization: Bearer $UPCLOUD_TOKEN" \
  -H "Accept: application/json" \
  "https://api.upcloud.com/1.3/account"
```

A successful call returns `HTTP 200 OK` and a JSON object describing your account, including remaining credits. If you see `HTTP 401 Authorization Required` error, your token is missing, expired, or incorrect. See [Authentication](#authentication) below for more details.

## Getting help

We have more documentation available in [upcloud.com/docs](https://upcloud.com/docs) and you can reach our support by [email](mailto:hello@upcloud.com) or by using the chat in the [hub.upcloud.com](https://hub.upcloud.com/).

## Architecture Overview
<!-- This is copy-pasted from developers.upcloud.com, we can move this to a separate sub-page later -->

### API versioning

The API uses versioning to allow backwards incompatible modifications in the
service without affecting clients using older versions of the API.

The versioning uses an `X.Y.Z` scheme. The `X.Y` part is shown in the URL, e.g.
`https://api.upcloud.com/1.3/`.

Backwards compatible changes in the API does not require changes to
clients using the API. Such changes include but are not limited to adding or
modifying error codes and messages or adding new features. When backwards
compatible changes are made to the API, the Z version is incremented.

Small and large backwards incompatible changes increment the Y or X version
respectively. Upgrading to a backwards incompatible API version require
changing the URLs that are used to access the service.

If an invalid or inexistent API version is requested, the error code
`API_VERSION_INVALID` is returned. If an obsolete API version is requested,
the error code `API_VERSION_OBSOLETE` is returned.

### Authentication

The UpCloud API uses HTTP Bearer authentication. An [API token](../24-api-tokens) is required to authenticate
with the UpCloud API. The API token can be created in the [UpCloud control panel](https://hub.upcloud.com).
Alternatively, you can create an API token using the API directly, or with the [upctl](https://github.com/UpCloudLtd/upcloud-cli/). Note that if you want to
use HTTP Basic authentication on API or upctl, you will need to enable API access in the [UpCloud control panel](https://hub.upcloud.com) first.

```shell
$ upctl account token create --name terraform --expires-in 1h --allow-ip-range 1.2.3.4 --allow-ip-range ::/0 --allow-ip-range 2.3.4.0/24

✓ Creating token terraform

  API Token             ucat_01DQE3AJDEBFEKECFM558TGH2F
  Name                  terraform
  ID                    0c0b03be-b755-4392-8bbc-644b79ac98e5
  Created At            2025-04-04T11:11:25Z
  Expires At            2025-04-04T12:11:25Z
  Allowed IP Ranges     [1.2.3.4 ::/0 2.3.4.0/24]
  Can Create Sub Tokens false
```

HTTP Basic authentication with a username and password can also be used to
authenticate with the UpCloud API. However, use of this authentication method
is discouraged, and it will be deprecated and disabled at a later date. We
recommend using an API subaccount with HTTP Basic authentication. The
subaccount can be created in the UpCloud control panel's People-page.

#### Sample request header

```http
GET /1.3/server HTTP/1.1
Host: api.upcloud.com
Authorization: Bearer ucat_01DQE3AJDEBFEKECFM558TGH2F
```

With HTTP Basic Auth:

```http
GET /1.3/server HTTP/1.1
Host: api.upcloud.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
```

#### Normal response

If authentication succeeds, the API returns an HTTP 200 OK response.
A sample response header for a successful authentication:

```http
HTTP/1.1 200 OK
Date: Mon, 01 Jan 2012 00:00:00 GMT
Server: Apache
Content-Length: 39042
Connection: close
Content-Type: application/json; charset=UTF-8
```

#### Error response

If authentication fails, the API returns an HTTP 401 error response.
An example response for a failed authentication attempt:

```http
HTTP/1.1 401 Authorization Required
Date: Mon, 01 Jan 2012 00:00:00 GMT
Server: Apache
WWW-Authenticate: Basic, realm="API"
Content-Length: 157
Connection: close
Content-Type: application/json; Charset=UTF-8
```

```json
{
  "error": {
    "error_code": "AUTHENTICATION_FAILED",
    "error_message": "Authentication failed using the given username and password."
  }
}
```

### Resource identifiers

UpCloud resources such as servers, storages and IP addresses are all referred
to by unique identifiers. These identifiers are assigned when resources are created.
Resources are always accessible by their unique identifiers as long as they exist on UpCloud.

The unique identifiers follow the version 4 format of the Universally unique identifier (UUID) standard.

Example UUID: `00104021-153d-4b0e-a4ec-730a5556442c`.

To help differentiate between various types of resources, different types of resources have different UUID prefixes:

Resource type          | UUID prefix | UUID example
-----------------------|-------------|-------------------------------------
Server                 | 00          | 00ff2a9e-2e38-449e-8dee-7986a127d035
Storage                | 01          | 01fe1129-b1cd-48e4-a488-c51874082818
*Reserved*             | 02          | -
Network                | 03          | 033bd7ad-8baf-42a9-81d8-e20a7bf4c2aa
Router                 | 04          | 04dd26fc-4afc-47b9-83a7-13ed31af1226
Zone                   | 05          | 05dfeb76-e7ce-4fe0-bf5f-c52ee24c2358
*Reserved* (was non-managed Object Storage discontinued in 2025) | 06 | -
Storage Import         | 07          | 07d66ada-61de-421d-915c-7921849ac6ca
Network Transfer Pool  | 08          | 0808993e-2cb0-4d1e-8061-f3ae7fd8f61f
Managed Database       | 09          | 0994abdc-6265-414f-ba65-f9de8118cdf2
Managed Load Balancer  | 0a          | 0ad8df6f-ea4c-423b-bd50-722e77310376
Server Group           | 0b          | 0bf22160-0cf4-4dd0-aa75-032b9aa2c865
API token              | 0c          | 0cf91cd1-22fb-459e-a367-a611cba1a72f
Managed Kubernetes     | 0d          | 0de5a5a3-27a6-488a-b26c-cd757cb62d57
IP-Address             | 0e          | 0ebe3896-bc86-411d-a278-ca8ad5817ce4
Network Peering        | 0f          | 0f050fd2-00b1-4142-b6d8-bfc5cc4eb5c2
NAT / VPN Gateway      | 10          | 105b8033-fefc-4bb3-8761-30aed0a05103
*Reserved*             | 11          | -
Managed Object Storage | 12          | 120bff98-4e2f-4616-9208-c040a182f504
*Reserved*             | 13          | -
*Reserved*             | 14          | -
*Reserved*             | 15          | -
*Reserved*             | 16          | -
File Storage           | 17          | 17260978-379b-4487-9b7f-9236e7ac1297

### Request and response data formats

In addition to HTTP requests, many API operations include exchange of data in
the request or response body. This data is encoded either in JavaScript
Object Notation (JSON) or eXtensible Markup Language (XML).
The default encoding in JSON.

All examples in this document are in JSON format.

The data type definition is given in the HTTP request header.
The `Accept` header defines the data type for requests and the `Content-type`
header defines the data type in responses.

It is possible to send data in one format and receive in the other format.

#### A sample HTTP request header

```http
POST /1.3/server HTTP/1.1
Host: api.upcloud.com
Authorization: Basic <base64-encoded authentication string>
Accept: application/json
Content-Type: application/json
Content-Length: <length>
```

Valid data type definitions:

* application/json
* application/xml

Sample response in JSON format:

```http
HTTP/1.1 200 OK
Date: Tue, 03 Apr 2012 20:12:12 GMT
 Server: Apache
Content-Length: 713
Connection: close
Content-Type: application/json; charset=UTF-8
```

```json
{
  "servers": {
    "server": [
      {
        "core_number": "2",
        "hostname": "server1.example.com",
        "license": 0,
        "memory_amount": "4096",
        "plan": "2xCPU-4GB",
        "plan_ipv4_bytes": "345354535",
        "plan_ipv6_bytes": "53543",
        "state": "started",
        "tags": {
          "tag": []
        },
        "title": "server1",
        "uuid": "001c397f-9b24-42ce-9977-07f16a592fb3",
        "zone": "fi-hel1"
      },
      {
        "core_number": "0",
        "hostname": "server2.example.com",
        "license": 0,
        "memory_amount": "512",
        "plan": "custom",
        "state": "started",
        "tags": {
          "tag": [
            "DEV",
            "Webserver"
          ]
        },
        "title": "server2",
        "uuid": "0077fa3d-32db-4b09-9f5f-30d9e9afb316",
        "zone": "fi-hel1"
      }
    ]
  }
}
```

Sample response in XML format:

```xml
<?xml version="1.0" encoding="utf-8"?>
<servers>
  <server>
    <core_number>2</core_number>
    <hostname>server1.example.com</hostname>
    <license>0</license>
    <memory_amount>4096</memory_amount>
    <plan>2xCPU-4GB</plan>
    <plan_ipv4_bytes>345354535</plan_ipv4_bytes>
    <plan_ipv6_bytes>53543</plan_ipv6_bytes>
    <state>started</state>
    <tags>
    </tags>
    <title>server1</title>
    <uuid>001c397f-9b24-42ce-9977-07f16a592fb3</uuid>
    <zone>fi-hel1</zone>
  </server>
  <server>
    <core_number>0</core_number>
    <hostname>server2.example.com</hostname>
    <license>0</license>
    <memory_amount>512</memory_amount>
    <plan>custom</plan>
    <state>started</state>
    <tags>
      <tag>DEV</tag>
      <tag>Webserver</tag>
    </tags>
    <title>server2</title>
    <uuid>0077fa3d-32db-4b09-9f5f-30d9e9afb316</uuid>
    <zone>fi-hel1</zone>
  </server>
</servers>
```

### Response codes

API responses use regular HTTP codes to indicate successful and failed requests.

#### Successful requests

Successful requests are responded with a response code between 200 and 299.
Possible response codes are:

| HTTP status   | Description |
| ------------- | ----------- |
| 200  OK       |  The request was successful. |
| 201  Created  |  The request resulted in the generation of a new resource such as a server or a storage. |
| 202  Accepted |  The request resulted in the asynchronous creation or update of an existing resource. |

#### Failed requests

Failed requests include a machine readable error code and a human readable
error description in the response body. Invalid requests are responded with a
response code between 400 and 499. Possible response codes are:

| HTTP status            | Description |
| ---------------------- | ----------- |
| 400 Bad request        | The request has invalid, unknown or missing attributes or the request cannot be properly parsed. |
| 401 Unauthorized       | The request does not use or fails authentication. |
| 402 Payment Required   | The request cannot be processed because of insufficient credits. |
| 403 Forbidden          | The request accesses resources owned by some other user. |
| 404 Not Found          | The request accesses resources that do not exist, but may have existed before. |
| 405 Method not allowed | The request uses an invalid HTTP verb, e.g. use POST on an operation that only accepts GET. |
| 406 Not Acceptable     | The request has requirements given in the Accept headers that the API service cannot comply with. |
| 409 Conflict           | The request cannot be processed because of a conflict between resources, e.g. trying to start an already started server. |

#### API errors

Should there be a problem with the API service, a request is responded with an
error code between 500 and 599. Possible response codes are:

| HTTP status               | Description |
| ------------------------- | ----------- |
| 500 Internal Server Error | The request cannot be processed because of a temporary problem in the cloud service.
| 503 Service Unavailable   | The API service is not in use because of maintenance.

The `error_code` parameter defines the more specific error code.
The error codes are defined under each operation in this API documentation.

The `error_message` parameter gives a human-readable error description that
can include dynamic content such as UUIDs of resources in order to help
track down the source of the error.

#### Example error response

```http
HTTP/1.1 404 Not Found
```

```json
{
  "error": {
    "error_message": "The server 00af0f73-7082-4283-b925-811d1585774b does not exist.",
    "error_code": "SERVER_NOT_FOUND"
  }
}
```
