# API

***

It is possible to control the features of the control panel via an API, enabling automation of many tasks. For example, you can run a script on a VM that uses the API to automatically adjust the number of CPU cores as the load fluctuates. A sample script for this purpose is available on [GitHub](https://github.com/glesys/api-docs/tree/master/BASH/LocalCPUCoresUpgradeDowngrade).

This section serves as a getting-started guide for the Glesys API. The complete API documentation can be found on the [Glesys GitHub page](https://github.com/glesys/api-docs/wiki).&#x20;

## Create keys

There are two types of API keys: permanent and temporary.

*Permanent keys* are created in advance and can be used from predefined IP addresses. You also specify the key's permissions before it can be used.

*Temporary keys* are retrieved by logging in to the API using a username and password. This is the same username and password you use to log in to the control panel in Glesys Cloud. Upon logging in, you receive a list of organizations and projects that the user has access to. These are the same organizations and projects you have granted the user access to under Permissions for collaborator in the control panel. You use these projects or organizations as the username when making API calls. The password is the API key you received when you logged in with your username and password.

{% tabs %}
{% tab title="Permanent keys" %}
You find the page for permanent API keys under your user profile in the control panel. Click on the user icon in the top-right corner and select **Control API access**.

<figure><img src="/files/9zwp4RGr5xrWJXg0hUXH" alt=""><figcaption></figcaption></figure>

In the dialog box that appears, click the **Create** button. In the next dialog box, we enter a name for the key and specify which project it should have access to. In the example image below, we name the key *my-test-key* and grant it access to the project *Lab1*. Click **Create** to generate the key.

<figure><img src="/files/WEIcuUPT2u3kGN3mBN21" alt=""><figcaption></figcaption></figure>

By default, new keys have no access from any IP addresses and no permissions to do anything. Start by granting *access* to the key from an IP address. Click **Access** in the **Actions** menu for the key.

<figure><img src="/files/Uhbz4X347KZfHUcd5CTI" alt=""><figcaption></figcaption></figure>

Here, enter the IP addresses that should be able to use the API key. It is possible to specify both individual addresses and entire networks. The IP addresses and networks are separated by commas. Hostnames can also be specified. Additionally, access can be granted to all IP addresses by using the network 0.0.0.0/0. However, this should be avoided.

In the example below, only the IP addresses 203.0.113.2, 203.0.113.11, and the network 192.0.2.0/24 can use the key. Click **Add** to save and add the IP addresses.

<figure><img src="/files/kUqg8kEORd2g5c08sSM0" alt=""><figcaption></figcaption></figure>

After clicking **Add**, the keys are displayed in the same dialog box under *Hosts with access*. If everything looks correct, close the dialog box by clicking **Close**.

In the overview, it now shows how many hosts have access to the key.

Next, you need to grant the key *permissions* to perform various actions on different types of resources. To do this, click **Permissions** in the **Actions** menu for the key.

<figure><img src="/files/2Wx59pNgYJeAWD2YREnB" alt=""><figcaption></figcaption></figure>

The permissions for keys are divided into modules. You can choose to grant the key permission to use all modules or restrict it to only the modules that are needed. It is more secure to only grant keys the permissions they genuinely require. Therefore, click **Show modules** to assign permissions to specific modules.

<figure><img src="/files/xrMtGtxl4GmZqEBXo520" alt=""><figcaption></figcaption></figure>

For each module listed, you can either grant full permissions to that module or specify which functions within the module the key should have permission to use. To display a module's functions, click **Show functions** next to the module.

In the example below, we have granted the key full permissions for the *Server* module, meaning the key can perform all functions for servers in the project where the key was created. For the *IP* module, the key has only specific permissions. Note that the image below is cropped and shows only a portion of the available modules.

<figure><img src="/files/Z0Eu8AOrtPnEaeGuqHZA" alt=""><figcaption></figcaption></figure>

Click **Save** at the bottom of the dialog box to save the key's permissions.

### Test the permanent key

You have now created the key, assigned permissions to certain modules, and granted access to the key from specific IP addresses. Now it’s time to test the key.

To test the key, you first need to copy the key's password. In the key's overview, click the icon to copy the key's password. The username for the key is the project; in this example, it is *cl43212*.

<figure><img src="/files/UH3wy6Vt9xnNgCn5QIOz" alt=""><figcaption></figcaption></figure>

Now, try making an API call using cURL. Keep in mind that the call must be made from an IP address that you have added to the access list.

The URL for the API is `https://api.glesys.com`. The function we are testing here is `/server/list`. Note that the key must have permission to use `/server/list`. We use *basic auth* for authentication. For security purposes, we disable the shell history first.

{% code title="Multiple commands" %}

```
set +o history
curl -X POST https://api.glesys.com/server/list -u cl43212:kucxxxyyyzzz
```

{% endcode %}

The response from the API will look like the example below (note that this is just a brief excerpt of the full output).

{% code title="API response" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<response>
 <status>
  <code>200</code>
  <timestamp>2023-09-21T15:38:35+02:00</timestamp>
  <text>OK</text>
 </status>
 <servers>
  <item>
   <serverid>kvm3652342</serverid>
   <projectkey>cl43212</projectkey>
   <hostname>testvm5</hostname>
   <datacenter>Falkenberg</datacenter>
   <platform>KVM</platform>
   <description/>
   <cpucores>1</cpucores>
   <memorysize>2048</memorysize>
   <disksize>30</disksize>
   <transfer/>
   <bandwidth>100</bandwidth>
   <templatename>Ubuntu 22.04 LTS (Jammy Jellyfish)</templatename>
```

{% endcode %}

Now we know that the key works, and we can re-enable the shell history:

{% code title="Command" %}

```terminal
set -o history
```

{% endcode %}
{% endtab %}

{% tab title="Temporary keys" %}
Temporary keys are created by logging into the API using the same username and password you use to log in to the Glesys Cloud control panel. The key created, therefore, has the same permissions as the user logging in to create it. A temporary key expires after six hours of inactivity.

To create a temporary key, start by logging into the API using the `/user/login` function. As parameters, you must provide the account's username and password. Since you will be entering your account password, start by disabling the shell history. Afterward, you can re-enable the history. Enclose the URL in quotation marks because it contains special characters that the shell would otherwise interpret.

{% code title="Multiple commands" %}

```terminal
set +o history
curl -X POST "https://api.glesys.com/user/login?username=colleague@example.com&password=xxx"
```

{% endcode %}

The response includes information about what the user has access to, as well as the key to be used as the password. It might look like the example below (this is just a brief excerpt from a much longer response):

{% code title="API response" %}

```xml
 <login>
  <username>colleague@example.com</username>
  <apikey>xxx-yyy-zzz-123</apikey>
  <accounts>
   <item>
    <account>cl43212</account>
    <description/>
    <roles>
     <item>FullAccess</item>
    </roles>
   </item>
  </accounts>
  <customers>
   <item>
    <customernumber>123456</customernumber>
    <description/>
    <roles>
     <item>ReadOnly</item>
    </roles>
   </item>
  </customers>
 </login>
```

{% endcode %}

Here, you can see that the user has full permissions for the project *cl43212*, but only read permissions for the organization *123456*.

In the response, you also received the API key, *xxx-yyy-zzz-123*.

### Testing the temporary key

You can now use the project, *cl43212*, as the username and the API key, *xxx-yyy-zzz-123*, as the password to make API calls. It is also possible to use the organization number as the username, but in this case, we only have read permissions for the organization. Additionally, the control panel username can be used. Depending on what you use as the username (project, organization, or Cloud account), you gain access to different features.

For example, using the Cloud account as the username provides access to personal account details. Using the project as the username grants access to project-based functions, such as creating, starting, and stopping VMs. Using the organization as the username allows access to organization-wide features, such as invoice management and similar tasks.

Since this user has full access to the project *cl43212*, we will use it as the username and list all servers. Provide the username and password as *basic auth*:

{% code title="Command" %}

```terminal
curl -X POST https://api.glesys.com/server/list -u cl43212:xxx-yyy-zzz-123
```

{% endcode %}

The response you receive looks something like the example below (this is just a brief excerpt from a much longer response):

{% code title="API response" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<response>
 <status>
  <code>200</code>
  <timestamp>2023-09-21T20:06:56+02:00</timestamp>
  <text>OK</text>
 </status>
 <servers>
  <item>
   <serverid>kvm3652342</serverid>
   <projectkey>cl43212</projectkey>
   <hostname>testvm5</hostname>
   <datacenter>Falkenberg</datacenter>
   <platform>KVM</platform>
   <description/>
   <cpucores>1</cpucores>
   <memorysize>2048</memorysize>
   <disksize>30</disksize>
```

{% endcode %}

This confirms that the temporary key works.
{% endtab %}
{% endtabs %}

## Some examples

Regardless of the type of key you use, the API works the same way and provides the same functions.

### JSON as response type

By default, the API responds with an XML document. If you want the response as a JSON object instead, you need to specify this to the API by including a header in the request. To format the JSON data, you can pipe it to `jq` (omit `jq` to get the raw JSON data):

{% code title="Command" %}

```terminal
curl -X POST https://api.glesys.com/server/list -u cl43212:kucxxxyyyzzz \
--header "Accept: application/json" | jq
```

{% endcode %}

The response you receive looks something like the example below (this is just a brief excerpt from a much longer response):

{% code title="API response" %}

```json
{
  "response": {
    "status": {
      "code": 200,
      "timestamp": "2023-09-21T19:14:24+02:00",
      "text": "OK"
    },
    "servers": [
      {
        "serverid": "kvm3652342",
        "projectkey": "cl43212",
        "hostname": "testvm5",
        "datacenter": "Falkenberg",
        "platform": "KVM",
        "description": null,
        "cpucores": 1,
        "memorysize": 2048,
        "disksize": 30,
        "transfer": null,
        "bandwidth": 100,
        "templatename": "Ubuntu 22.04 LTS (Jammy Jellyfish)",
        "initialtemplate": {
          "id": "f4521a83-e541-47b2-bc09-94161fe8b40d",
          "name": "Ubuntu 22.04 LTS (Jammy Jellyfish)",
```

{% endcode %}

### Update a PTR record

For functions that require arguments, you specify these as parameters in standard URL format. For example, to update the PTR record for an IP address, you provide the IP address and the fully qualified domain name (FQDN) as parameters to the `/ip/setptr` function:

{% code title="Multiple commands" %}

```terminal
set +o history
curl -X POST \
"https://api.glesys.com/ip/setptr?ipaddress=203.0.113.121&data=testvm5.example.com." \
-u cl43212:xxx-yyy-zzz-123
```

{% endcode %}

The response indicates whether the update was successful. The output below is just a brief excerpt.

{% code title="API response" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<response>
 <status>
  <code>200</code>
  <timestamp>2023-09-21T20:24:49+02:00</timestamp>
  <text>PTR updated.</text>
```

{% endcode %}

### Example with Python

To list all servers using Python, you can create a short script like the one below. We name it `glesys-api.py`.

{% code title="glesys-api.py" %}

```python
import requests
import json

url = 'https://api.glesys.com'
endpoint = '/server/list'
username = 'cl43212'
password = 'kucxxxyyyzzz'
headers = {
    'Accept': 'application/json'
}

response = requests.post(url + endpoint, headers=headers, auth=(username, password))
print(json.dumps(response.json(), indent=2))
```

{% endcode %}

Execute the script:

{% code title="Command" %}

```terminal
python3 glesys-api.py
```

{% endcode %}

An excerpt from the output is shown here:

{% code title="Output" %}

```json
{
  "response": {
    "status": {
      "code": 200,
      "timestamp": "2023-09-22T08:40:35+02:00",
      "text": "OK"
    },
    "servers": [
      {
        "serverid": "kvm3652342",
        "projectkey": "cl43212",
        "hostname": "testvm5",
        "datacenter": "Falkenberg",
        "platform": "KVM",
        "description": null,
        "cpucores": 1,
        "memorysize": 2048,
        "disksize": 30,
        "transfer": null,
        "bandwidth": 100,
```

{% endcode %}

## Viewing the built-in API documentation

It's possible to view the API documentation by making calls to the API. This way, you can drill down to the specific endpoint you need.

For example, by making a POST or GET request to <https://api.glesys.com/> you'll get a list of all available modules.

{% code title="Multiple command" %}

```
set +o history
curl -X POST "https://api.glesys.com/" -u cl43212:xxx-yyy-zzz-123
```

{% endcode %}

This will return a 404 error, but will print out a list of all available modules.

{% code title="API response" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<response>
 <status>
  <code>404</code>
  <timestamp>2025-09-11T08:20:57+02:00</timestamp>
  <text>Unknown module. Please specify module (ex: api.glesys.com/module/)</text>
 </status>
 <modules>
  <item>server</item>
  <item>ip</item>
  <item>database</item>
  <item>domain</item>
  <item>archive</item>
  <item>email</item>
  <item>invoice</item>
  <item>country</item>
  <item>customer</item>
  <item>account</item>
  <item>paymentcard</item>
  <item>vpn</item>
  <item>loadbalancer</item>
  <item>user</item>
  <item>api</item>
  <item>sshkey</item>
  <item>networkadapter</item>
  <item>networkcircuit</item>
  <item>network</item>
  <item>filestorage</item>
  <item>project</item>
  <item>objectstorage</item>
  <item>serverdisk</item>
  <item>privatenetwork</item>
 </modules>
 <debug>
  <input>
   <projectkey>cl43212</projectkey>
   <organizationnumber>31704</organizationnumber>
  </input>
 </debug>
</response>

```

{% endcode %}

You can now make another request to a module of interest, for example, the object storage module.

```
set +o history
curl -X POST "https://api.glesys.com/objectstorage/" -u cl43212:xxx-yyy-zzz-123
```

This will now result in another 404 error, but this time it will return all the information about the module's available functions and their required and optional arguments. The example below is just a short snippet of a much longer output.

{% code title="API response" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<response>
 <status>
  <code>404</code>
  <timestamp>2025-09-11T08:31:15+02:00</timestamp>
  <text>Unknown function. Please specify function (ex: api.glesys.com/module/function</text>
 </status>
 <module>
  <description>Manage your Object Storage Instances</description>
  <authentication>
   <required>true</required>
   <apikey>true</apikey>
   <user>
    <username>false</username>
    <cloudaccount>true</cloudaccount>
    <customernumber>false</customernumber>
   </user>
   <anonymous>false</anonymous>
  </authentication>
  <allowed_functions>
   <item>
    <function>instancedetails</function>
    <documentation>Get detailed information of an Object Storage Instance such as datacenter, descriptions and associated credentials.</documentation>
    <get>1</get>
    <post>1</post>
    <required_arguments>
     <item>instanceid</item>
    </required_arguments>
   </item>
   <item>
    <function>listinstances</function>
    <documentation>Get a list of Object Storage Instances for a project</documentation>
    <get>1</get>
    <post>1</post>
    <required_arguments>
     <item>projectkey</item>
    </required_arguments>
   </item>
   <item>
    <function>createinstance</function>
    <documentation>Create a new Object Storage Instance. Your first credentials will be created automatically</documentation>
    <post>1</post>
    <required_arguments>
     <item>projectkey</item>
     <item>datacenter</item>
    </required_arguments>
    <optional_arguments>
     <item>description</item>
     <item>createinitialbucket</item>
    </optional_arguments>
   </item>
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.glesys.com/platform/control-panel/api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
