Hosting API documentation

Welcome to the documentation of scaledo-hosting API.

Server

Server CRUD

Resource

Operation

Description

Server

GET /v2/server

List servers

GET /v2/server/(hostname)

Show one server

POST /v2/server

Create new server

PUT /v2/server/(hostname)

Update server.

DELETE /v2/server/(hostname)

Delete server

PUT /v2/server/evacuate

Evacuate server

GET /v2/server/(server)/storage

List storages on server

PUT /v2/server/upstream/(php_version)

Upstream createEnabled php-version

GET /v2/server/get-full-cdb-export/(rack)/(log_type)

CDB; MCDB; Logs

POST /v2/server/data-send-of

Send data of a specific type

GET /v2/server

Server List.

Status Codes:

Example request:

GET /server HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items":[{
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 2,
        "nfsMountpoint": "/nfsmnt/web-1",
        "rack": "r0",
    }]
}
GET /v2/server/(hostname)

Server List.

Status Codes:

Example request:

GET /server/web-1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":{
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 2,
        "nfsMountpoint": "/nfsmnt/web-1",
        "rack": "r0",
        "upstreams": [
            {
                "createEnabled": true,
                "id": 1,
                "identString": "local-php56-1",
                "name": "Apache 2.4 PHP 5.6",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php56"
            },
            {
                "createEnabled": true,
                "id": 2,
                "identString": "local-php71-1",
                "name": "Apache 2.4 PHP 7.1",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php71"
            },
            {
                "createEnabled": true,
                "id": 3,
                "identString": "local-php73-1",
                "name": "Apache 2.4 PHP 7.3",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php73"
            }
        ]
    }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Server not found"
}
POST /v2/server

Server create.

Status Codes:

Example request:

POST /server HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "createEnabled": true,
    "group": "local",
    "hostname": "web-1",
    "id": 2,
    "nfsMountpoint": "/nfsmnt/web-1",
    "rack": "r0",
    "serverUpstreams":[
        {
            "php_container": "php56",
            "php_version": "5.6",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        },
        {
            "php_container": "php71",
            "php_version": "7.1",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        },
        {
            "php_container": "php73",
            "php_version": "7.3",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        }]
}

Example request - new ident string:

POST /server HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "createEnabled": true,
    "group": "local",
    "hostname": "web-1",
    "id": 2,
    "nfsMountpoint": "/nfsmnt/web-1",
    "rack": "r1",
    "newIdentString": true,
    "unit": "u1",
    "serverUpstreams":[
        {
            "php_container": "php56",
            "php_version": "5.6",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        },
        {
            "php_container": "php71",
            "php_version": "7.1",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        },
        {
            "php_container": "php73",
            "php_version": "7.3",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        }]
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":{
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 2,
        "nfsMountpoint": "/nfsmnt/web-1",
        "rack": "r0",
        "upstreams": [
            {
                "createEnabled": true,
                "id": 1,
                "identString": "local-php56-1",
                "name": "Apache 2.4 PHP 5.6",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php56"
            },
            {
                "createEnabled": true,
                "id": 2,
                "identString": "local-php71-1",
                "name": "Apache 2.4 PHP 7.1",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php71"
            },
            {
                "createEnabled": true,
                "id": 3,
                "identString": "local-php73-1",
                "name": "Apache 2.4 PHP 7.3",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php73"
            }
        ]
    }
}

Example response - error:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "error": {"hostname": ["Unable to find server ident number"]}
}
PUT /v2/server/(hostname)

Server update.

Status Codes:

Example request:

PUT /server HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "createEnabled": true,
    "hostname": "web-1",
    "rack": "r1",
    "serverUpstreams":{"containers":[
        {
            "php_container": "php74",
            "php_version": "7.4",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        }]}
}

Example request - new ident string:

PUT /server HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "createEnabled": true,
    "hostname": "web-1",
    "rack": "r1",
    "newIdentString": true,
    "unit": "u1",
    "serverUpstreams":{"containers":[
        {
            "php_container": "php74",
            "php_version": "7.4",
            "apache_version": "2.4",
            "upstream_type": "hosting"
        }]}
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":{
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 2,
        "nfsMountpoint": "/nfsmnt/web-1",
        "rack": "r1",
        "upstreams": [
            {
                "createEnabled": true,
                "id": 1,
                "identString": "local-php56-1",
                "name": "Apache 2.4 PHP 5.6",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php56"
            },
            {
                "createEnabled": true,
                "id": 2,
                "identString": "local-php71-1",
                "name": "Apache 2.4 PHP 7.1",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php71"
            },
            {
                "createEnabled": true,
                "id": 3,
                "identString": "local-php73-1",
                "name": "Apache 2.4 PHP 7.3",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php73"
            },
            {
                "createEnabled": true,
                "id": 4,
                "identString": "local-php74-1",
                "name": "Apache 2.4 PHP 7.4",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php74"
            }
        ]
    }
}

Example response - error:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "error": {"hostname": ["Unable to find server ident number"]}
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Server not found"
}
DELETE /v2/server/(hostname)

Server delete.

Status Codes:

Example request:

DELETE /server HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":{
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 2,
        "nfsMountpoint": "/nfsmnt/web-1",
        "rack": "r0",
        "upstreams": [
            {
                "createEnabled": true,
                "id": 1,
                "identString": "local-php56-1",
                "name": "Apache 2.4 PHP 5.6",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php56"
            },
            {
                "createEnabled": true,
                "id": 2,
                "identString": "local-php71-1",
                "name": "Apache 2.4 PHP 7.1",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php71"
            },
            {
                "createEnabled": true,
                "id": 3,
                "identString": "local-php73-1",
                "name": "Apache 2.4 PHP 7.3",
                "protected": false,
                "type": "hosting",
                "upstream": "apache24-php73"
            }
        ]
    }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Server not found"
}
PUT /v2/server/evacuate

Evacuate source server to target server. Updates all storages in database from source server and send cdb / mcdb updates. We create many small updates so that cdb queue is not blocked by big cdb / mcdb update.

This method doesn’t migrate / delete any data and should be called only after data is on target server.

We rely on proper validations during the data migration process - for example, making sure that all upstreams used on the source server are available on the target, too. That’s why here, we do our best to go through with the operation and only log errors. This is the last step of an evacuation process, and we don’t want to leave hundreds of websites dysfunctional.

Status Codes:
Request JSON Object:
  • sourceServer (str) – Source server hostname

  • targetServer (str) – Target server hostname

  • async (bool) – If true (default), return a Task ID immediately and perform the evacuation in the background. Otherwise, wait for the process to complete.

Example request:

PUT /v2/server/evacuate HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "sourceServer": "r1-u19-web",
    "targetServer": "r1-u20-web",
    "async": false
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success"
    "items":[
        "848fd3e9-feea-4dfe-b2a7-c92b74fd59d8",
        "5975a26f-0349-46af-9334-4b5231b881a0",
        "d772f3b3-ab4c-41de-aefa-88719c12d452"
    ],
    "tasks": {
        "mcdb": "e2119676-340b-4388-8f06-9351d572a72f",
        "ftp": "a45abf5f-a8dc-4303-ab3e-d24d16c07a0e",
        "crontab_source": "5815dd49-264b-4cdf-9c33-e7721de581ea",
        "crontab_target": "a08422f4-4222-4423-a704-86c2c7fb5c94",
        "shell": "1e8121cf-6463-476e-9a12-344a34fcbca2"
    },
    "warnings": {
        "domain-1.com": "message which should be logged and operator should handle it"
    },
    "upstream_errors": {
        "r1-u18-php85-fpm9": "Error message",
        "r1-u18-php83": "Upstream not found on target server"
    }
}
GET /v2/server/(server)/storage

List all storages on server

Status Codes:

Example request:

GET /web-1/storage HTTP/1.1
Content-Type: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json
{
“items”: [
[

“e3b0a1af-fcff-4cc5-b7db-79aa7991470b”, “mrena.sk”, 130900

], [

“625eb1d4-6b66-4d89-9101-5bf200f18b99”, “halka.sk”, 71360

],

], “status”: “success”

}

PUT /v2/server/upstream/(php_version)

Update a rack/all rack upstream value ‘createEnabled’ for specific PHP-version. If no rack is specified, request will apply to ALL rack.

Status Codes:

Example request:

PUT /v2/server/upstream/php-version HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "rack": "r101",
    "createEnabled": True,
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "r101": [
        {
            "id": 2024,
            "name": "Apache 2.4 PHP 7.4",
            "upstream": "apache24-php74",
            "createEnabled": true,
            "protected": false,
            "type": "hosting",
            "identString": "r101-u24-php74",
            "defaultUpstreamFlag": false
        },
    ]
}
GET /v2/server/get-full-cdb-export/(rack)/(log_type)

Get the latest FULL cdb/mcdb log from specified rack.

Parameters:
  • rack – rack

  • log_type – type of log (cdb/mcdb)

Example request:

GET /v2/server/get-full-cdb-export/r101 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "log_type": "cdb",
    "uuid": "79acb3b4-6ce9-4bd9-aed6-678083280ebd"
}
POST /v2/server/data-send-of

Send data of a specific type to a server.

Status Codes:

Example request:

POST /v2/server/data-send-of HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "hostname": "web-1",
    "dataType": "cdb"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "task_id": "some-task-id"
}

Example response - error:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "error": "Unsupported data type"
}

Storage

Manipulating hosting Storages

Resource

Operation

Description

POST /v2/storage/(uuid)/push-config

PUT /v2/storage/(uuid)/push-config

PUT /v2/storage/(uuid)/deploy-ddos-protection

Storage

GET /v2/storage

list all Storage objects

GET /v2/storage/by-rack/(rack)

list all Rack Storages objects

GET /v2/storage/(uuid)

show info

POST /v2/storage/(uuid)/defaults

insert default vhost/services

POST /v2/storage/(uuid)

create storage

PUT /v2/storage/(uuid)

update storage

DELETE /v2/storage/(uuid)

delete storage

PUT /v2/storage/(uuid)/restore

restore storage

PUT /v2/storage/(uuid)/enable-files

enable files for storage

PUT /v2/storage/(uuid)/set_limit_queued

set quota

PUT /v2/storage/(uuid)/set_limit

PUT /v2/storage/quota_multiset

set multiple quotas

GET /v2/storage/by-domain/(domain)

get storage by domain

DELETE /v2/storage/by-domain/(domain)/mcdb/(rack)

cleanup mcdb

GET /v2/storage/by-domain/(domain)/public-ip

public ip by domain

GET /v2/storage/by-domain/(domain)/rack

get rack by domain

GET /v2/storage/(uuid)/quarantine

check quarantine status

POST /v2/storage/(uuid)/quarantine

enable quarantine

PUT /v2/storage/(uuid)/quarantine

DELETE /v2/storage/(uuid)/quarantine

clear quarantine

GET /v2/storage/(uuid)/cms-geoip

check CMS Admin GeoIP protection status

POST /v2/storage/(uuid)/cms-geoip

update CMS Admin GeoIP protection status

DELETE /v2/storage/(uuid)/cms-geoip

GET /v2/storage/search-info

check quarantine status

GET /v2/storage/user-location

get uid locations

PUT /v2/storage/(uuid)/php-backend

set PHP backend

PUT /v2/storage/(uuid)/php-container

change PHP container

Web sender whitelist

GET /v2/storage/(uuid)/whitelist-web-sender

list rules

POST /v2/storage/(uuid)/whitelist-web-sender

add rule

DELETE /v2/storage/(uuid)/whitelist-web-sender/(int:rule_id)

delete rule

GET /v2/storage

Lists all existing Storages.

Example request

GET /v2/storage HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "id": 55363,
            "createTime": 1411978388,
            "updateTime": 1411978388,
            "uuid": "816e9892-c580-11e8-b389-fba089f55f59",
            "domain": "asdf.sk",
            "uid": 1005,
            "gid": 1005,
            "limitBytes": 0,
            "disabled": false,
            "deleted": false,
            "disabledChangeTime": null,
            "deletedChangeTime": null,
            "rootPath": "/data/a/s/asdf.sk",
            "storagePool": {
                "id": 1,
            },
            "server": {
                "id": 3,
                "host": "web-1",
                "group": "it13",
            },
            "filesEnabled": true,
            "scheduledToDelete": null,

        },
    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}
Query Parameters:
  • pagesize – limit number of records shown at once

  • page – page index

GET /v2/storage/by-rack/(rack)

Lists all existing Storages for specific rack.

Example request

GET /v2/storage/by-rack/r101 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
    {
        "id": 2119952,
        "createTime": 1691966925,
        "updateTime": 1691966927,
        "uuid": "3327df65-eb87-423c-b77b-e72f476f5090",
        "domain": "deduco.se",
        "uid": 3619952,
        "gid": 3619952,
        "limitBytes": 107374182400,
        "disabled": false,
        "deleted": false,
        "disabledChangeTime": null,
        "deletedChangeTime": null,
        "rootPath": "/data/3/3/3327df65-eb87-423c-b77b-e72f476f5090",
        "storagePool": {
            "id": 7,
            "mountpoint": "/data"
        },
        "server": {
            "id": 445,
            "rack": "r101",
            "group": "local",
            "hostname": "r101-u22-web",
            "createEnabled": true,
            "nfsMountpoint": "/nfsmnt/r101-u22-web"
        },
        "filesEnabled": true,
        "scheduledToDelete": null,
        "quarantine": null,
        "cmsProtection": true,
        "business": false,
        "sysTempDir": ".tmp",
        "uploadTmpDir": ".tmp/upload"
        }
    ],
    "pager": {
        "page": 1,
        "pagesize": null,
        "items": 118418
    }
    }

:query pagesize: limit number of records shown at once
:query page: page index
GET /v2/storage/(uuid)

Get Storage information by its uuid identifier.

Example request

GET /v2/storage/816e9892-c580-11e8-b389-fba089f55f59 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 55363,
    "createTime": 1411978388,
    "updateTime": 1411978388,
    "uuid": "816e9892-c580-11e8-b389-fba089f55f59"
    "domain": "asdf.sk",
    "uid": 1005,
    "gid": 1005,
    "limitBytes": 0,
    "disabled": false,
    "deleted": false,
    "disabledChangeTime": null,
    "deletedChangeTime": null,
    "rootPath": "/data/a/s/asdf.sk",
    "storagePool": {
        "id": 1,
    },
    "server": {
        "id": 3,
        "host": "web-1",
        "group": "it13",
    },
    "filesEnabled": true,
    "scheduledToDelete": null
    "ddosProtection": HIGH
}
POST /v2/storage/(uuid)/defaults

Sets up default Services and Virtualhost on a new Storage.

Request JSON Object:
  • indexTemplate (string) – Default template file name if we don’t provide language (in that case, it’s used to assemble the file name dynamically together with entity).

  • language (string) – Two-letter country code, used to select the correct index template file

  • entity (string) – Company name abbreviation, used to select the correct index template file (default ws)

Example request:

POST /v2/storage/816e9892-c580-11e8-b389-fba089f55f59/defaults HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "entity": "sk-ws"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 55363,
        "createTime": 1411978388,
        "updateTime": 1411978388,
        "uuid": "816e9892-c580-11e8-b389-fba089f55f59"
        "domain": "asdf.sk",
        "uid": 1005,
        "gid": 1005,
        "limitBytes": 0,
        "disabled": false,
        "deleted": false,
        "disabledChangeTime": null,
        "deletedChangeTime": null,
        "rootPath": "/data/a/s/asdf.sk",
        "storagePool": {
            "id": 1,
        },
        "server": {
            "id": 3,
            "host": "web-1",
            "group": "it13",
        },
        "filesEnabled": true,
        "scheduledToDelete": null,
    },
    "error": null
}

Example response - Storage already has children:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "items": {
        "virtualhosts": []
    },
    "error": "Cannot setup defaults on non-empty Storage."
}
POST /v2/storage/(uuid)

Creates a Storage identified by a unique identifier uuid. Domain is a required request parameter and specifies a domain with which the Storage will be associated until it is deleted. A Domain cannot be shared by two or more Storage objects, and a Storage cannot be updated to use a new domain; it can only be deleted and created anew.

Request JSON Object:
  • domain (string) – domain associated with this Storage

  • filesEnabled (bool) – if false, only redirects are supported

  • limitBytes (int) – Storage quota

  • location (string) – location of storage (sk, hu, …) - if not specified any location is chosen

  • business (bool) – mark storage as business (false by default)

  • premium (bool) – create storage in premium rack (false by default)

  • skipLetsEncryptCertificate (bool) – skip generating new Lets Encrypt certificates (false by default)

Response JSON Object:
  • status (string) – operation status

  • item (obj) – JSON representation of created Storage model

  • error (string) – error message (if any)

Status Codes:

Example request:

POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "domain": "nahodnadomenatest.sk",
    "filesEnabled": true,
    "limitBytes": 1024,
    "location": "sk"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
       "id": 94336,
        "createTime": 1560853445,
        "updateTime": 1569575907,
        "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
        "domain": "nahodnadomenatest.sk",
        "uid": 1074174,
        "gid": 1074174,
        "limitBytes": 10642040832,
        "disabled": false,
        "deleted": false,
        "disabledChangeTime": 1560846245,
        "deletedChangeTime": null,
        "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
        "storagePool": {
            "mountpoint": "/nfsmnt/hosting2_1",
            "id": 3
        },
       "server": {
            "id": 223,
            "rack": "r0",
            "group": "local",
            "hostname": "web-100",
            "createEnabled": true,
            "nfsMountpoint": "/nfsmnt/web-100"
        },
        "filesEnabled": true,
        "scheduledToDelete": null,
        "quarantine": null,
        "cmsProtection": true
       },
    "status": "success",
    "error": null,
    "async_tasks": {
        "set_mcdb": "72896007-624e-405f-a37b-6efda1011986"
    }
}

Example response - validation error:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "error": {
        "domain": ["Domain name already used."]
    },
    "status": "error"
}

Example response - Not Found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "error": "No available location found",
    "status": "error"
}

Example response - Internal Server Error:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
    "error": "Could not get available locations",
    "status": "error"
}
PUT /v2/storage/(uuid)

Update Storage.

Request JSON Object:
  • limitBytes (int) – Storage quota

  • disabled (bool) – (un)mark storage as disabled

  • scheduledToDelete (int) – specify date (UNIX) on which the storage files will be deleted unless it’s restored in the meantime.

  • deleted (bool) – do not update directly; use delete/restore endpoint

  • serverId (int) – update server id

  • business (bool) – mark storage as business

  • ddosProtection (str) – change ddos protection. Options: “DISABLED”, “LOW”, “HIGH”

Response JSON Object:
  • status (string) – operation status

  • item (obj) – JSON representation of updated Storage model

  • error (string) – error message (if any)

DELETE /v2/storage/(uuid)

Delete a Storage. Immediately marks the Storage as deleted and begins the process of deleting hosting files from the web server.

The safer approach is to update the Storage with disabled`=1 and set `scheduledToDelete.

Response JSON Object:
  • status (string) – operation status

  • item (obj) – JSON representation of updated Storage model

  • error (string) – error message (if any)

PUT /v2/storage/(uuid)/restore

Restore Storage that was marked as deleted. Clears deleted/disabled flags and resets scheduled deletion time, if set.

Creates folder structure on the hosting server, however it does not perform restore from backup.

Example request:

PUT /v2/storage/625eb1d4-6b66-4d89-9101-5bf200f18b99/restore HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "restoreData": true
}
Response JSON Object:
  • status (string) – operation status

  • item (obj) – JSON representation of updated Storage model

  • error (string) – error message (if any)

PUT /v2/storage/(uuid)/enable-files

Enable files for storage. Create storage on server, set storage limit (limitBytes), set correct dns settings and nginx configuration.

Return success if files are already enabled for storage.

Note: This method does not create default Virtualhost nor any services.

Request JSON Object:
  • location (string) – location of storage (sk, hu, …)

Response JSON Object:
  • status (string) – operation status

  • item (obj) – JSON representation of Storage model

  • error (string) – error message (if any)

  • async_tasks (obj) – async celery tasks - key is task name, value is task id

Status Codes:

Example request:

PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/enable-files HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "location": "sk"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "id": 94336,
        "createTime": 1560853445,
        "updateTime": 1569575907,
        "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
        "domain": "nahodnadomenatest.sk",
        "uid": 1074174,
        "gid": 1074174,
        "limitBytes": 10642040832,
        "disabled": false,
        "deleted": false,
        "disabledChangeTime": 1560846245,
        "deletedChangeTime": null,
        "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
        "storagePool": {
            "mountpoint": "/nfsmnt/hosting2_1",
            "id": 3
        },
       "server": {
            "id": 223,
            "rack": "r0",
            "group": "local",
            "hostname": "web-100",
            "createEnabled": true,
            "nfsMountpoint": "/nfsmnt/web-100"
        },
        "filesEnabled": true,
        "scheduledToDelete": null,
        "quarantine": null,
        "cmsProtection": true
       },
    "status": "success",
    "async_tasks": {
        "set_mcdb": "72896007-624e-405f-a37b-6efda1011986"
    }
}

Example response - validation error:

HTTP/1.1 400 OK
Content-Type: application/json

{
    "error": {
        "location": ["This field is required."]
    },
    "status": "error"
}

Example response - validation error - storage:

HTTP/1.1 400 OK
Content-Type: application/json

{
    "error": {
        "storage": ["Storage cannot have virtualhosts"]
    },
    "status": "error"
}

Example response - Not Found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "error": "Storage does not exist",
    "status": "error"
}

Example response - Internal Server Error:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
    "error": "Could not get available locations",
    "status": "error"
}
PUT /v2/storage/(uuid)/set_limit_queued
PUT /v2/storage/(uuid)/set_limit

Update filesystem quota for a Storage.

Parameters:
  • uuid – Storage UUID

Request JSON Object:
  • limit (int) – New storage quota in KiB

Status Codes:

Example request - set quota to 200 MiB:

PUT /v2/storage/a6d80ff7-2603-45c5-b83b-83d8d15d4d35/set_limit HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "limit": 204800
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "error": null,
    "async_tasks": {
        "set_limit": ["63bf9ac6-c6da-45c1-a2ca-433f757939b2"]
    },
    "item": {
        "limit": 204800,
        "limitBytes": 209715200,
        "uuid": "a6d80ff7-2603-45c5-b83b-83d8d15d4d35",
        "uid": 10247710
    }
}
PUT /v2/storage/quota_multiset

Batch update of quotas for multiple Storages. Expects a dictionary in which keys are Storage UUIDs (str) and values new quota values (int) specified in kB.

Only integer quota values are supported.

Status Codes:

Example request:

POST /v2/storage/quota_multiset HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "720a57b7-b1e8-4b54-b25d-ce18651df3fb": 45612345,
    "3fb63c3c-0d07-4b20-bb43-56467b2cb20a": 12345,
    "not-a-uuid.com": 12345
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "async_tasks": {
        "quota_multiset": ["a4c87582-ac0c-11ea-b89a-97352964f0cc"]
    },
    "malformed_entries": {
        "not-a-uid.com": 12345
    }
}

Example response - no valid data submitted:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "status": "No (valid) data was supplied",
    "async_tasks": {
        "quota_multiset": []
    },
    "malformed_entries": {
        "not-a-uid.com": 12345
    }
}
GET /v2/storage/by-domain/(domain)

Get storage by domain. Prefer non deleted and non disabled storage if exists.

Status Codes:
Query Parameters:
  • full-dump – Get full dump of storage with virtualhosts and services, optional

Example request

GET /v2/storage/by-domain/nahodnadomenatest.sk HTTP/1.1
Content-Type: application/json
Accept: application/json

Example request - full dump request

GET /v2/storage/by-domain/nahodnadomenatest.sk?full-dump=1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 94336,
    "createTime": 1560853445,
    "updateTime": 1569575907,
    "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
    "domain": "nahodnadomenatest.sk",
    "uid": 1074174,
    "gid": 1074174,
    "limitBytes": 10642040832,
    "disabled": false,
    "deleted": false,
    "disabledChangeTime": 1560846245,
    "deletedChangeTime": null,
    "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
    "storagePool": {
        "id": 3,
        "mountpoint": "/nfsmnt/hosting2_1"
    },
    "server": {
        "id": 223,
        "rack": "r0",
        "group": "local",
        "hostname": "web-100",
        "createEnabled": true,
        "nfsMountpoint": "/nfsmnt/web-100"
    },
    "filesEnabled": true,
    "scheduledToDelete": null,
    "quarantine": null,
    "cmsProtection": true
}

Example response - not found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "error": "Storage does not exist"
}
DELETE /v2/storage/by-domain/(domain)/mcdb/(rack)

Cleanup mcdb for domain in rack. We have nginx fallback in every rack if mcdb data is not found request can be routed to correct rack so we need to delete mcdb data after certain operations (for example after migration).

Status Codes:

Example request

DELETE /v2/storage/by-domain/nahodnadomenatest.sk/mcdb/r1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "async_tasks": [
        "3d805bc3-40b9-4d33-9386-5fd96e407280"
    ]
}
GET /v2/storage/by-domain/(domain)/public-ip

Get public ip on which is domain accessible. Public ip is obtained from scaledo-dns according to rack of storage.

Status Codes:

Example request

GET /v2/storage/by-domain/nahodnadomenatest.sk/public-ip HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

"37.9.175.24"

Example response - not found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "error": "Storage does not exist"
}

Example response - internal error

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
    "error": "Could not get public ip"
}
GET /v2/storage/by-domain/(domain)/rack

Get rack for domain. If domain is normal storage the rack of the assigned server is returned. If domain is masked redirect than rack of the target storage is returned. If rack cannot be determined than default rack is returned and storage_exists flag is set to False.

Response JSON Object:
  • rack (string) – rack for the domain

  • storage_exists (bool) – if storage exists on server.

Status Codes:

Example request

GET /v2/storage/by-domain/nahodnadomenatest.sk/rack HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "rack": "r0",
    "storage_exists": true
}
POST /v2/storage/(uuid)/push-config

Forces Nginx, Apache and PHP-FPM configuration update.

PUT /v2/storage/(uuid)/push-config

Forces Nginx, Apache and PHP-FPM configuration update.

GET /v2/storage/(uuid)/quarantine

Check quarantine status.

Example request

GET /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - quarantine inactive

HTTP/1.1 200 OK
Content-Type: application/json

{
    "countries": [],
    "status": "inactive"
}

Example response - quarantine active

HTTP/1.1 200 OK
Content-Type: application/json

{
    "countries": [
        "SK",
        "CZ",
        "HU"
    ],
    "status": "active"
}
POST /v2/storage/(uuid)/quarantine

Restrict access to a website by supplying a list of whitelisted country codes. Attempts to access the website from a non-whitelisted country will result in a 403 HTTP error code.

Example request

PUT /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "countries": ["SK"]
}

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "async_tasks": {
        "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280"
    },
    "countries": [
        "SK"
    ],
    "status": "success"
}
PUT /v2/storage/(uuid)/quarantine

Restrict access to a website by supplying a list of whitelisted country codes. Attempts to access the website from a non-whitelisted country will result in a 403 HTTP error code.

Example request

PUT /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "countries": ["SK"]
}

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "async_tasks": {
        "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280"
    },
    "countries": [
        "SK"
    ],
    "status": "success"
}
DELETE /v2/storage/(uuid)/quarantine

Clear quarantine.

Example request

DELETE /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "async_tasks": {
        "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280"
    },
    "countries": [],
    "status": "success"
}
GET /v2/storage/(uuid)/whitelist-web-sender

List email addresses for the given Storage that are allowed to be used as the “envelope sender” or as the From: header value when sending messages from the website (e.g. using PHP mail()).

The address field can have three formats:
  • Allow sending from a specific email address (e.g. info@example.com)

  • Allow sending from any email address in a domain (e.g. @example.com)

  • Allow sending from any email address at all (@). This value is not allowed for new entries and was only used during migration of records from the Email API.

Status Codes:

Example request

GET /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "id": 1,
            "address": "info@example.com",
            "note": "Customer request, see LA ticket BVF-UDJ-234"
        },
        {
            "id": 2,
            "address": "@my-eshop.com",
            "note": null
        }
    ]
}
POST /v2/storage/(uuid)/whitelist-web-sender

Add a new email address that can be used as the “envelope sender” or as the From: header value when sending messages from the website (e.g. using PHP mail()).

Normally, we only allow using email addresses that exist in our system, either as a regular mailbox or as an alias to a mailbox.

Request JSON Object:
  • address (string) – The email address to allow. This can actually have two forms; the exact address (info@example.com) or a domain-wide pattern (@example.com).

  • note (string) – An optional note to add to the entry, e.g. a reference to the customer request ticket or a short reason description.

Status Codes:

Example request

POST /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "address": "info@example.com",
    "note": "Customer request, see LA ticket BVF-UDJ-234"
}

Example response

HTTP/1.1 201 Created
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "address": "info@example.com",
        "note": "Customer request, see LA ticket BVF-UDJ-234"
    }
}
DELETE /v2/storage/(uuid)/whitelist-web-sender/(int: rule_id)

Delete a whitelisted email address identified by its ID.

Parameters:
  • rule_id (int) – The ID of the rule to delete.

Status Codes:
  • 200 OK – Rule deleted successfully.

  • 404 Not Found – Storage not found, not active or files are disabled; or rule not found.

Example request

DELETE /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender/213 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 213,
        "address": "info@example.com",
        "note": "Customer request, see LA ticket BVF-UDJ-234"
    }
}

Example response - rule not found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "error": "Rule not found"
}
GET /v2/storage/(uuid)/cms-geoip

Check status of GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.

POST /v2/storage/(uuid)/cms-geoip

Enable (DELETE) or disable (POST) GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.

Note: API endpoint name /cms-geoip may be confusing, since POSTing to it disables GeoIP protection, and DELETEing it re-enables GeoIP protection.

DELETE /v2/storage/(uuid)/cms-geoip

Enable (DELETE) or disable (POST) GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.

Note: API endpoint name /cms-geoip may be confusing, since POSTing to it disables GeoIP protection, and DELETEing it re-enables GeoIP protection.

GET /v2/storage/search-info

Generate a dictionary mapping domains to uid and uuid. Includes disabled, but not deleted storages. Used as a data source for elastic-powered search in FE.

Example request

GET /v2/storage/search-info HTTP/1.1
Accept: application/json

Example response (snip)

HTTP/1.1 200 OK
Content-Type: application/json

{
    "zlesapocujem.sk": [
        166987,
        "203160c5-c27f-4e1c-851d-a2fccbee97e7"
    ],
    "znarodnenie.sk": [
        164585,
        "0fcbca4d-add7-41b2-a187-a3b405e2653c"
    ]
}
GET /v2/storage/user-location

Return a dictionary of server names to lists of numerical uid`s whose `Storage is currently located on that server. Used in scaledo-rrhad web size measurements to determine which size usage measurement is correct if an uid has files on multiple servers.

We’re using the server-name-to-list-of-uids data structure because of two reasons:
  • It’s more compact (about half the size) than an uid-to-server-name dictionary

  • JSON has a limitation that dictionary keys can only be strings, so we’d have to keep this in mind and do type conversions on the client side

Query Parameters:
  • server – Only return uids located on the specified server

Example request

GET /v2/storage/user-location HTTP/1.1
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "web-1": [12345, 24231],
    "r1-u18-web": [299532, 3948183, 21245]
}
PUT /v2/storage/(uuid)/deploy-ddos-protection

Deploy DDoS protection settings.

Example request

PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/deploy-ddos-protection HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "async_tasks": {
        "set_ddos_protection": "45f0318f-32eb-4c58-af40-fffd213e96ce"
    }
}
PUT /v2/storage/(uuid)/php-backend

Change the PHP backend on all Services under this Storage to PHP-FPM or to mod_php. All masked redirects pointed to this Storage (defined under other Storages) are also switched.

If any single Service fails validations, roll back to the original state. Validations may include presence of given PHP version on the current server and so on.

Request JSON Object:
  • php_backend (string) – New PHP backend for all PHP services. Valid values are mod_php and php_fpm.

Status Codes:

Example request

PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/php-backend HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "php_backend": "php_fpm"
}

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "service_upstreams": {
        "domain-1.com": "apache24-php85-fpm",
        "php83.domain-1.com": "apache24-php83-fpm",
        "masked-sub-php101.domain-2.com": "apache24-php101-fpm",
        "masked-sub-php83.domain-2.com": "apache24-php83-fpm",
    },
    "async_tasks": {
        "mcdb": ["efb353f9-e081-401f-ad1f-a02b9f0aecf4", "aa1f78ce-f9b7-427a-bd8c-5b325b073181"],
        "fpm_config": ["608f9711-f96d-43a3-a24d-c3c578f312af", "c6458e9a-c845-4133-818f-c212206354aa"],
        "sync_user_ini_files": ["de58a0a9-e086-496a-8df2-600e492dad6b"]
    }
}

Example response - PHP version unavailable

HTTP/1.1 409 Conflict
Content-Type: application/json

{
    "status": "error",
    "error": "Some hosting or masked redirect services currently use a PHP version that's not
              available as PHP-FPM on the server",
    "detail": {
        "unsupported_php_versions": ["php83", "php84"]
    }
}
PUT /v2/storage/(uuid)/php-container

Direct all Services under the Storage to another PHP container on the same web server. No data migration takes place during this operation. The backend type is also left unchanged, so only PHP-FPM services are affected.

This operation is best-effort - if the new container doesn’t provide a PHP version used by one of the Services, we skip that Service.

Request JSON Object:
  • container_id (int) – New PHP-FPM container ID where services should point to.

  • force (bool) – If true, only log an error for services whose PHP version is not available in the target container or if they’re still using mod_php. If false (default), return an error if at least one service is not changeable to the target upstream, and don’t change anything.

Response JSON Object:
  • service_upstream_idents – Map of Service subdomains to the ``identString``s of their upstream. This value encodes rack and server ID, PHP version, PHP backend and container ID where applicable.

  • errors – Map of Service subdomains to detailed error messages if, for some reason, we were unable to set the new container ID for that Service.

Status Codes:
  • 200 OK – Success, either full or partial (see response body)

  • 400 Bad Request – Validation error

  • 409 Conflict – PHP version for some services is not available in the new container

Example request

PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/php-container HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "container_id": 17,
    "force": true
}

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "service_upstream_idents": {
        "domain-1.com": "r1-u18-php85-fpm17",
        "blog.domain-1.com": "r1-u18-php85-fpm8",
        "php83.domain-1.com": "r1-u18-php83",
        "masked-sub-php101.domain-2.com": "r1-u18-php101-fpm17",
    },
    "errors": {
        "blog.domain-1.com": "PHP version php56 not available in the target container",
        "php83.domain-1.com": "Service ID 45663 is not PHP-FPM"
    },
    "async_tasks": {
        "mcdb": ["efb353f9-e081-401f-ad1f-a02b9f0aecf4", "aa1f78ce-f9b7-427a-bd8c-5b325b073181"],
        "fpm_config": ["608f9711-f96d-43a3-a24d-c3c578f312af", "c6458e9a-c845-4133-818f-c212206354aa"],
        "sync_user_ini_files": ["de58a0a9-e086-496a-8df2-600e492dad6b"]
    }
}

Example response - unable to change some upstreams

HTTP/1.1 409 Conflict
Content-Type: application/json

{
    "status": "error",
    "errors": {
        "blog.domain-1.com": "PHP version php56 not available in the target container",
        "php83.domain-1.com": "Service ID 45663 is not PHP-FPM"
    }
}

Services

Configure Nginx services

Resource

Operation

Description

GET /v2/storage/upstream

GET /v2/storage/upstream/active

GET /v2/storage/(uuid)/upstream/(upstream_name)

Service

GET /v2/storage/(uuid)/service

list services

GET /v2/storage/(uuid)/service/(service_id)

show service

POST /v2/storage/(uuid)/service

create service

PUT /v2/storage/(uuid)/update-upstreams

update services upstream

PUT /v2/storage/(uuid)/service/(service_id)

update service

DELETE /v2/storage/(uuid)/service/(service_id)

delete service

PUT /v2/storage/default-upstream

update default upstream

GET /v2/storage/service/upstream/check-multiple

list available upstreams

Storage

GET /v2/storage/(uuid)/available-upstreams

list available upstreams

GET /v2/storage/(uuid)/upstreams/(upstream_name)

show upstream details

GET /v2/storage/(uuid)/service

List Services in a specific Storage.

Request JSON Object:
  • filter (ServiceFilter) – Filter results based on various criteria.

Query Parameters:
  • page (int) – Page offset number (default is 1).

  • pagesize (int) – Page size; return all results if omitted.

  • sort (string) – Sort results by this attribute.

  • reverse (bool) – Set to true to reverse sort order.

Response JSON Object:
  • items (list) – List of Service objects.

  • pager (object) – Pagination properties.

  • filter_errors (object) – In case the filters didn’t pass validation, return the complete result set and include the errors in this field.

ServiceFilter object format:

Request JSON Object:
  • typeIn (list[string]) – Filter services whose type attribute matches one of these values.

  • redirCodeIn (list[string]) – Filter services whose redirect response code (redirCode attribute) matches one of these values.

  • subLike (string) – Filter services whose sub attribute contains the value.

  • pathLike (string) – Filter services whose path attribute contains the value.

  • redirTargetLike (string) – Filter services whose redirect target (redirTarget attribute) contains the value.

Status Codes:

Example request:

GET /v2/storage/13e43429-77c1-4e2d-a0d5-37a1ace49472/service?sort=sub HTTP/1.1
Accept: application/json
Content-Type: application/json

{
    "filter": {
        "redirCodeIn": ["301"],
        "redirTargetLike": "shop",
        "typeIn": ["redirect"]
    }
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "filter_errors": null,
    "items": [
        {
            "cache": true,
            "default": false,
            "https_upgrade": false,
            "upgrade_insecure_requests": false,
            "id": 2755875,
            "path": "",
            "redirCode": "301",
            "redirCopyPath": false,
            "redirTarget": "https://gcutzbarbershop.hu/barbershop-budapest",
            "sub": "balint",
            "type": "redirect",
            "upstream": null,
            "upstreamName": null,
            "virtualhost": null
        },
        {
            "cache": true,
            "default": false,
            "https_upgrade": false,
            "upgrade_insecure_requests": false,
            "id": 2755899,
            "path": "",
            "redirCode": "301",
            "redirCopyPath": false,
            "redirTarget": "https://gcutzbarbershop.hu/a-legjobb-barber-shop-budapesten",
            "sub": "dave",
            "type": "redirect",
            "upstream": null,
            "upstreamName": null,
            "virtualhost": null
        },
        {
            "cache": true,
            "default": false,
            "https_upgrade": false,
            "upgrade_insecure_requests": false,
            "id": 2755908,
            "path": "",
            "redirCode": "301",
            "redirCopyPath": false,
            "redirTarget": "https://gcutzbarbershop.hu/barbershop-budapest-7-kerulet",
            "sub": "geri",
            "type": "redirect",
            "upstream": null,
            "upstreamName": null,
            "virtualhost": null
        }
    ],
    "pager": {
        "items": 3,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/storage/(uuid)/service/(service_id)

Show details of an existing Service record.

Example request:

GET /v2/<UUID>/service/<svc_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 1,
    "default": 0,
    "sub": "blog",
    "path": "",
    "type": "hosting",
    "upstream": {
        "id": 21,
        "upstream": "apache24-php72",
    },
    "virtualhost": {
        "id": 39,
    },
    "redirTarget": "",
    "redirCopyPath": "",
    "cache": 0
}
POST /v2/storage/(uuid)/service

Creates a Service record. These are used to generate configuration for our Nginx load-balancers.

When creating a type: masked Service record, this method also creates a Virtualhost record, that copies the default Virtualhost model on Storage specified by redirTarget. In this case, this method also accepts all JSON parameters accepted by create/update Virtualhost methods, and passes the parameters to them.

Request JSON Object:
  • sub (string) – subdomain

  • path (string) – URI path (example.com/this-right-here)

  • type (string) – hosting, masked, redirect or upstream

  • upstreamName (string) – ServerUpstream name (ex.: roundcube, apache24-php56) Only for type: hosting and type: upstream

  • prefer_fpm (bool) – In case of “masked” and “hosting” upstream types, swap the requested upstream for a PHP-FPM equivalent if available. The PHP version remains unchanged. Default: False.

  • redirTarget (string) – URL (type: redirect) or target domain (type: masked)

  • redirCopyPath (string) – copy URI when redirecting (only for type: redirect)

  • disabled (bool) – mark Service as disabled (configuration does not propagate)

  • cache (bool) – enable Nginx HTTP cache

  • https_upgrade (bool) – upgrade insecure requests to HTTPS (default: False)

  • upgrade_insecure_requests (bool) – add Content-Security-Policy upgrade-insecure-requests header when redirecting to HTTPS - NOTE: this flag has no effect unless https_upgrade is set to True (default: False)

  • skip_dns (bool) – Skip DNS updates.

Status Codes:

Example request:

POST /v2/<UUID>/service/<svc_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "sub": "blog",
    "upstreamName": "apache24-php84",
    "prefer_fpm": true
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "default": false,
        "sub": "blog",
        "path": "",
        "type": "hosting",
        "upstream": {
            "id": 21,
            "upstream": "apache24-php84-fpm"
        },
        "virtualhost": {
            "id": 39
        },
        "redirTarget": "",
        "redirCopyPath": "",
        "cache": false,
        "https_upgrade": false,
        "upgrade_insecure_requests": false
    },
    "error": null
}

Example response - validation error:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "error": {
        "sub": [
            "A service with this sub and path combination already exists."
        ]
    }
}
PUT /v2/storage/(uuid)/update-upstreams

Update upstream for hosting and masked services under storage according to storage.server.

Status Codes:

Example request:

PUT /v2/storage/<UUID>/update-upstreams HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items": [
        {
            "cache": true,
            "default": true,
            "https_upgrade": false,
            "upgrade_insecure_requests": false,
            "id": 433285,
            "path": "",
            "redirCode": null,
            "redirCopyPath": false,
            "redirTarget": "",
            "storage": {
                "cmsProtection": true,
                "createTime": 1560853445,
                "deleted": false,
                "deletedChangeTime": null,
                "disabled": false,
                "disabledChangeTime": 1560846245,
                "domain": "nahodnadomenatest.sk",
                "filesEnabled": true,
                "gid": 1074174,
                "id": 94336,
                "limitBytes": 10641645568,
                "quarantine": null,
                "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a",
                "scheduledToDelete": null,
                "server": {
                    "createEnabled": true,
                    "group": "local",
                    "hostname": "web-92",
                    "id": 183,
                    "nfsMountpoint": "/nfsmnt/web-92",
                    "rack": "r0"
                },
                "storagePool": {
                    "id": 3,
                    "mountpoint": "/nfsmnt/hosting2_1"
                },
                "uid": 1074174,
                "updateTime": 1567745694,
                "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a"
            }]
    "error": null
}

Example response - internal error:

HTTP/1.1 500 OK
Content-Type: application/json

{
    "status": "success",
    "error": "Unknown upstream"
}
PUT /v2/storage/(uuid)/service/(service_id)

Update a Service record.

Request JSON Object:
  • sub (string) – subdomain

  • path (string) – URI path (example.com/this-right-here)

  • type (string) – hosting, masked, redirect or upstream

  • upstreamName (string) – ServerUpstream name (ex.: roundcube, apache24-php56) Only for type: hosting and type: upstream

  • prefer_fpm (bool) – In case of “masked” and “hosting” upstream types, swap the requested upstream for a PHP-FPM equivalent if available. The PHP version remains unchanged. Default: False.

  • redirTarget (string) – URL (type: redirect) or target domain (type: masked)

  • redirCopyPath (string) – copy URI when redirecting (only for type: redirect)

  • disabled (bool) – mark Service as disabled (configuration does not propagate)

  • cache (bool) – enable Nginx HTTP cache

  • https_upgrade (bool) – upgrade insecure requests to HTTPS (default: False)

  • upgrade_insecure_requests (bool) – add Content-Security-Policy upgrade-insecure-requests header when redirecting to HTTPS - NOTE: this flag has no effect unless https_upgrade is set to True (default: False)

  • skip_dns (bool) – Skip DNS updates. Useful for batch service updates.

Status Codes:

Example request:

PUT /v2/<UUID>/service/<svc_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "upstream": "roundcube",
    "sub": "mail",
    "type": "upstream",
    "https_upgrade": true
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "default": false,
        "sub": "mail",
        "path": "",
        "type": "hosting",
        "upstream": {
            "id": 1,
            "upstream": "roundcube",
        },
        "virtualhost": {
            "id": 39,
        },
        "redirTarget": "",
        "redirCopyPath": "",
        "cache": false,
        "https_upgrade": true,
        "upgrade_insecure_requests": false
    },
    "error": null
}
DELETE /v2/storage/(uuid)/service/(service_id)

Removes a Service record permanently. If you want to disable the indicated Service temporarily, use the PUT endpoint to set the flag instead.

Status Codes:

Example request:

DELETE /v2/<UUID>/service/<svc_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "default": 0,
        "sub": "blog",
        "path": "",
        "type": "hosting",
        "upstream": {
            "id": 21,
            "upstream": "apache24-php72",
        },
        "virtualhost": {
            "id": 39,
        },
        "redirTarget": "",
        "redirCopyPath": "",
        "cache": 0
    },
    "error": null
}
GET /v2/storage/upstream

Lists all ServerUpstream records.

GET /v2/storage/upstream/active

Lists all active ServerUpstream records.

GET /v2/storage/(uuid)/available-upstreams

List upstreams available to Services on this Storage.

In case of PHP-FPM upstreams, multiple entries with the same upstream name can appear in the output. When selecting an upstream for subsequent operations (e.g. which upstream to use for a new Service), just provide its name and the Hosting API will choose the most suitable instance.

When ‘protected’ is set to true, denotes that said upstream is immutable/read-only, i.e. its contents cannot be changed by the user. Only Service of type hosting or masked should be able to use unprotected upstreams.

Response JSON Object:
  • createEnabledOnly (bool) – filter between createEnabled upstreams and all upstreams (optional).

By default, only createEnabled upstreams are listed.

Example request:

GET /v2/storage/<uuid>/available-upstreams HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "createEnabled": true,
            "id": 694,
            "identString": "r7-u40-php83",
            "name": "Apache 2.4 PHP 8.3",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php83"
        },
        {
            "createEnabled": true,
            "id": 695,
            "identString": "r7-u40-php84",
            "name": "Apache 2.4 PHP 8.4",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php84"
        },
        {
            "createEnabled": true,
            "id": 696,
            "identString": "r7-u40-php85-fpm8",
            "name": "Apache 2.4 PHP 8.5",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php85-fpm"
        },
        {
            "createEnabled": true,
            "id": 697,
            "identString": "r7-u40-php85-fpm11",
            "name": "Apache 2.4 PHP 8.5",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php85-fpm"
        }
        {
            "createEnabled": true,
            "id": 1391,
            "identString": "roundcube",
            "name": "Webmail - Roundcube",
            "protected": true,
            "type": "email",
            "upstream": "roundcube"
        }
    ],
    "pager": {
        "items": 3,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/storage/(uuid)/upstream/(upstream_name)

WARNING: This API endpoint is deprecated in favor of GET /v2/storage/<uuid>/upstreams/<upstream_name> which returns a list of upstreams. As of SE1OPQ1-1884, upstream name is no longer a unique identifier and multiple upstreams with the same name may exist on a single web server.

Parameters:
  • upstream_name – Upstream name, e.g. apache24-php84.

GET /v2/storage/(uuid)/upstreams/(upstream_name)

Get detailed information about upstreams with the requested name, which are available to this Storage. There can be multiple upstreams, especially for the PHP-FPM backend.

Generally, the caller does not need to be concerned about which one to use - it’s only necessary to provide upstream name in other requests (e.g. apache24-php85-fpm) and the Hosting API will make the right choice.

Parameters:
  • upstream_name – Upstream name, e.g. apache24-php84.

Response JSON Object:
  • createEnabledOnly (bool) – filter between createEnabled upstreams and all upstreams (optional).

By default, only createEnable upstreams are listed.

Status Codes:

Example request:

GET /v2/storage/49640220-d93f-48dd-8071-0b57178223aa/upstreams/apache24-php85-fpm HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items": [
        {
            "createEnabled": true,
            "id": 696,
            "identString": "r7-u40-php85-fpm8",
            "name": "Apache 2.4 PHP 8.5",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php85-fpm"
        },
        {
            "createEnabled": true,
            "id": 697,
            "identString": "r7-u40-php85-fpm11",
            "name": "Apache 2.4 PHP 8.5",
            "protected": false,
            "type": "hosting",
            "upstream": "apache24-php85-fpm"
        }
    ]
}
PUT /v2/storage/default-upstream

Update current default upstream.

Request JSON Object:
  • defaultUpstream (string) – default upstream

GET /v2/storage/service/upstream/check-multiple

List upstreams for all services and crons under multiple storages by uuid.

Response JSON Object:
  • list[str] – list of uuids.

Example request:

GET /service/upstream/check-multiple HTTP/1.1
Content-Type: application/json
Accept: application/json

["961c2e55-1413-4938-98de-d3fee5114805", "8f518fbd-02ef-473a-a42d-9b79d284a22a"]

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": {
        "8f518fbd-02ef-473a-a42d-9b79d284a22a": {
            "crons": [
                {
                    "id": 1,
                    "phpVersion": "php73",
                    "target": "domain1.sk/web/get4.php"
                }
            ],
            "upstreams": [
                {
                    "serviceId": 1,
                    "name": "domain1.sk",
                    "phpVersion": "php74",
                    "isModPhp": true,
                    "isPhpFpm": false,
                    "subdomain": "",
                    "type": "hosting"
                }
            ]
        },
        "961c2e55-1413-4938-98de-d3fee5114805": {
            "crons": [
                {
                    "id": 2,
                    "phpVersion": "php80",
                    "target": "domain2.sk/sub/api/cron.php"
                }
            ],
            "upstreams": [
                {
                    "serviceId": 2,
                    "name": "domain2.sk",
                    "phpVersion": "php71",
                    "isModPhp": true,
                    "isPhpFpm": false,
                    "subdomain": "",
                    "type": "hosting"
                },
                {
                    "serviceId": 3,
                    "name": "domain2.sk",
                    "phpVersion": "php72",
                    "isModPhp": true,
                    "isPhpFpm": false,
                    "subdomain": "sub",
                    "type": "hosting"
                }
            ]
        }
    },
    "status": "success"
}

Virtualhosts

Manipulate Apache virtualhosts

Resource

Operation

Description

DELETE /v2/storage/(uuid)/virtualhost/(vhost_id)

POST /v2/storage/virtualhost/check-multiple

GET /v2/storage/virtualhost/check-multiple

Virtualhost

GET /v2/storage/virtualhost/assigned/(fqdn)

list assigned virtualhosts

GET /v2/storage/(uuid)/virtualhost

list virtualhosts

GET /v2/storage/(uuid)/masked-virtualhost

list masked virtualhosts

GET /v2/storage/(uuid)/virtualhost/(vhost_id)

show virtualhost

POST /v2/storage/(uuid)/virtualhost

create virtualhost

PUT /v2/storage/(uuid)/virtualhost/(vhost_id)

update virtualhost

GET /v2/storage/virtualhost/assigned/(fqdn)

List of Virtualhost records assigned to specified subdomain. We only list Virtualhost containing specified subdomain, from non deleted, non disabled storage.

Example request:

GET /v2/storage/virtualhost/assigned/non-existing.example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - error:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "No vhost assigned for non-existing.example.com"
}
GET /v2/storage/(uuid)/virtualhost

List of Virtualhost records under this Storage.

GET /v2/storage/(uuid)/masked-virtualhost

List of Virtualhost records by masked storage id.

Query Parameters:
  • exclude_disabled – Excludes all disabled storage

Example request

GET /v2/storage/12345678-1234-1234-1234-123456789012/masked-virtualhost HTTP/1.1
Content-Type: application/json
Accept: application/json

Example request - full dump request

GET /v2/storage/12345678-1234-1234-1234-123456789012/masked-virtualhost?exclude_disabled=0 HTTP/1.1
Content-Type: application/json
Accept: application/json
GET /v2/storage/(uuid)/virtualhost/(vhost_id)

Show details of an existing Virtualhost record.

Example request:

GET /v2/<UUID>/virtualhost/<vhost_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "createTime": 1500292181,
    "default": true,
    "id": 892,
    "keepAliveOff": false,
    "logsOnStorage": "halka.sk/logs",
    "nonExistSubDomainsToWeb": false,
    "phpDefaultMysql": "mariadb55",
    "phpMaxExecutionTime": 30,
    "phpMemoryLimit": 64,
    "phpOpenBaseDir": false,
    "phpOpenBaseDirAll": false,
    "phpOpenBaseDirStorage": false,
    "phpOpenBaseWebInWeb": false,
    "phpPostMaxSize": 48,
    "phpRegisterGlobalsOff": false,
    "phpSafeModeOff": false,
    "phpUploadMaxFilesize": 48,
    "storage": {
        "createTime": 1486658172,
        "deleted": false,
        "deletedChangeTime": null,
        "disabled": false,
        "disabledChangeTime": null,
        "filesEnabled": true,
        "gid": 71360,
        "id": 757,
        "limitBytes": 13765221376,
        "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99",
        "scheduledToDelete": null,
        "server": {
            "group": "local",
            "host": "web-1",
            "id": 79
        },
        "storagePool": {
            "id": 2,
            "mountpoint": "/nfsmnt/hosting2_1"
        },
        "uid": 71360,
        "updateTime": 1539929920,
        "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99"
    },
    "sub": "",
    "subOnStorage": "halka.sk/sub",
    "webOnStorage": "halka.sk/web"
}
POST /v2/storage/(uuid)/virtualhost

Creates a Virtualhost record. This record is used to generate virtualhost configuration for our Apache webservers.

If redirTarget or maskedStorageId is specified, the configuration of the default Virtualhost on target Storage is used instead of default values to pre-populate this record’s configuration.

Request JSON Object:
  • sub (string) – Subdomain name (leave empty for main domain)

  • webOnStorage (string) – relative path to webroot (domain.tld/web)

  • subOnStorage (string) – relative path to subdomains root (domain.tld/sub)

  • logsOnStorage (string) – relative path to log directory (domain.tld/logs)

  • nonExistSubDomainsToWeb (bool)

  • keepAliveOff (bool) – unset keep-alive flag

  • phpSafeModeOff (bool) – unset PHP safe_mode

  • phpRegisterGlobalsOff (bool) – unset PHP register_globals

  • phpOpenBaseDir (bool) – PHP open_basedir directive

  • phpOpenBaseDirAll (bool) – PHP open_basedir directive

  • phpOpenBaseWebInWeb (bool) – PHP open_basedir directive

  • phpOpenBaseDirStorage (bool) – PHP open_basedir directive

  • phpDefaultMysql (string) – one of mysql50, mysql51, mysql57, mysql80, mariadb55, mariadb101, mariadb103, mariadb105

  • phpMaxExecutionTime (int) – default 30 (s)

  • phpMemoryLimit (int) – default 128 (M)

  • phpUploadMaxFilesize (int) – default 48 (M)

  • phpPostMaxSize (int) – default 48 (M)

  • redirTarget (string) – domain name

  • maskedStorageId (int) – id of a masked Storage

  • entity (string) – Company name abbreviation, used to select the correct index template file (default sk-ws)

Example request:

POST /v2/<UUID>/virtualhost HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "sub": "blog",
    "phpMemoryLimit": 256,
    "webOnStorage": "halka.sk/sub/blog",
    "entity": "sk-ws"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "createTime": 1500292181,
        "id": 892,
        "default": false,
        "keepAliveOff": false,
        "logsOnStorage": "halka.sk/logs",
        "nonExistSubDomainsToWeb": false,
        "phpDefaultMysql": "mariadb55",
        "phpMaxExecutionTime": 30,
        "phpMemoryLimit": 64,
        "phpOpenBaseDir": false,
        "phpOpenBaseDirAll": false,
        "phpOpenBaseDirStorage": false,
        "phpOpenBaseWebInWeb": false,
        "phpPostMaxSize": 48,
        "phpRegisterGlobalsOff": false,
        "phpSafeModeOff": false,
        "phpUploadMaxFilesize": 48,
        "storage": {
            "createTime": 1486658172,
            "deleted": false,
            "deletedChangeTime": null,
            "disabled": false,
            "disabledChangeTime": null,
            "filesEnabled": true,
            "gid": 71360,
            "id": 757,
            "limitBytes": 13765221376,
            "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99",
            "scheduledToDelete": null,
            "server": {
                "group": "local",
                "host": "web-1",
                "id": 79
            },
            "storagePool": {
                "id": 2,
                "mountpoint": "/nfsmnt/hosting2_1"
            },
            "uid": 71360,
            "updateTime": 1539929920,
            "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99"
        },
        "sub": "blog",
        "subOnStorage": "",
        "webOnStorage": "halka.sk/sub/blog"
    }
}
PUT /v2/storage/(uuid)/virtualhost/(vhost_id)

Update an existing Virtualhost record.

Request JSON Object:
  • webOnStorage (string) – relative path to webroot (domain.tld/web)

  • subOnStorage (string) – relative path to subdomains root (domain.tld/sub)

  • logsOnStorage (string) – relative path to log directory (domain.tld/logs)

  • nonExistSubDomainsToWeb (bool)

  • keepAliveOff (bool) – unset keep-alive flag

  • phpSafeModeOff (bool) – unset PHP safe_mode

  • phpRegisterGlobalsOff (bool) – unset PHP register_globals

  • phpOpenBaseDir (bool) – PHP open_basedir directive

  • phpOpenBaseDirAll (bool) – PHP open_basedir directive

  • phpOpenBaseWebInWeb (bool) – PHP open_basedir directive

  • phpOpenBaseDirStorage (bool) – PHP open_basedir directive

  • phpDefaultMysql (string) – one of mysql50, mysql51, mysql57, mysql80, mariadb55, mariadb101, mariadb103, mariadb105

  • phpMaxExecutionTime (int) – default 30 (s)

  • phpMemoryLimit (int) – default 128 (M)

  • phpUploadMaxFilesize (int) – default 48 (M)

  • phpPostMaxSize (int) – default 48 (M)

  • redirTarget (string) – UUID of a masked Storage

  • maskedStorageId (int) – id of a masked Storage

DELETE /v2/storage/(uuid)/virtualhost/(vhost_id)

Removes a Virtualhost record. The associated database record will be removed permanently without the possibility of a later recovery, but hosting data will remain unaffected. The attempt will fail if there is at least a single Service pointing to the Virtualhost. Default Virtualhost cannot be deleted.

Example request:

DELETE /v1/<UUID>/virtualhost/<vhost_id> HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "createTime": 1500292181,
        "default": true,
        "id": 892,
        "keepAliveOff": false,
        "logsOnStorage": "halka.sk/logs",
        "nonExistSubDomainsToWeb": false,
        "phpDefaultMysql": "mariadb55",
        "phpMaxExecutionTime": 30,
        "phpMemoryLimit": 64,
        "phpOpenBaseDir": false,
        "phpOpenBaseDirAll": false,
        "phpOpenBaseDirStorage": false,
        "phpOpenBaseWebInWeb": false,
        "phpPostMaxSize": 48,
        "phpRegisterGlobalsOff": false,
        "phpSafeModeOff": false,
        "phpUploadMaxFilesize": 48,
        "storage": {
            "createTime": 1486658172,
            "deleted": false,
            "deletedChangeTime": null,
            "disabled": false,
            "disabledChangeTime": null,
            "filesEnabled": true,
            "gid": 71360,
            "id": 757,
            "limitBytes": 13765221376,
            "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99",
            "scheduledToDelete": null,
            "server": {
                "group": "local",
                "host": "web-1",
                "id": 79
            },
            "storagePool": {
                "id": 2,
                "mountpoint": "/nfsmnt/hosting2_1"
            },
            "uid": 71360,
            "updateTime": 1539929920,
            "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99"
        },
        "sub": "",
        "subOnStorage": "halka.sk/sub",
        "webOnStorage": "halka.sk/web"
    },
    "error": null
}

Example response - Attempt to delete default Virtualhost:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Cannot delete default Virtualhost."
}
POST /v2/storage/virtualhost/check-multiple

Get a list of Virtualhost records on Storages specified by a list of UUIDs.

Example request:

GET /v2/storage/virtualhost/check-multiple HTTP/1.1
Content-Type: application/json
Accept: application/json

["625eb1d4-6b66-4d89-9101-5bf200f18b99"]

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "createTime": 1371758257,
            "id": 862,
            "keepAliveOff": true,
            "logsOnStorage": "halka.sk/logs",
            "nonExistSubDomainsToWeb": true,
            "phpDefaultMysql": "mariadb101",
            "phpMaxExecutionTime": 60,
            "phpMemoryLimit": 128,
            "phpOpenBaseDir": false,
            "phpOpenBaseDirAll": false,
            "phpOpenBaseDirStorage": false,
            "phpOpenBaseWebInWeb": false,
            "phpPostMaxSize": 96,
            "phpRegisterGlobalsOff": true,
            "phpSafeModeOff": true,
            "phpUploadMaxFilesize": 96,
            "sub": "",
            "default": true,
            "subOnStorage": "halka.sk/sub",
            "webOnStorage": "halka.sk/web"
        },

    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/storage/virtualhost/check-multiple

Get a list of Virtualhost records on Storages specified by a list of UUIDs.

Example request:

GET /v2/storage/virtualhost/check-multiple HTTP/1.1
Content-Type: application/json
Accept: application/json

["625eb1d4-6b66-4d89-9101-5bf200f18b99"]

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "createTime": 1371758257,
            "id": 862,
            "keepAliveOff": true,
            "logsOnStorage": "halka.sk/logs",
            "nonExistSubDomainsToWeb": true,
            "phpDefaultMysql": "mariadb101",
            "phpMaxExecutionTime": 60,
            "phpMemoryLimit": 128,
            "phpOpenBaseDir": false,
            "phpOpenBaseDirAll": false,
            "phpOpenBaseDirStorage": false,
            "phpOpenBaseWebInWeb": false,
            "phpPostMaxSize": 96,
            "phpRegisterGlobalsOff": true,
            "phpSafeModeOff": true,
            "phpUploadMaxFilesize": 96,
            "sub": "",
            "default": true,
            "subOnStorage": "halka.sk/sub",
            "webOnStorage": "halka.sk/web"
        },

    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}

SSL

Add and manipulate SSL certificates

Resource

Operation

Description

POST /v2/storage/(uuid)/service/(service_id)/ssl

PUT /v2/storage/(uuid)/service/(service_id)/ssl

CSR

POST /v2/storage/csr

generate CSR

SSL

GET /v2/storage/(uuid)/ssl

list certificates

GET /v2/storage/by-domain/(domain)/ssl

public ip by domain

GET /v2/storage/(uuid)/ssl/(ssl_id)

get certificate by id

GET /v2/storage/(uuid)/ssl/dns/(name)

get certificate by name

POST /v2/storage/(uuid)/ssl

install new certificate

PUT /v2/storage/(uuid)/ssl/(ssl_id)

update an existing certificate

DELETE /v2/storage/(uuid)/ssl/(ssl_id)

delete certificate

GET /v2/storage/(uuid)/ssl

List SSL certificates.

Example request:

GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "activeCount": 2,
            "activeDomains": "*.example.com,example.com",
            "activeServiceIds": [
                2017537
            ],
            "activeSubdomains": [
                "*.example.com",
                "example.com"
            ],
            "altNames": "*.example.com,example.com",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "expireDate": 1574321006,
            "id": 179227,
            "key": "-----BEGIN RSA PRIVATE KEY----- ...",
            "subject": "CN=*.example.com"
        }
    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/storage/by-domain/(domain)/ssl

Get ssl cert for host (domain or subdomain). Returns pem format.

Status Codes:

Example request

GET /v2/storage/by-domain/nahodnadomenatest.sk/ssl HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

"-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDX05H6+/6xK7TE
465yBfclc1M2n/XRiyIxbYLqsoqyQqgvwrjeeOz+er4wloLWvF7OQ8nrp2SW/dwq
qNSsOFgmBDoSukFzgugd20/z+MCcMkeWRQlJMVaXuWKVSBTdZLFVpif1VQDvCYHx
lUSxasRGDunjd4sPQs90bzCm/Y8cVbXqIb/6OGIPqRc0JCm8SVNqeBwPe0iWxjOK
+dlEwV8lJhIzw6VLTHrMA/8ku0sCHcQcIsB8igymNPrGfau+zkSgOHgiRXj/0awn
pdmjRpHy6FCbZy0kdkJbSHZu1SyKuJSDNq2GV4sNjVetY9qIMSe6BW+i9+QMNrg0
tv0e0ku7AgMBAAECggEBAIpWYzCDy0mWoSS+Z3dQmYyYshLGTxMD4mPaNNrom/wM
u675WfPHgOjQlg2gu7aWQRJm4ws4XUJm73MsijzlVKLxfKO6XO+ETfGtPD8+B39W
vwnzsDMI+97+hdD3xd/uhbhHaz9WP+X3qyHFMqWhsLLTJlmVqz2Z7k1MY9v1lIBs
xntHG4i66NTxRcD78+KtRhSLjePpcjIvQxA94VFZoukQ7TRSM7PPzQo6XI7CMGZi
BMQFewOQ4v9O6MspgzUM3xC5bpvD8orYY4NhL0JZzKfJSI5Gvn4JxeGORKm4QNyg
aKQ8SlDLAuJ6R35p08pcX3p4cPEwIoQxRD/4EeQVnIECgYEA6+h4HoFlDOrW+sBh
kSy9KP2owQfCiE5DVdg9K+YNHFuQlYSCe13XMFx/N457nr0q4LAyge+QE5Q97nZT
0CTgu2AbCGgj0ovlXfgTDS30DVL5yxvcmh2exfLhhVqm7HP3LtKwSpXn7csoa9Md
GrLjpPvrgORw+X4awSEVeO3vHXsCgYEA6jVCQW8iDFloO2KIl4h3DouKDjc67dur
86WBviCta+zdSAwaiEjKCbVt3E549rgNzK8Ql54SRGTBb8U5vkKgrmKQBilol1cl
hZodTePlQsRZ5kug/xKQvqZnYRD7UUA+R0T0zFm3wOnmJkL0chT8hPx4Ve8SuDDC
Xwx8jkallsECgYBiFCl0jVlk0HIGmFs4D0CpvSQe9Mn0/4zRMPDlwmRrCMqIzyms
fqxLp/kgMPXGXmFoPvkQunfNHBHPhZR88ggY/vDeQuW50H3Q3qWVEijoLTo7Ll8+
F9h99ee7GKBTqDb5WZD/wWlGnPM2OPRduEgavL4BvXgW0k3vQ4D44PtL5wKBgFIV
cnAue/dqCm7tvMOnL1roqu0KjFu65swQ0KULHNy7el56532mTTET5joVQq3tmeCH
5r/Mxcg0q9r5e6BkB562qpWOQ7ru7xahCe43li1NVdix3u4m2pYHCipp4jr60hj2
YPmR5CX3lBMK2lN1aX9OYPp1PNFTPXxEiw7uUbDBAoGBANWjc5EiQnDpWyLyX7Gs
WjOkkZZgn/06zbhh25Bo0bFHaHOIqEjKs263AEOm3kpBDPNKTx5AREOwvY3D6Lxj
jPO4HDt891zoHhfvxoI0hqbETZWB2wuoZAKWEz7GK2wd2otv4hrRpAwr7EjpyBd4
YDQLO3F48GP5q2CJaX9OSKBP
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDUTCCAjmgAwIBAgIUQC5j3NFS1rnJHPqFQ4L0Z6N1AhQwDQYJKoZIhvcNAQEL
BQAwODE2MDQGA1UEAwwtbmFob2RuYWRvbWVuYXRlc3Quc2ssd3d3Lm5haG9kbmFk
b21lbmF0ZXN0LnNrMB4XDTE5MDkyNzEyMzkyMFoXDTIwMDkyNjEyMzkyMFowODE2
MDQGA1UEAwwtbmFob2RuYWRvbWVuYXRlc3Quc2ssd3d3Lm5haG9kbmFkb21lbmF0
ZXN0LnNrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19OR+vv+sSu0
xOOucgX3JXNTNp/10YsiMW2C6rKKskKoL8K43njs/nq+MJaC1rxezkPJ66dklv3c
KqjUrDhYJgQ6ErpBc4LoHdtP8/jAnDJHlkUJSTFWl7lilUgU3WSxVaYn9VUA7wmB
8ZVEsWrERg7p43eLD0LPdG8wpv2PHFW16iG/+jhiD6kXNCQpvElTangcD3tIlsYz
ivnZRMFfJSYSM8OlS0x6zAP/JLtLAh3EHCLAfIoMpjT6xn2rvs5EoDh4IkV4/9Gs
J6XZo0aR8uhQm2ctJHZCW0h2btUsiriUgzathleLDY1XrWPaiDEnugVvovfkDDa4
NLb9HtJLuwIDAQABo1MwUTAdBgNVHQ4EFgQUisTox6jIrWXF6gpfEI2d/2XOcCEw
HwYDVR0jBBgwFoAUisTox6jIrWXF6gpfEI2d/2XOcCEwDwYDVR0TAQH/BAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAQEA01u4sI3iUWbkbw27OmT78stHDCJGIxW4rQpW
8OKJXdFBxD2Z5UvEpoGk+L5H9f+NimX5LUd594n6rX9qOcN6qD0U6hv0f2Jt9AX/
sRzLwBGGLXBZN5coe8gJidt6nXAOdgh405TLqDEJQQJaXcGLAioq9TbLTmdzV+7O
081G+MNoaBF3LPavJOxXuF6fZ3C/+c9CGE7Pd0VwIJeOkjwcWGKYfcmCZfjj6+ze
CfHGMAXP184tXY5a6MCHsdONvDSvutohY1xe23R2ErYmhKbIj5/GVpg4Mq69MAiX
QSiNlgVi73xmijzT6R+vfPsg93llz3LKEkBsg7jvrt8Gfe2i3Q==
-----END CERTIFICATE-----"

Example response - not found

HTTP/1.1 404 NOT FOUND
Content-Type: application/json

{
    "error": "SSL for domain not found"
}
GET /v2/storage/(uuid)/ssl/(ssl_id)

Get SSL certificate by id.

Example request:

GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl/179227 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "activeCount": 2,
    "activeDomains": "*.example.com,example.com",
    "activeServiceIds": [
        2017537
    ],
    "activeSubdomains": [
        "*.example.com",
        "example.com"
    ],
    "altNames": "*.example.com,example.com",
    "cert": "-----BEGIN CERTIFICATE----- ...",
    "chain": "-----BEGIN CERTIFICATE----- ...",
    "expireDate": 1574321006,
    "id": 179227,
    "key": "-----BEGIN RSA PRIVATE KEY----- ...",
    "subject": "CN=*.example.com"
}
GET /v2/storage/(uuid)/ssl/dns/(name)

Get SSL certificate(s) by DNS identifier.

Example request:

GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl/dns/*.example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "activeCount": 2,
            "activeDomains": "*.example.com,example.com",
            "activeServiceIds": [
                2017537
            ],
            "activeSubdomains": [
                "*.example.com",
                "example.com"
            ],
            "altNames": "*.example.com,example.com",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "expireDate": 1574321006,
            "id": 179227,
            "key": "-----BEGIN RSA PRIVATE KEY----- ...",
            "subject": "CN=*.example.com"
        }
    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}
POST /v2/storage/(uuid)/ssl

Insert a new SSL certificate. Optionally specify which FQDNs should use this certificate by passing them in the domains parameter.

Request JSON Object:
  • key (string) – SSL certificate key

  • cert (string) – SSL certificate

  • chain (string) – CA intermediate certificate chain

  • domains[string] (list) – list of FQDNs that should use this cert

  • activeServiceIds[int] (list) – list of service IDs that should use this cert

Key, cert and chain should pe posted as one-liners. Using activeServiceIds is not recommended and only here for convenience. It will get a list of subdomains from indicated services and proceed as if a list of domains was passed; there is no FK relation.

Status Codes:

Example request:

POST /v1/<UUID>/ssl HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "cert": "-----BEGIN CERTIFICATE----- ...",
    "key": "-----BEGIN PRIVATE KEY----- ...",
    "chain": "-----BEGIN CERTIFICATE----- ...",
    "domains": ["nicereply.com", "*.nicereply.com"]
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "async_tasks": {
        "set_mcdb": "69eb2d28-c4af-11e9-91cb-9ffaf0077f08"
    },
    "item": {
        "id": 1,
        "key": "-----BEGIN PRIVATE KEY----- ...",
        "cert": "-----BEGIN CERTIFICATE----- ...",
        "chain": "-----BEGIN CERTIFICATE----- ...",
        "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.",
        "altNames": "nicereply.com,*.nicereply.com",
        "expireDate": 1534431694,
        "activeCount": 1,
        "activeDomains": "nicereply.com,*.nicereply.com",
        "activeSubdomains": ["nicereply.com", "*.nicereply.com"],
        "activeServiceIds": []
    }
}

Example response - Storage not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "status": "error",
    "error": "Storage does not exist"
}
PUT /v2/storage/(uuid)/ssl/(ssl_id)

Update an existing SSL certificate.

Request JSON Object:
  • key (string) – SSL certificate key

  • cert (string) – SSL certificate

  • chain (string) – CA intermediate certificate chain

  • domains[string] (list) – list of FQDNs that should use this cert

  • activeServiceIds[int] (list) – list of service IDs that should use this certificate

DELETE /v2/storage/(uuid)/ssl/(ssl_id)

Delete an SSL certificate along with active configurations.

DELETE /v2/storage/a17fb16a-c5a3-11e9-a37e-f78545774a41/ssl/1234 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "altNames": "example.com",
        "cert": "-----BEGIN CERTIFICATE----- ...",
        "chain": "-----BEGIN CERTIFICATE----- ...",
        "createDate": 1536953064.0,
        "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
        "domain": "example.com",
        "expireDate": 1536283780.0,
        "id": 1234,
        "key": "-----BEGIN RSA PRIVATE KEY----- ...",
        "renewalDate": 1538518570.0,
        "renewalError": null,
        "revoked": true,
        "subject": "CN=example.com"
    }
}
POST /v2/storage/(uuid)/service/(service_id)/ssl

Sets SSL certificate that will be used by this service (or more precisely, the FQDN that is associated with this service).

Pass either storageSSLId to use an existing certificate, key, cert and chain to create a new certificate, or both to update an existing certificate (useful when doing a renewal).

Note for the latter: since more services may share the same subdomain, and many services may use a single SSL certificate, updating an existing certificate here will also effectively update it for all other services that were using it. If this behavior is undesirable, simply omit storageSSLId.

Request JSON Object:
  • storageSSLId (int) – ID of an existing SSL certificate

  • key (string) – SSL certificate key

  • cert (string) – SSL certificate

  • chain (string) – CA intermediate certificate chain

Example request:

POST /v1/<UUID>/service/1/ssl HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "cert": "-----BEGIN CERTIFICATE----- ...",
    "key": "-----BEGIN PRIVATE KEY----- ...",
    "chain": "-----BEGIN CERTIFICATE----- ..."
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "storageSSL": {
            "id": 1,
            "key": "-----BEGIN PRIVATE KEY----- ...",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.",
            "altNames": "nicereply.com,*.nicereply.com",
            "expireDate": 1534431694,
            "activeCount": 1,
            "activeDomains": "nicereply.com,*.nicereply.com",
            "activeSubdomains": ["nicereply.com", "*.nicereply.com"],
            "activeServiceIds": [1]
        },
    "sub": ""
    }
}
PUT /v2/storage/(uuid)/service/(service_id)/ssl

Sets SSL certificate that will be used by this service (or more precisely, the FQDN that is associated with this service).

Pass either storageSSLId to use an existing certificate, key, cert and chain to create a new certificate, or both to update an existing certificate (useful when doing a renewal).

Note for the latter: since more services may share the same subdomain, and many services may use a single SSL certificate, updating an existing certificate here will also effectively update it for all other services that were using it. If this behavior is undesirable, simply omit storageSSLId.

Request JSON Object:
  • storageSSLId (int) – ID of an existing SSL certificate

  • key (string) – SSL certificate key

  • cert (string) – SSL certificate

  • chain (string) – CA intermediate certificate chain

Example request:

POST /v1/<UUID>/service/1/ssl HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "cert": "-----BEGIN CERTIFICATE----- ...",
    "key": "-----BEGIN PRIVATE KEY----- ...",
    "chain": "-----BEGIN CERTIFICATE----- ..."
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "storageSSL": {
            "id": 1,
            "key": "-----BEGIN PRIVATE KEY----- ...",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.",
            "altNames": "nicereply.com,*.nicereply.com",
            "expireDate": 1534431694,
            "activeCount": 1,
            "activeDomains": "nicereply.com,*.nicereply.com",
            "activeSubdomains": ["nicereply.com", "*.nicereply.com"],
            "activeServiceIds": [1]
        },
    "sub": ""
    }
}
POST /v2/storage/csr

Provision a new CSR.

A new RSA private key is generated for each request.

<json string domain:

desired Common Name of the certificate

<json string organization:

Organization Name (optional, default: “Websupport, s.r.o.”)

<json string organization_unit:

Organizational Unit Name (optional, default: “IT”)

<json string city:

Location (optional, default: “Bratislava”)

<json string state:

State or Province Name (optional, default: “Slovakia”)

<json string country:

Country Name (optional, default: “SK”)

Example request:

POST /v2/storage/csr HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "domain": "example.com"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 12345,
        "createTime": 1607152713,
        "domain": "example.com",
        "csr": "-----BEGIN CERTIFICATE REQUEST-----
MIIEyzCCAr …”,

“rsa_key”: “—–BEGIN RSA PRIVATE KEY—–

MIIJKQIBAA …”,

}

}

LetsEncrypt

Issue and revoke free SSL certificates using LetsEncrypt API

Resource

Operation

Description

GET /.well-known/acme-challenge/ping

GET /.well-known/acme-challenge/(token)

GET /v2/letsencrypt/challenge/(token)

GET /v2/letsencrypt/account

GET /v2/letsencrypt/account/(int:account_id)

PUT /v2/letsencrypt/account/(int:account_id)/enable

DELETE /v2/letsencrypt/account/(int:account_id)

PUT /v2/letsencrypt/account/(int:account_id)/disable

POST /v2/letsencrypt/account

POST /v2/letsencrypt/new-account

LetsEncrypt

GET /v2/letsencrypt/(domain)

list domain certificates

GET /v2/letsencrypt/(domain)/(ssl_id)

get certificate

GET /v2/letsencrypt/(domain)/(ssl_id)/ari-info

get ARI information

DELETE /v2/letsencrypt/(domain)/(ssl_id)

delete certificate

PUT /v2/letsencrypt/(domain)/(ssl_id)

renew certificate

PUT /v2/letsencrypt/renew/(ssl_id)

POST /v2/letsencrypt/(domain)

issue a new certificate

POST /v2/letsencrypt/(domain)/async

issue a new certificate for domain with active Storage.

PUT /v2/letsencrypt/revoke/(ssl_id)

revoke certificate

GET /.well-known/acme-challenge/ping

Returns “pong”.

Used to check whether the Nginx passthrough for http-01 challenges is set up correctly. If a request to http://<domain>/.well-known/acme-challenge/ping returns “pong”, we’re able to issue non-wildcard certificates for it.

GET /.well-known/acme-challenge/(token)
GET /v2/letsencrypt/challenge/(token)

Returns an encoded response to a LetsEncrypt http-01 challenge.

Used for issuing non-wildcard certificates using LetsEncrypt.

GET /v2/letsencrypt/account

List known LetsEncrypt accounts.

GET /v2/letsencrypt/account/(int: account_id)

Show LetsEncrypt account details.

PUT /v2/letsencrypt/account/(int: account_id)/enable

Enable a LetsEncrypt account.

DELETE /v2/letsencrypt/account/(int: account_id)

Disable a LetsEncrypt account.

PUT /v2/letsencrypt/account/(int: account_id)/disable

Disable a LetsEncrypt account.

POST /v2/letsencrypt/account
POST /v2/letsencrypt/new-account

Create a new LetsEncrypt account.

Generates a new private key, requests a new account via LetsEncrypt API, and stores both the key and account url (“kid”) to database.

https://tools.ietf.org/html/draft-ietf-acme-acme#section-7.3

Example request:

POST /v2/letsencrypt/account HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "message": "Registered",
    "kid": "https://acme-v02.api.letsencrypt.org/acme/acct/12345678"
    "item": {
        "id": 1,
        "kid": "https://acme-v02.api.letsencrypt.org/acme/acct/12345678",
        "active": True,
        "comment": None,
        "createTime": 1234567890,
        "updateTime": 1234567890
    }
}
GET /v2/letsencrypt/(domain)

List LetsEncrypt certificates issued for domain.

GET /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "altNames": "test.example.com",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "createDate": 1536953064.0,
            "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
            "domain": "example.com",
            "expireDate": 1536283780.0,
            "id": 54727,
            "key": "-----BEGIN RSA PRIVATE KEY----- ...",
            "renewalDate": 1538518570.0,
            "renewalError": "http-01: NXDOMAIN looking up A for test.example.com",
            "revoked": false,
            "subject": "CN=test.example.com"
        },
        {
            "altNames": "example.com,www.example.com",
            "cert": "-----BEGIN CERTIFICATE----- ...",
            "chain": "-----BEGIN CERTIFICATE----- ...",
            "createDate": 1546953064.0,
            "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
            "domain": "example.com",
            "expireDate": 1566283780.0,
            "id": 54728,
            "key": "-----BEGIN RSA PRIVATE KEY----- ...",
            "renewalDate": 1558518570.0,
            "renewalError": null,
            "revoked": false,
            "subject": "CN=www.example.com"
        }
    ],
    "pager": {
        "items": 2,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/letsencrypt/(domain)/(ssl_id)

Get a LetsEncrypt certificate by domain and id.

GET /v2/letsencrypt/example.com/54728 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "altNames": "example.com,www.example.com",
    "cert": "-----BEGIN CERTIFICATE----- ...",
    "chain": "-----BEGIN CERTIFICATE----- ...",
    "createDate": 1546953064.0,
    "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
    "domain": "example.com",
    "expireDate": 1566283780.0,
    "id": 54728,
    "key": "-----BEGIN RSA PRIVATE KEY----- ...",
    "renewalDate": 1558518570.0,
    "renewalError": null,
    "revoked": false,
    "subject": "CN=www.example.com"
}
GET /v2/letsencrypt/(domain)/(ssl_id)/ari-info

Get ARI information for a certificate by domain and id.

Displays ARI certificate ID and ideal renewal window - both one that’s requested from ACME API directly, and one we calculate by ourselves. These don’t always line up completely.

GET /v2/letsencrypt/example.com/54728/ari HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "ari_id": "56ufDywzoFPTXk94yLKEDjvWkjM.BhQl0s4X-V6_3yZYTelHzyQ6",
    "ari_url": "https://acme-v02.api.letsencrypt.org/acme/renewal-info/56ufDywzoFPTXk94yLKEDj...",
    "ari_response": {
        "suggestedWindow": {
            "start": "2025-11-16T19:08:00Z",
            "end": "2025-11-18T14:18:49Z"
        }
    },
    "calculated_renewal_window": {
        "start": "2025-11-16T19:08:00+00:00",
        "end": "2025-11-18T14:18:49+00:00",
    }
}
DELETE /v2/letsencrypt/(domain)/(ssl_id)

Delete a LetsEncrypt certificate. For revoking the certificate first, see /v2/letsencrypt/revoke/<ssl_id>.

This method does not deactivate certificates that are set up via /v2/storage/<UUID>/ssl , as they use a different certificate store.

GET /v2/letsencrypt/example.com/54728 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "altNames": "example.com,www.example.com",
        "cert": "-----BEGIN CERTIFICATE----- ...",
        "chain": "-----BEGIN CERTIFICATE----- ...",
        "createDate": 1546953064.0,
        "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
        "domain": "example.com",
        "expireDate": 1566283780.0,
        "id": 54728,
        "key": "-----BEGIN RSA PRIVATE KEY----- ...",
        "renewalDate": 1558518570.0,
        "renewalError": null,
        "revoked": false,
        "subject": "CN=www.example.com"
    }
}
PUT /v2/letsencrypt/(domain)/(ssl_id)
PUT /v2/letsencrypt/renew/(ssl_id)

Renew a LetsEncrypt certificate.

Will attempt to match configured active certificates in other certificate stores and update them on successful renewal.

PUT /v2/letsencrypt/example.com/54728 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "altNames": "example.com,www.example.com",
        "cert": "-----BEGIN CERTIFICATE----- ...",
        "chain": "-----BEGIN CERTIFICATE----- ...",
        "createDate": 1546953064.0,
        "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
        "domain": "example.com",
        "expireDate": 1566283780.0,
        "id": 54728,
        "key": "-----BEGIN RSA PRIVATE KEY----- ...",
        "renewalDate": 1558518570.0,
        "renewalError": null,
        "revoked": false,
        "subject": "CN=www.example.com"
    },
    "async_tasks": {
        "set_mcdb": "ba27dfa6-c582-11e9-81d0-93ca4401da60"
    }
}
POST /v2/letsencrypt/(domain)

Request a new certificate from LetsEncrypt.

Uses DNS-01 challenge for wildcard certificates and HTTP-01 for all others. This means the domain has to either use our nameservers (wildcard certificates) or point the A record to our webservers (for regular certificates).

Example request - single certificate:

POST /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "subdomains": ["", "www"]
}

Example request - wildcard certificate:

POST /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "subdomains": ["*"]
}

Example request - mixed certificate:

POST /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "subdomains": ["", "*"]
}

Example request - wildcard certificate for 3rd level domain:

POST /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "subdomains": ["*.subdomain"]
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 1,
        "domain": "example.com",
        "csr": "---BEGIN CERTIFICATE REQUEST--- ...",
        "key": "---BEGIN RSA PRIVATE KEY--- ...",
        "cert": "---BEGIN CERTIFICATE--- ...",
        "chain": "---BEGIN CERTIFICATE--- ...",
        "subject": "CN=example.com",
        "altNames": "example.com,www.example.com",
        "revoked": false,
        "createDate": 1515582789.0,
        "expireDate": 1565905305.0,
        "renewalDate": 1515582789.0,
        "renewalError": null
    }
}

Example response - error:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "error",
    "error": {
        "domain": ["http-01: NXDOMAIN looking for example.com"]
    }
}
POST /v2/letsencrypt/(domain)/async

Request a new certificate from LetsEncrypt for domain with active Storage.

Uses DNS-01 challenge for wildcard certificates and HTTP-01 for all others. This means the domain has to either use our nameservers (wildcard certificates) or point the A record to our webservers (for regular certificates).

Request JSON Object:
  • subdomains (list[str]) – List of subdomains to issue the certificate for.

  • delay (int) – Time in seconds to wait before issuing the certificate.

Example request - single certificate:

POST /v2/letsencrypt/example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "subdomains": ["", "www"],
    "delay": 600
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "task_id": "45f0318f-32lb-4x58-af40-fafd213e95ce"
}
PUT /v2/letsencrypt/revoke/(ssl_id)

Revoke a LetsEncrypt certificate via ACME API. Does not attempt to revoke already expired certificates, but will simply mark them as evoked.

PUT /v2/letsencrypt/revoke/1234 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "altNames": "example.com",
        "cert": "-----BEGIN CERTIFICATE----- ...",
        "chain": "-----BEGIN CERTIFICATE----- ...",
        "createDate": 1536953064.0,
        "csr": "-----BEGIN CERTIFICATE REQUEST----- ...",
        "domain": "example.com",
        "expireDate": 1536283780.0,
        "id": 1234,
        "key": "-----BEGIN RSA PRIVATE KEY----- ...",
        "renewalDate": 1538518570.0,
        "renewalError": null,
        "revoked": true,
        "subject": "CN=example.com"
    }
}

FTP

Add, remove and configure FTP accounts

Resource

Operation

Description

PUT /v2/storage/(uuid)/ftp

FTP

GET /v2/storage/(uuid)/ftp

list FTP accounts for Storage

POST /v2/storage/ftp/check-multiple

list FTP accounts for multiple Storages

GET /v2/storage/ftp/check-multiple

GET /v2/storage/(uuid)/ftp/(ftp_id)

get FTP account by id

POST /v2/storage/(uuid)/ftp

create FTP account

PUT /v2/storage/(uuid)/ftp/(ftp_id)

update an FTP account by id

DELETE /v2/storage/(uuid)/ftp/(ftp_id)

delete an FTP account by id

GET /v2/storage/ftp/check-duplicity/(login)

check login for duplicates

Temporary FTP

GET /v2/storage/(uuid)/temporary-ftp

get temporary FTP account details

POST /v2/storage/(uuid)/temporary-ftp

create temporary FTP account

DELETE /v2/storage/(uuid)/temporary-ftp

delete temporary FTP account

GET /v2/storage/(uuid)/ftp

List of all FTP accounts under Storage specified by UUID.

Example request:

GET /v2/<UUID>/ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "countries": [
                "SK",
                "CZ",
                "HU"
            ],
            "countryCheck": true,
            "createTime": 1489736457,
            "dir": "",
            "disabled": false,
            "ftpEnabled": true,
            "id": 2,
            "ipCheck": false,
            "ips": [],
            "ips_v6": [],
            "login": "example.com",
            "note": "",
            "password": "{sha256}qEg6b/jphztLRYC3wd0fo+YmIGqWRpIJ1veWfCl86wY=",
            "sshEnabled": true,
            "storage": {
                "id": 55363,
                "createTime": 1411978388,
                "updateTime": 1411978388,
                "uuid": "816e9892-c580-11e8-b389-fba089f55f59"
                "domain": "example.com",
                "uid": 1005,
                "gid": 1005,
                "limitBytes": 0,
                "disabled": false,
                "deleted": false,
                "disabledChangeTime": null,
                "deletedChangeTime": null,
                "rootPath": "/data/e/x/example.com",
                "storagePool": {
                    "id": 1,
                },
                "server": {
                    "id": 3,
                    "host": "web-1",
                    "group": "it13",
                },
                "filesEnabled": true,
                "scheduledToDelete": null
            },
            "temporary": false
        }
    ],
    "pager": {
        "items": 1,
        "page": 1,
        "pagesize": null
    }
}
POST /v2/storage/ftp/check-multiple

List FTP accounts for Storages specified in the POST request.

Request JSON Object:
  • data (obj) – list of UUIDs

Query Parameters:
  • draw – draw parameter

  • page – page offset number (default is 1)

  • pagesize – page size; return all results if omitted

  • search – filter results by searching in all columns

  • search.column_name – filter results by specified column

  • sort[column_name] – sort by column, set to “desc” or “reverse” for reverse sort

  • sort.column_name – same as above

  • sort – sort by column name

  • reverse – flags previous sort key as reverse, accepts “true”/”false” (default “false”)

Response JSON Object:
  • recordsTotal – total record count before filtering

  • recordsFiltered – total record count after filtering (using search* query parameters)

  • pager.page – current page

  • pager.pagesize – page size

  • pager.items – number of records displayed on current page

Filtering results

Results may be filtered by passing either search=substring or search.<column name>=substring in the query string.

Only top-level objects are searched, filtering in nested object contents is not supported.

Sorting results

Chaining sort expressions is supported, order in which they appear in the query string is taken into consideration. sort[name]=desc is the same as sort.name=desc is the same as sort=name&reverse=true.

Paging

Use pagesize query parameter to specify page size, and page to specify page number. Negative values are not supported.

Example request

GET /v2/storage/ftp/check-multiple?draw=123&search.login=test&sort.login=desc HTTP/1.1
Content-Type: application/json
Accept: application/json

["625eb1d4-6b66-4d89-9101-5bf200f18b99"]

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "draw": 123,
    "items": [
        {
            "id": 1,
            "login": "testing",
            "comment": "fields omitted for brevity"
            "storage": {
                "id": 12345,
                "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99",
                "domain": "example.com"
            }
        }
    ],
    "pager": {
        "items": 2,
        "page": 1,
        "pagesize": 2
    },
    "recordsFiltered": 2,
    "recordsTotal": 3
}
GET /v2/storage/ftp/check-multiple

List FTP accounts for Storages specified in the POST request.

Request JSON Object:
  • data (obj) – list of UUIDs

Query Parameters:
  • draw – draw parameter

  • page – page offset number (default is 1)

  • pagesize – page size; return all results if omitted

  • search – filter results by searching in all columns

  • search.column_name – filter results by specified column

  • sort[column_name] – sort by column, set to “desc” or “reverse” for reverse sort

  • sort.column_name – same as above

  • sort – sort by column name

  • reverse – flags previous sort key as reverse, accepts “true”/”false” (default “false”)

Response JSON Object:
  • recordsTotal – total record count before filtering

  • recordsFiltered – total record count after filtering (using search* query parameters)

  • pager.page – current page

  • pager.pagesize – page size

  • pager.items – number of records displayed on current page

Filtering results

Results may be filtered by passing either search=substring or search.<column name>=substring in the query string.

Only top-level objects are searched, filtering in nested object contents is not supported.

Sorting results

Chaining sort expressions is supported, order in which they appear in the query string is taken into consideration. sort[name]=desc is the same as sort.name=desc is the same as sort=name&reverse=true.

Paging

Use pagesize query parameter to specify page size, and page to specify page number. Negative values are not supported.

Example request

GET /v2/storage/ftp/check-multiple?draw=123&search.login=test&sort.login=desc HTTP/1.1
Content-Type: application/json
Accept: application/json

["625eb1d4-6b66-4d89-9101-5bf200f18b99"]

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "draw": 123,
    "items": [
        {
            "id": 1,
            "login": "testing",
            "comment": "fields omitted for brevity"
            "storage": {
                "id": 12345,
                "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99",
                "domain": "example.com"
            }
        }
    ],
    "pager": {
        "items": 2,
        "page": 1,
        "pagesize": 2
    },
    "recordsFiltered": 2,
    "recordsTotal": 3
}
GET /v2/storage/(uuid)/ftp/(ftp_id)

Get FTP account details by its ID

POST /v2/storage/(uuid)/ftp

Create an FTP account.

Required parameters:

Request JSON Object:
  • login (string) – desired FTP login

  • password (string) – FTP password in plaintext

  • dir (string) – relative directory

Optional parameters:

Request JSON Object:
  • note (string) – text comment

  • ipCheck (bool) – enable login restriction by IP address/range

  • countryCheck (bool) – enable login restriction by country

  • ips (obj) – list of allowed IPs and/or ranges (CIDR format)

  • countries (obj) – list of ISO allowed country codes

  • disabled (bool)

  • ftpEnabled (bool) – enable/disable FTP access

  • sshEnabled (bool) – enable/disable SFTP access

Example request:

POST /v2/<UUID>/ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "login": "test.example.com",
    "password": "the stronkest password",
    "dir": "",
    "ipCheck": true,
    "ips": [
        "192.168.0.0/16"
    ],
    "ips_v6": [
            2a01::1/64"
        ],
    "countryCheck": true,
    "countries": [
        "SK",
        "CZ",
        "HU"
    ]
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 2,
        "login": "test.example.com",
        "password": "the stronkest password",
        "dir": "",
        "ipCheck": true,
        "ips": [
            "192.168.0.0/16"
        ],
        "ips_v6": [
            2a01::1/64"
        ],
        "countryCheck": true,
        "countries": [
            "SK",
            "CZ",
            "HU"
        ]
    }
}
PUT /v2/storage/(uuid)/ftp

Update all FTP accounts data on ingress servers.

Example request:

PUT /v2/<UUID>/ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items": [{
        "id": 2,
        "login": "test.example.com",
        "password": "the stronkest password",
        "dir": "",
        "ipCheck": true,
        "ips": [
            "192.168.0.0/16"
        ],
        "countryCheck": true,
        "countries": [
            "SK",
            "CZ",
            "HU"
        ]
    }]
    "async_tasks": ["625eb1d4-6b66-4d89-9101-5bf200f18b99"]
}
PUT /v2/storage/(uuid)/ftp/(ftp_id)

Update an FTP account.

Required parameters:

Request JSON Object:
  • login (string) – desired FTP login

  • password (string) – FTP password in plaintext

  • dir (string) – relative directory

Example request:

PUT /v2/<UUID>/ftp/2 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "login": "test.example.com",
    "password": "the stronkest password",
    "dir": "",
    "disabled": true
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "id": 2,
        "login": "test.example.com",
        "password": "the stronkest password",
        "dir": "",
        "ipCheck": true,
        "ips": [
            "192.168.0.0/16"
        ],
        "ips_v6": [
            2a01::1/64"
        ],
        "countryCheck": true,
        "countries": [
            "SK",
            "CZ",
            "HU"
        ]
    }
}
DELETE /v2/storage/(uuid)/ftp/(ftp_id)

Hard delete an FTP account.

GET /v2/storage/ftp/check-duplicity/(login)

Check for duplicate login before attempting to create FTP account.

Example request:

GET /v2/check-duplicity/test.example.com HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - login is present:

HTTP/1.1 200 OK
Content-Type: application/json

true
GET /v2/storage/(uuid)/temporary-ftp

Get temporary FTP account if present.

Example request:

GET /v2/storage/<UUID>/temporary-ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - temp FTP account not present:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "login": "",
    "message": "No active account exists",
    "password": "",
    "status": "error"
}

Example response - temp FTP account present:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "login": "8cb1a8bahelpdesk.halka.sk",
    "password": "d2dd1472",
    "status": "success",
    "storage": {
        "createEnabled": true,
        "group": "local",
        "host": "ftp.websupport.sk",
        "hostname": "web-1",
        "id": 79,
        "nfsMountpoint": "/nfsmnt/web-1"
    }
}
POST /v2/storage/(uuid)/temporary-ftp

Create a temporary FTP account. This account has a lifetime of one hour after which it’ll be disabled if not deleted explicitly.

Example request:

POST /v2/storage/<UUID>/temporary-ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "login": "8cb1a8bahelpdesk.halka.sk",
    "password": "d2dd1472",
    "status": "success",
    "storage": {
        "createEnabled": true,
        "group": "local",
        "hostname": "web-1",
        "id": 79,
        "nfsMountpoint": "/nfsmnt/web-1"
    }
}

Example response - temp FTP account already present:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
    "error": "Temporary FTP is already active"
}
DELETE /v2/storage/(uuid)/temporary-ftp

Deactivate the temporary FTP account.

Example request:

DELETE /v2/storage/<UUID>/temporary-ftp HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "message": "Deleted temporary account 8cb1a8bahelpdesk.halka.sk",
    "status": "success"
}

Example response - no account present:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "message": "No active account found for halka.sk",
    "status": "error"
}

Restore

Restoring contents of FTP from backup

Resource

Operation

Description

Restore

GET /v2/restore/(domain_or_uuid)/info

show restore info

GET /v2/restore/(uuid)/backups

list snapshots

GET /v2/restore/(uuid)/backups/(snapshot)

browse snapshot filesystem

GET /v2/restore/(uuid)/current

browse current filesystem

POST /v2/restore/(uuid)/mkdir

create folder

GET /v2/restore/(uuid)

list jobs

GET /v2/restore/(uuid)/(int:restore_id)

show job

POST /v2/restore/(uuid)

restore from snapshot

GET /v2/restore/(domain_or_uuid)/info

List hosting backup info.

This is one of the few endpoints where domain is still accepted (and widely used) instead of just UUID. Currently it’s only used when rendering “edit service” view in helpdesk app.

Example request:

POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/info HTTP/1.1
Content-Type: application/json
Accept: application/json

Equivalent request using domain (deprecated):

POST /v2/restore/example.com/info HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "arch": "local",
    "backup_path": [
        "web-94",
        "/data/.zfs/snapshot/2019-05-22-23:00:04/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99"
    ],
    "host": "web-94",
    "path": "/nfsmnt/hosting1_2/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99"
}
GET /v2/restore/(uuid)/backups

List available snapshots for hosting storage.

Example request:

POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/backups HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": {
        "2023-03-10-18:30:27": "",
        "2023-03-11-18:30:32": "",
        "2023-03-12-18:30:25": "",
        "2023-03-13-18:30:20": "",
        "2023-03-14-18:30:34": "",
        "2023-03-15-18:30:20": "",
        "2023-03-16-18:30:34": "",
        "2023-03-17-18:30:27": "",
        "2023-03-18-18:30:20": "",
        "2023-03-19-18:30:15": "",
        "2023-03-20-18:30:23": "",
        "2023-03-21-18:30:33": "",
        "2023-03-22-18:30:16": "",
        "2023-03-23-18:30:22": ""
    }
}
GET /v2/restore/(uuid)/backups/(snapshot)

Browse filesystem of a particular snapshot.

Request JSON Object:
  • dir (string) – (optional) relative path

Example request:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/backups/2023-03-23-18:30:22 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "dir": ".tmp"
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": {
        "upload": {
            "atime": 1676899264.46657,
            "ctime": 1677505795.9872718,
            "gid": 2024955,
            "mode": {
                "is_blk": false,
                "is_chr": false,
                "is_dir": true,
                "is_fifo": false,
                "is_lnk": false,
                "is_reg": false,
                "is_sock": false,
                "perm": "0o770"
            },
            "mtime": 1676899264.46657,
            "size": 0,
            "uid": 0
        }
    }
}
GET /v2/restore/(uuid)/current

Browse current filesystem for hosting.

Request JSON Object:
  • dir (string) – (optional) relative path

Example request:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/current HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "dir": ".tmp"
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": {
        "upload": {
            "atime": 1676899264.46657,
            "ctime": 1677505795.9872718,
            "gid": 2024955,
            "mode": {
                "is_blk": false,
                "is_chr": false,
                "is_dir": true,
                "is_fifo": false,
                "is_lnk": false,
                "is_reg": false,
                "is_sock": false,
                "perm": "0o770"
            },
            "mtime": 1676899264.46657,
            "size": 0,
            "uid": 0
        }
    }
}
POST /v2/restore/(uuid)/mkdir

Create a new folder.

Request JSON Object:
  • dir (string) – (optional) relative path

  • name (string) – name of the folder to create

POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "dir": "example/com/www",
    "name": "new_folder"
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success"
}
GET /v2/restore/(uuid)

List previous restore jobs

Example request:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "restoreDomainDataUuid": "880b994d-7231-4b21-89d0-71bcbd93f7b6"
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "createTime": 1490021820,
            "domain": "example.com",
            "finishTime": 1490021822,
            "id": 20932,
            "message": "",
            "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-f18b99/example.com",
            "sourceServer": "backup5",
            "startTime": 1490021820,
            "status": "DONE",
            "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test",
            "targetServer": "web-64",
            "restoreDomainDataUuid": "880b994d-7231-4b21-89d0-71bcbd93f7b6"
        }
    ],
    "pager": {
        "items": 0,
        "page": 1,
        "pagesize": null
    }
}
GET /v2/restore/(uuid)/(int: restore_id)

Show restore job by id.

Example request:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json


{
    "createTime": 1490021820,
    "domain": "example.com",
    "finishTime": 1490021822,
    "id": 20932,
    "message": "",
    "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-f18b99/example.com",
    "sourceServer": "backup5",
    "startTime": 1490021820,
    "status": "DONE",
    "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test",
    "targetServer": "web-64"
}
POST /v2/restore/(uuid)

Restore folder or file from snapshot.

Note: this endpoint no longer accepts domain names, only Storage UUIDs. No requests containing domains were recorded since well before the start of 2023.

When restoring a folder, both sourceDir and targetDir need to be specified. The current contents of targetDir will be moved prior to restore, unless skip_backup is set.

When sourceFile is specified, a single file in this path will be restored in-place. All other arguments (except date and skip_backup) are ignored.

Request JSON Object:
  • date (string) – snapshot date (name of the snapshot)

  • sourceFile (string) – relative path to file (restore single file in-place)

  • sourceDir (string) – relative path to directory to be restored

  • targetDir (string) – relative path where to restore contents of sourceDir

  • skip_backup (bool) – do not move existing target to a new location before restore (defaults to false)

Status Codes:

Example request - restore folder:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "date": "2017-02-28-22:35:09",
    "sourceDir": "example.com",
    "targetDir": "test",
    "skip_backup": false
}

Example request - restore file:

GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "date": "2017-02-28-22:35:09",
    "sourceFile": "example.com/info.php",
    "skip_backup": false
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    item = {
        "createTime": 1490021820,
        "domain": "example.com",
        "finishTime": 1490021822,
        "id": 20932,
        "message": "",
        "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-5bf18b99/example.com",
        "sourceServer": "backup5",
        "startTime": 1490021820,
        "status": "QUEUED",
        "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test",
        "targetServer": "web-64"
    },
    "task_id": "b6128f94-ccac-11ed-8e19-c7670bae6ed6"
}

Cron

Manipulating scheduled tasks

Resource

Operation

Description

Crontab

PUT /v2/storage/refresh-crontabs

refrest crontabs

PUT /v2/storage/refresh-crontabs

Refresh crontabs for servers.

Example request:

PUT /v2/storage/refresh-crontabs HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "servers" : [1, 2, 3, "web-100"]
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "task_ids": [
        "ff130a62-7bd0-49df-8a68-11ed9c769287",
        "8b48e036-2a08-4881-bb72-74acb7046ca9",
        "cc0f1baf-d625-49e5-8a79-94cb0bea7081",
        "f0f301b2-1bb1-4e25-9c01-e91417c2ad54"
        ]
    "error": null
}

Htaccess

Manipulating .htaccess files

Logs

Accessing Apache access/error logs

Resource

Operation

Description

Logs

GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs

list of log files

GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/(file_name)

Get logs file content

GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/archive

Get compressed log files

GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs

List of all available log files

Example request:

GET /v2/<uuid>/virtualhost/<vhost_id>/logs HTTP/1.1
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": {
        "access_log": {
            "atime": 1576502426.2307496,
            "ctime": 1576483631.9866045,
            "gid": 0,
            "mode": 33188,
            "mtime": 1576483631.9866045,
            "size": 495,
            "uid": 0
        },
        "access_log-2019-12-14.gz": {
            "atime": 1576360684.315062,
            "ctime": 1576364463.3059802,
            "gid": 0,
            "mode": 33188,
            "mtime": 1576355575.321021,
            "size": 262,
            "uid": 0
        },
        "access_log-2019-12-15.gz": {
            "atime": 1576441146.5722764,
            "ctime": 1576450862.7608495,
            "gid": 0,
            "mode": 33188,
            "mtime": 1576434504.187748,
            "size": 243,
            "uid": 0
        }
    }
}
GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/(file_name)

Get logs file content

Example request

GET /v2/<uuid>/virtualhost/<vhost_id>/logs/<file_name> HTTP/1.1
Accept: */*

Example response

HTTP/1.1 200 OK
Content-Type: application/octet-stream

domain.sk 185.110.144.25 - - [17/Dec/2019:07:43:13 +0100] "GET / HTTP/1.1" 200 55 "-"
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/605.1.15 (KHTML, like Gecko)
Version/13.0.3 Safari/605.1.15" 0.003 MISS 10.10.153.26:80 0.004
domain.sk 185.110.144.25 - - [17/Dec/2019:07:43:13 +0100] "GET /favicon.ico HTTP/1.1"
404 194 "http://domain.sk/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1)
AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15"
0.001 MISS 10.10.153.26:80 0.000

Example request

GET /v2/<uuid>/virtualhost/<vhost_id>/logs/<file_name>?format=parsed HTTP/1.1
Accept: */*

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "body_bytes_sent": "55",
            "http_host": "domain.sk",
            "http_referer": "-",
            "http_user_agent": "Mozilla/5.0 (Macintosh)",
            "method": "GET",
            "raw": "domain.sk 185.110.144.25",
            "remote_addr": "185.110.144.25",
            "request_time": "0.003",
            "request_uri": "/",
            "server_protocol": "HTTP/1.1",
            "status": "200",
            "time_local": "2019-12-17T07:43:13",
            "upstream_addr": "10.10.153.26:80",
            "upstream_cache_status": "MISS",
            "upstream_response_time": "0.004"
        }
    ],
    "not_parsed": ""
}
Query Parameters:
  • format – (parsed / raw) type of response

  • start – Start cursor position of reading log file

  • length – Length of reading log file

  • tail – Read log file from end

GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/archive

Get compressed log files

Example request

GET /v2/<uuid>/virtualhost/<vhost_id>/logs/archive?name=access_log&name=error_log HTTP/1.1
Accept: */*

Example response - success

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 440
Content-Type: application/octet-stream
X-Sentry-Id: None

+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+

Example response - success (large file)

 HTTP/1.1 201 CREATED
 Connection: keep-alive
 Content-Length: 440
 Content-Type: application/json
 X-Sentry-Id: None

{
     "message": "Archive file is larger than 100MB.Please download this file via FTP"
 }

Example response - error

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 35
Content-Type: application/json
Date: Thu, 19 Dec 2019 13:41:35 GMT
Server: nginx/1.17.3
X-Sentry-Id: None

{
    "error": "No files specified"
}
Query Parameters:
  • name – Name of file

Scanner

Run a alware scan on hosting

CMS Installer

One-click CMS installer

Resource

Operation

Description

CMS

PUT /v2/storage/(uuid)/cms-install-check

check installation folder

PUT /v2/storage/(uuid)/service/(service_id)/cms-install-check

PUT /v2/storage/(uuid)/install/(cms)

install CMS

PUT /v2/storage/(uuid)/service/(service_id)/install/(cms)

install CMS under a specific Service

GET /v2/cms-settings

list available CMS installers and configurations

PUT /v2/storage/(uuid)/cms-install-check

Check whether CMS can be installed to a folder.

Runs the same validations that are run during a normal CMS installation. Accepts a subset of arguments of the CMS installation endpoint.

Request JSON Object:
  • directory (string) – URI path

  • subDomain (string) – subdomain name

PUT /v2/storage/(uuid)/service/(service_id)/cms-install-check

Check whether CMS can be installed to a folder used by specified Service’s Virtualhost.

Accepts a subset of arguments of the CMS installation endpoint.

Request JSON Object:
  • directory (string) – URI path

  • subDomain (string) – subdomain name

PUT /v2/storage/(uuid)/install/(cms)

Install a CMS under a matching virtualhost/service. If we find a service that matches the subDomain/directory (path) specified, we update the Service PHP upstream to the one recommended by /v2/cms-settings endpoint.

If no matching Service is found, a new one is created.

The exception to these rules is if no subdomain or path (directory) is specified (or if subdomain equals to ‘www’) - in this case we don’t touch the default Service as updating its PHP upstream might break other websites running under it.

We expect the database specified in the request body to already exist (it doesn’t need to be immediately available, as the RPC process will wait until it becomes live - it just won’t be created by calling this endpoint and has to be created explicitly).

By default, the installation is executed synchronously; but as the installer can sometimes take well over a minute, the response can be returned almost immediately and the installer task executed in the background - to do this, include "async": True in request parameters.

Asynchronous tasks are listed in the response body under async_tasks. This endpoint can trigger up to two asynchronous tasks:

  • set_mcdb handles Nginx configuration update if Service PHP version was updated

  • install_cms handles CMS installation itself if executed using async=True

To check the status of an async task, make a GET request to /v2/queue/<task_id> (see below)

Request JSON Object:
  • async (bool)

  • adminEmail (string)

  • adminLogin (string)

  • adminPassword (string)

  • dbHost (string)

  • dbName (string)

  • dbUser (string)

  • dbPw (string)

  • siteDomain (string)

  • siteTitle (string)

  • siteLanguage (string)

  • ssl (bool) – whether to enable redirect to HTTPS

  • overwrite (bool) – optional, default: false. Overwrite contents of the installation directory.

  • disableWpMail (bool) – (optional) Disable built-in wp_mail() function (ignored for non-WordPress installations). This is a persistent configuration change and needs to be turned off manually.

Example request:

PUT /v2/storage/8340327c-a188-11e9-8480-ab9f87f07045/install/prestashop HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "async": true,
    "adminEmail": "info@example.com",
    "adminLogin": "administrator",
    "adminPassword": "******",
    "dbHost": "mariadb101.websupport.sk:3312",
    "dbName": "4p7j0oducq8t",
    "dbPw": "*********",
    "dbUser": "4p7j0oducq8t",
    "siteDomain": "example.com",
    "subDomain": "www",
    "siteTitle": "Example Site",
    "siteLanguage": "sk",
    "directory": "",
    "archive_url": "http://m.websupport.sk/prestashop-1.7.5.2.tar.gz",
    "ssl": true,
    "overwrite": false,
    "update_default_service": false,
    "disableWpMail": false
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "host": "web-96",
        "path": "/data/2/d/2d62414c-a22d-11e9-8d32-1f869af45ef2/example.com/web"
        "uid": 123456
        "config": {
            "adminEmail": "info@example.com",
            "adminLogin": "administrator",
            "adminPassword": "******",
            "dbHost": "mariadb101.websupport.sk:3312",
            "dbName": "4p7j0oducq8t",
            "dbPw": "*********",
            "dbUser": "4p7j0oducq8t",
            "siteDomain": "www.example.com",
            "siteTitle": "Example Site",
            "siteLanguage": "sk",
            "directory": "",
            "ssl": true,
            "overwrite": false
        },
    },
    "async_tasks": {
        "install_cms": "f72ead9f-9195-458e-ba04-5918e38fe6e3",
        "set_mcdb": "6cafcc46-a7b6-11e9-a8ec-0b4e0e935bce"
    }
}

Polling async task status::

GET /v2/queue/f72ead9f-9195-458e-ba04-5918e38fe6e3 HTTP/1.1

Async task not started:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3",
    "result": null,
    "state": "PENDING",
    "successful": false
}

Async task started:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3",
    "result": null,
    "state": "STARTED",
    "successful": false
}

Async task finished successfully:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3",
    "result": true,
    "state": "SUCCESS",
    "successful": true
}

Async task failed:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3",
    "result": null,
    "state": "FAILURE",
    "successful": false
}
PUT /v2/storage/(uuid)/service/(service_id)/install/(cms)

Install a CMS under the specified service. Updates the PHP upstream if it’s not a default Service.

Request JSON Object:
  • async (bool)

  • adminEmail (string)

  • adminLogin (string)

  • adminPassword (string)

  • dbHost (string)

  • dbName (string)

  • dbUser (string)

  • dbPw (string)

  • siteDomain (string)

  • siteTitle (string)

  • siteLanguage (string)

  • ssl (bool) – whether to enable redirect to HTTPS

  • overwrite (bool) – optional, default: false. Overwrite contents of the installation directory.

  • disableWpMail (bool) – (optional) Disable built-in wp_mail() function (ignored for non-WordPress installations). This is a persistent configuration change and needs to be turned off manually.

Otherwise, it behaves the same as /v2/storage/<uuid>/install/<cms>.

Example request:

POST /v2/storage/8340327c-a188-11e9-8480-ab9f87f07045/service/1/install/prestashop HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "adminEmail": "info@example.com",
    "adminLogin": "administrator",
    "adminPassword": "******",
    "dbHost": "mariadb101.websupport.sk:3312",
    "dbName": "4p7j0oducq8t",
    "dbPw": "*********",
    "dbUser": "4p7j0oducq8t",
    "siteDomain": "example.com",
    "subDomain": "www",
    "siteTitle": "Example Site",
    "siteLanguage": "sk",
    "directory": "",
    "archive_url": "http://m.websupport.sk/prestashop-1.7.5.2.tar.gz",
    "ssl": true,
    "overwrite": false,
    "update_default_service": false,
    "disableWpMail": false
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item": {
        "host": "web-96",
        "path": "/data/2/d/2d62414c-a22d-11e9-8d32-1f869af45ef2/example.com/web"
        "uid": 123456
        "config": {
            "adminEmail": "info@example.com",
            "adminLogin": "administrator",
            "adminPassword": "******",
            "dbHost": "mariadb101.websupport.sk:3312",
            "dbName": "4p7j0oducq8t",
            "dbPw": "*********",
            "dbUser": "4p7j0oducq8t",
            "siteDomain": "www.example.com",
            "siteTitle": "Example Site",
            "siteLanguage": "sk",
            "directory": "",
            "overwrite": false
        }
    }
}
GET /v2/cms-settings

List known CMS types.

Example request:

GET /v2/cms-settings HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [
        {
            "archive": "http://m.websupport.sk/wordpress-5.2.2.tar.gz",
            "createEnabled": true,
            "databaseType": "mariadb101",
            "id": 1,
            "languages": [
                "sk_SK",
                "cs_CZ",
                "hu_HU",
                "en_US"
            ],
            "name": "wordpress",
            "upstream": "apache24-php73",
            "version": "5.2.2"
        },
    ]
}

Shell

Start/stop shell container instances

Resource

Operation

Description

GET /v2/storage/(uuid)/shell

GET /v2/storage/(uuid)/shell/last-activated

GET /v2/storage/(uuid)/shell/ssh-keys

PUT /v2/storage/(uuid)/shell/ssh-keys

POST /v2/shell/(rack)/ensure-socat-services

Shell

POST /v2/storage/(uuid)/shell

activate shell access

DELETE /v2/storage/(uuid)/shell

stop console

DELETE /v2/shell/(domain)

GET /v2/storage/(uuid)/shell

Look for an active shell container for this domain.

GET /v2/storage/(uuid)/shell/last-activated

Look for last shell container for given domain.

GET /v2/storage/(uuid)/shell/ssh-keys

Get all ssh keys from authorizes_keys file for this domain.

PUT /v2/storage/(uuid)/shell/ssh-keys

Add all ssh keys to authorizes_keys file for this domain.

POST /v2/storage/(uuid)/shell

Create a shell container, providing shell access via a web interface and the SSH protocol. Note that if activating premium shell, active shell will be terminated.

Only available for Storage objects with filesEnabled==1.

Request JSON Object:
  • premium (bool) – Create ‘premium’ container (SSL, sshd, no expiration timeout). Default False.

  • last_password (bool) – Reuse password from last active shell for this account. Default False.

  • country (string) – Two-letter country code representing the domain’s market. If specified, we’ll try to return a web shell URL for the given country, otherwise we fall back to the first shell URL for the given rack.

Example request:

POST /v2/storage/b3f34e3a-6cb7-4494-ad0e-cb316bb4539f/shell HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "country": "SK",
    "premium": true
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "country": "SK",
        "createTime": 1642592792,
        "deleteTime": null,
        "host": "shellserver-2",
        "id": 322308,
        "login": "uid71083",
        "message": null,
        "password": "d9b716f0fe",
        "port": 20219,
        "premium": true,
        "rootdir": "/nfsmnt/web-101/b/3/b3f34e3a-6cb7-4494-ad0e-cb316bb4539f",
        "ssh_port": 25219,
        "status": "ACTIVE",
        "url": "https://shellserver-2.websupport.sk:20219",
        "storageId": 3120932
    },
    "status": "success"
}
DELETE /v2/storage/(uuid)/shell

Stop a shell container under Storage specified by uuid.

Status Codes:
DELETE /v2/shell/(domain)

Stop a shell container under Storage specified by domain.

This endpoint is called from FRM at the moment of Premium Shell service expiry.

Status Codes:
POST /v2/shell/(rack)/ensure-socat-services

Make sure that all socat redirects on ing servers are configured and running. Useful after ing server reinstall

GitHookEvent

Manage git hooks.

Resource

Operation

Description

GitHook

GET /v2/storage/(uuid)/githook/push

List git hooks.

GET /v2/storage/(uuid)/githook/push/(hook_id)

Show git hook.

POST /v2/storage/(uuid)/githook/push

Create a new git hook.

PUT /v2/storage/(uuid)/githook/push/(hook_id)

Update a git hook.

PUT /v2/storage/(uuid)/githook/push/(hook_id)/test

Test a git hook.

DELETE /v2/storage/(uuid)/githook/push/(hook_id)

Delete a git hook.

POST /v2/storage/githook/listener

Listener for git hook.

GET /v2/storage/(uuid)/githook/push/logs

All git hook logs for storage.

GET /v2/storage/(uuid)/githook/push/(hook_id)/logs

Git hook logs.

GET /v2/storage/(uuid)/githook/push

List ‘push’ githooks for a storage.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [{
        "branch": "master",
        "clone_url": "git@github.com:johnybx/test-webhook.git",
        "http_password": null,
        "http_user": null,
        "id": 1,
        "reset_before_pull": false,
        "listener_password": null,
        "listener_user": null,
        "path": "nahodnadomenatest.sk/web/",
        "project_name": "johnybx/test-webhook",
        "protocol": "SSH",
        "secret_token": null,
        "ssh_fingerprint": null,
        "ssh_public_key": null,
        "status": "ACTIVE",
        "storageId": 94336
    }],
    "status": "success"
}
GET /v2/storage/(uuid)/githook/push/(hook_id)

Show the details of a single git hook.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "branch": "master",
        "clone_url": "git@github.com:johnybx/test-webhook.git",
        "http_password": null,
        "http_user": null,
        "id": 1,
        "reset_before_pull": false,
        "listener_password": null,
        "listener_user": null,
        "path": "nahodnadomenatest.sk/web/",
        "project_name": "johnybx/test-webhook",
        "protocol": "SSH",
        "secret_token": null,
        "ssh_fingerprint": null,
        "ssh_public_key": null,
        "status": "ACTIVE",
        "storageId": 94336
    },
    "status": "success"
}
POST /v2/storage/(uuid)/githook/push

Create a new hook.

Status Codes:
Request JSON Object:
  • project_url (string) – clone url of project

  • branch (string) – branch which should be pulled

  • path (string) – path where git repository should be pulled to

  • reset_before_pull (bool) – git reset repository before pulling, optional

  • keypairId (int) – id of ssh key pair, optional

  • http_user (string) – user for basic authentication to git repository, optional

  • http_password (string) – password for basic authentication to git repository, optional

  • secret_token (string) – secret tocket to authorize push event (supported only for github and giltab), optional

  • listener_user (string) – user for basic authentication for listener endpoint, optional

  • listener_password (string) – password for basic authentication for listener endpoint, optional

  • build_command (string) – command to run after git pull in order to build the application, optional ( nothing is run if not specified )

Example request

POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "project_url": "git@github.com:johnybx/test-webhook.git",
    "branch": "master",
    "path": "nahodnadomenatest.sk/web/",
    "reset_before_pull": false
}

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "branch": "master",
        "clone_url": "git@github.com:johnybx/test-webhook.git",
        "http_password": null,
        "http_user": null,
        "id": 1,
        "reset_before_pull": false,
        "listener_password": null,
        "listener_user": null,
        "path": "nahodnadomenatest.sk/web/",
        "project_name": "johnybx/test-webhook",
        "protocol": "SSH",
        "secret_token": null,
        "ssh_fingerprint": null,
        "ssh_public_key": null,
        "status": "ACTIVE",
        "storageId": 94336
        "build_command": "composer install"
    },
    "status": "success"
}
PUT /v2/storage/(uuid)/githook/push/(hook_id)
Update hook settings. You can change:
  • hook status

  • clone path

  • branch

  • http username and password

  • secret token

  • listener username and password

Status Codes:
Request JSON Object:
  • branch (string) – branch which should be pulled, optional

  • path (string) – path where git repository should be pulled to, optional

  • reset_before_pull (bool) – git reset repository before pulling, optional

  • keypairId (int) – id of ssh key pair, optional

  • http_user (string) – user for basic authentication to git repository, optional

  • http_password (string) – password for basic authentication to git repository, optional

  • secret_token (string) – secret tocket to authorize push event (supported only for github and giltab), optional

  • listener_user (string) – user for basic authentication for listener endpoint, optional

  • listener_password (string) – password for basic authentication for listener endpoint, optional

  • build_command (string) – command to run after git pull in order to build the application, optional ( nothing is run if not specified )

Example request

PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "branch": "staging",
    "path": "nahodnadomenatest.sk/sub/staging",
    "reset_before_pull": true
}

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "branch": "staging",
        "clone_url": "git@github.com:johnybx/test-webhook.git",
        "http_password": null,
        "http_user": null,
        "id": 1,
        "reset_before_pull": true,
        "listener_password": null,
        "listener_user": null,
        "path": "nahodnadomenatest.sk/sub/staging",
        "project_name": "johnybx/test-webhook",
        "protocol": "SSH",
        "secret_token": null,
        "ssh_fingerprint": null,
        "ssh_public_key": null,
        "status": "ACTIVE",
        "storageId": 94336
    },
    "status": "success"
}
PUT /v2/storage/(uuid)/githook/push/(hook_id)/test

Test if storage git hook is correctly configured. This endpoint try to pull latest data from git and returns error message in case of fail.

Status Codes:

Example request

PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1/test HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success"
}

Example response - git hook fail

HTTP/1.1 500 Internal error
Content-Type: application/json

{
    "status": "error",
    "error": "git@github.com: Permission denied (publickey)"
}
DELETE /v2/storage/(uuid)/githook/push/(hook_id)

Delete git hook.

Status Codes:

Example request

DELETE /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "branch": "staging",
        "clone_url": "git@github.com:johnybx/test-webhook.git",
        "http_password": null,
        "http_user": null,
        "id": 1,
        "reset_before_pull": true,
        "listener_password": null,
        "listener_user": null,
        "path": "nahodnadomenatest.sk/sub/staging",
        "project_name": "johnybx/test-webhook",
        "protocol": "SSH",
        "secret_token": null,
        "ssh_fingerprint": null,
        "ssh_public_key": null,
        "status": "ACTIVE",
        "storageId": 94336
    },
    "status": "success"
}
POST /v2/storage/githook/listener

Listener for git hooks from github, gitlab or bitbucket.

Status Codes:

Example request

POST /v2/storage/githook/listener HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "data": "payload from github, gitlab or bitbucket"
}

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "task_id": "7941f72d-d121-4c43-8bce-2d0f58b663a1",
    "status": "success"
}
GET /v2/storage/(uuid)/githook/push/logs

Get logs for all git hooks connected to specified storage.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/logs HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items": [
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": null,
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 200,
            "utc_datetime": "Tue, 23 Feb 2021 17:21:57 GMT"
        },
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": "Access denied to URL",
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 403,
            "utc_datetime": "Tue, 23 Feb 2021 17:22:08 GMT"
        },
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": null,
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 200,
            "utc_datetime": "Tue, 23 Feb 2021 17:22:19 GMT"
        }
    ]
}
GET /v2/storage/(uuid)/githook/push/(hook_id)/logs

Get logs for specified git hook.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/41413/logs HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items": [
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": null,
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 200,
            "utc_datetime": "Tue, 23 Feb 2021 17:21:57 GMT"
        },
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": "Access denied to URL",
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 403,
            "utc_datetime": "Tue, 23 Feb 2021 17:22:08 GMT"
        },
        {
            "branch": "master",
            "clone_url": "https://gitlab.com/gituser/test-ws-githook",
            "error": null,
            "path": "testdomain.com/web",
            "project_name": "gituser/test-ws-githook",
            "status_code": 200,
            "utc_datetime": "Tue, 23 Feb 2021 17:22:19 GMT"
        }
    ]
}

SSHKeys

Manage ssh keys.

Resource

Operation

Description

SshKeys

GET /v2/storage/(uuid)/ssh-keys

List ssh keys.

GET /v2/storage/(uuid)/ssh-keys/(int:key_id)

Show ssh key.

POST /v2/storage/(uuid)/ssh-keys

Add ssh key.

PUT /v2/storage/(uuid)/ssh-keys/(int:key_id)

Update ssh key.

DELETE /v2/storage/(uuid)/ssh-keys/(int:key_id)

Delete ssh key.

GET /v2/storage/(uuid)/ssh-keys

List ssh keys.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items": [{
        "comment": null,
        "createTime": 1595510348,
        "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a",
        "id": 1,
        "private_key": "-----BEGIN RSA PRIVATE KEY-----
        MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
        pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
        QUlC1oOZmE8aUjyoQ/6vJ8AEyH+lItQx1VdktpUDa91lYk84SH07sza/GUtXqMG7
        del8kzxT3Wdf33K+CULmkD7Xx/CuyED5V22i2U5ZhPrR4EK/L13RcB40QajzUsw3
        xkIh1wjZoKJPSs9/p2dFv2xOxXzm0fPKq/qfd9zRwbRUpvO+PikdcpKrzrN8DgHl
        wSEiWWnMzBywc/4wjlfeaSo3srNo7Q+0q3GCWp8ulXoH+1ZzV9VisJqKVbpW2zI7
        3zB14GQuEc/qVrFX2qFZ50AWHoH/595vf42/f9KeooGnQpYTBWUOt5/kmpIHgaNy
        WQHxrNlPXQu4RHSLWa99tijW21i7pyb/ftupyX6K7puzA1plua0ypgXyg1iMXuiv
        TEyCpVFNs4vPvE+QneLA0TwEHiE0BspYusFcljyaeMi1ETKvsxN4bs9ZNm0S7imQ
        weQJJ9mBDBqnIPUJAmlc0s/Kep2vR/FFho0nOQXF3id+S2BQjqqbo5zPMPe0WYBh
        A4UhR3ITXdkToEiLBZw2bSnmMQDW6iYAz8zkiVkZlMGcdjvCAl4aePPxf7kCAwEA
        AQKCAgBAxeZMD7KJgXjZDDEKLNggJy4MgQ8U2VitzbhQH2u87CzitCFpXbaWoyQc
        nhKdU4M4lsMI2bRStPBkNbD7R8Sbxf6AQplj666F4Yd42BFP93dP4oCvQT3Ja5Zd
        zj4xg77WJLGqOd4oKRlxt+x34cO1zZdVB2hBTFElhRlvf4hSHI7nfB+xZeiocAHO
        UBsI0d74A3e1LKKQ/R7UsasJdV473HfbNMk6RkCIWa6/hj4aHv2Kcif5H/sUE82r
        1s9hebW4HBYAaVAR8TTBJnaTrgBc5KfZxZRUR44HgaWva26vTKUEs3NvZZczEegG
        xtqXzqAXF7tdcvo5I1cmOOfPjoq1nu+63K0r76DXDTyLpRMtsBPRn/LRxW+Gw5kb
        X5v9ugehBbVPErVhxbtdtBapcmnn3rqAGfAM/EhLPPD7dT0ZmJGmO7EwMlAFgYEO
        vjjV8u26GKiDb6fMemmb3tPJ62tMDQiGT2yR7C0CTfjMPr6S0KUCMFhYylFr4M/s
        MRVKsdDqkeP3vdknhiqZ3LJaOfFYtpxtti0JnwMsqRnMh5mUcySkxqu2eo9Qx/J0
        w9jZOMQf8Dg7vmUzldrxQfavzgsUgPD08xdyDbsyPyb59p7swWpxh2r9CmwoH/c6
        jsLKepTqxEmMHT4gH+/wI41zk6jqg3jpk0lLS4NBHkq0d22r4wKCAQEA1R05ib/Z
        eXuA6uc9kLAD5rNkn8lG9eYNTYFSrP26GokcvN+p+B2b6KOJLYcIZOp9bEnlD/Ng
        F6GeQF3B+T7VARno6HqICL1d/cf5tpKsndIqwNl/p87BTs6eaZUI7cFZz0w5uV4K
        1nkEsrWIZv6dUAd+W+Px0NVa6N5/4XPNreKAj9SYmAtOdEP6JvvTKBgQaPG9sZ02
        kzYUwcpAWHG3N/kCcLPwVkav4MX1ZUe5jECD1bEaOAYjqIsXndP5meH3VUefPLyl
        aiGJj3Iq7uXYYeHf+vA1h76RJgd2F4Y12g4D4fBg53W17OfBBZxVxPktdOqzE9jj
        Roz8n75Zc8FxgwKCAQEA9tAUqvxfoj0QjP+pHdqO2SPUTIVYa1De46augvE0We1d
        bqMOr3Ji4JGp2qqtpz0Tfb0kCNTQcU4mnYec3KuyU8uK/0LIMDkTFYLDYFp00bDG
        nyjLEUt015MpAzR9T8lOBVdo2UA+LF9EKq50Ak3qvTQr+XxnYUA8ofehb3jZTKpf
        uoP4PEZPoAZiJ9x4B0DvBnDmbPuq3kMCk2U90WL+zhhtv0mO7md4/ZddCO23sayG
        oGgJbC7Z5x1Y//lB5w+SqbpvdqsbjeZPoE+KamIQm+2pKMz3x2JSOjyOtbJAJ+Fy
        yoUvt+hG0A6CJ42hj/hqrMjpMpBcpSsNa0tON/QxEwKCAQEApg6hmN4unORJLcCF
        Tkp4n7jE/WSesFhToULVowoJi0evZtR44mZf58QVza3cMpYsqMZjgCxJgeBjKRBl
        Zss4uiTwQMXJXdYAeRDrWQGtE0SCH8baG22VXszMzsRcMrZoPojMqc3HcBrYOFAP
        OwHGnmdYZE2XTPwSXEWTK59KcuV8+5XSWRbmSN32+41ZmXI2xy8melFgBxEq1127
        Ca+B7lFPP3ZWHUPzI5fcgNCEme5jS402OtU9z8Sh4E8dvHRAfujSAUeVNL9xKp7x
        KTlbg9m25xdo/p7VBublc6sWJxSondLqDzC/Uxu6YZ7RjiwC6Yk/hIWJgp208twl
        Y3cl9QKCAQBHItgiJBVIRINlsDZFFX5AlXQWDgTbAXcMdDkuImktVh2syrBr3vMi
        uLkU/kaIwjDA9+fP586gKZ81niWW8KG4Rx0rz0q1o22dsI+xUMEEwwesTeyhcncd
        vxt+Af3wJhwnq/bbTwncbiTOjHOBSoXSvJvED5gYTpRrNl1ALLusvhpTPsAoVzeR
        7uURihjKNmvuFlJDrRGld/jhFLgJhpfcPOw8yu24Rvh3Vs4IycM9IXW3++RjWumR
        FENXm7bj6vghlUuVD2IktvHSSbqiSNtypcAws0rjG7KJeHTFZ7fYBsG4H0UOo5Lt
        WpEm50penYHZhRq5aSRaspruhsjnlakjAoIBAHgUAfT81RhLZisgldiYlDf9tfCk
        vYN9YB/dMoniWzFvZCRGvVjQkPTufhplFrFWpFdavMOFpVVMzKQL/VqZEQin3SGn
        BA35HU6t1bqOfKD1c4COyz4qo+rF8+OEuTEs00KvrRVMCaRcQ8i8Ah2k2v/P6I/2
        EsrZLSqYNQnSVVTl59gfP3+vo7qmDT4Q8ZdHGO045XZ+KJ1ZDdWLBxs9i17zfOlT
        LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
        Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
        -----END RSA PRIVATE KEY-----",
        "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNd049vkY1cQ1CJhP3UzOje1Jmq+RxFWyNKS6n1HtXm6gvWG2m/G/kqZ1N6M6rxnBsRUKHDnGRFLM1u9QGVB6mLi8TZibNUPxLwgm7PN8om6tDgkpBSULWg5mYTxpSPKhD/q8nwATIf6Ui1DHVV2S2lQNr3WViTzhIfTuzNr8ZS1eowbt16XyTPFPdZ1/fcr4JQuaQPtfH8K7IQPlXbaLZTlmE+tHgQr8vXdFwHjRBqPNSzDfGQiHXCNmgok9Kz3+nZ0W/bE7FfObR88qr+p933NHBtFSm874+KR1ykqvOs3wOAeXBISJZaczMHLBz/jCOV95pKjeys2jtD7SrcYJany6Vegf7VnNX1WKwmopVulbbMjvfMHXgZC4Rz+pWsVfaoVnnQBYegf/n3m9/jb9/0p6igadClhMFZQ63n+SakgeBo3JZAfGs2U9dC7hEdItZr322KNbbWLunJv9+26nJforum7MDWmW5rTKmBfKDWIxe6K9MTIKlUU2zi8+8T5Cd4sDRPAQeITQGyli6wVyWPJp4yLURMq+zE3huz1k2bRLuKZDB5Akn2YEMGqcg9QkCaVzSz8p6na9H8UWGjSc5BcXeJ35LYFCOqpujnM8w97RZgGEDhSFHchNd2ROgSIsFnDZtKeYxANbqJgDPzOSJWRmUwZx2O8ICXhp48/F/uQ==",
        "storageId": 94336
    }]
}
GET /v2/storage/(uuid)/ssh-keys/(int: key_id)

Show ssh key.

Status Codes:

Example request

GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "comment": null,
        "createTime": 1595510348,
        "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a",
        "id": 1,
        "private_key": "-----BEGIN RSA PRIVATE KEY-----
        MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
        pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
        .....
        LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
        Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
        -----END RSA PRIVATE KEY-----",
        "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==",
        "storageId": 94336
    },
    "status": "success"
}
POST /v2/storage/(uuid)/ssh-keys

Add ssh key. If not private key is send in request than new ssh key will be automatically generated.

Status Codes:

Example request

POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "comment": "My ssh key",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----
    MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
    pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
    .....
    LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
    Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
    -----END RSA PRIVATE KEY-----",
}

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "comment": "My ssh key",
        "createTime": 1595510348,
        "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a",
        "id": 1,
        "private_key": "-----BEGIN RSA PRIVATE KEY-----
        MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
        pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
        .....
        LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
        Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
        -----END RSA PRIVATE KEY-----",
        "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==",
        "storageId": 94336
    },
    "status": "success"
}
PUT /v2/storage/(uuid)/ssh-keys/(int: key_id)

Update ssh key.

Status Codes:

Example request

PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "comment": "My ssh key"
}

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "comment": "My ssh key",
        "createTime": 1595510348,
        "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a",
        "id": 1,
        "private_key": "-----BEGIN RSA PRIVATE KEY-----
        MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
        pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
        .....
        LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
        Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
        -----END RSA PRIVATE KEY-----",
        "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==",
        "storageId": 94336
    },
    "status": "success"
}
DELETE /v2/storage/(uuid)/ssh-keys/(int: key_id)

Delete ssh key.

Status Codes:

Example request

DELETE /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item": {
        "comment": null,
        "createTime": 1595510348,
        "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a",
        "id": 1,
        "private_key": "-----BEGIN RSA PRIVATE KEY-----
        MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht
        pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK
        .....
        LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp
        Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4=
        -----END RSA PRIVATE KEY-----",
        "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==",
        "storageId": 94336
    },
    "status": "success"
}

IptablesRule

Manage iptables rules.

Resource

Operation

Description

Iptables

GET /v2/storage/(uuid)/iptables

List iptables rules

GET /v2/storage/(uuid)/iptables/(rule_id)

Show one iptables rule

POST /v2/storage/(uuid)/iptables

Create new iptables rule

PUT /v2/storage/(uuid)/iptables/(rule_id)

Update iptables rule

DELETE /v2/storage/(uuid)/iptables/(rule_id)

Delete iptables rule

PUT /v2/storage/(uuid)/iptables/export/(rack)

Export rules by rack

GET /v2/storage/(uuid)/iptables

List iptables rules under storage.

Status Codes:

Example request:

GET /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "items":
        [
            {
                "chain": "hosting_allowlist",
                "comment": "This rule is added based on client request",
                "deleted": false,
                "destination": "37.9.175.0/24,37.9.169.5",
                "id": 1,
                "port": 10000,
                "protocol": "tcp",
                "storageId": 94336,
                "jump_target": "ACCEPT"
            }
        ]
}
GET /v2/storage/(uuid)/iptables/(rule_id)

Show iptables rule under storage

Status Codes:

Example request:

GET /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":
        {
            "chain": "hosting_allowlist",
            "comment": "This rule is added based on client request",
            "deleted": false,
            "destination": "37.9.175.0/24,37.9.169.5",
            "id": 1,
            "port": 10000,
            "protocol": "tcp",
            "storageId": 94336,
            "jump_target": "ACCEPT"
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Iptables rule not found"
}
POST /v2/storage/(uuid)/iptables

Create new iptables rule under storage

Status Codes:
Request JSON Object:
  • port (int) – port which should be allowed

  • destination (str) – ipaddress or ip range. Multiple ipaddresses or ip ranges can be specified devided by comma

  • protocol (str) – tcp or udp

  • comment (str) – most often reason for existence of rule

  • jump_target (str) – iptables jump target ACCEPT (default) or DROP, optional

Example request:

POST /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "port": 10000,
    "destination": "37.9.175.0/24,37.9.169.5",
    "protocol": "tcp",
    "comment": "This rule is added based on client request",
    "jump_target": "ACCEPT"
}

Example response - success:

HTTP/1.1 201 Created
Content-Type: application/json

{
    "item":
        {
            "chain": "hosting_allowlist",
            "comment": "This rule is added based on client request",
            "deleted": false,
            "destination": "37.9.175.0/24,37.9.169.5",
            "id": 1,
            "port": 10000,
            "protocol": "tcp",
            "storageId": 94336,
            "jump_target": "ACCEPT"
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Iptables rule not found"
}
PUT /v2/storage/(uuid)/iptables/(rule_id)

Update iptables rule under storage

Status Codes:
Request JSON Object:
  • port (int) – port which should be allowed, optional

  • destination (str) – ipaddress or ip range. Multiple ipaddresses or ip ranges can be specified devided by comma, optional

  • protocol (str) – tcp or udp, optional

  • comment (str) – most often reason for existence of rule, optional

  • jump_target (str) – iptables jump target ACCEPT or DROP, optional

Example request:

PUT /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "port": 10001,
    "destination": "37.9.175.0/24",
    "protocol": "udp",
    "comment": "This rule is added based on client request",
    "jump_target": "ACCEPT",
    "deleted": false
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":
        {
            "chain": "hosting_allowlist",
            "comment": "This rule is added based on client request",
            "deleted": false,
            "destination": "37.9.175.0/24",
            "id": 1,
            "port": 10001,
            "protocol": "udp",
            "storageId": 94336,
            "jump_target": "ACCEPT"
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Iptables rule not found"
}
DELETE /v2/storage/(uuid)/iptables/(rule_id)

Delete iptables rule under storage

Status Codes:

Example request:

DELETE /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "item":
        {
            "chain": "hosting_allowlist",
            "comment": "This rule is added based on client request",
            "deleted": true,
            "destination": "37.9.175.0/24",
            "id": 1,
            "port": 10001,
            "protocol": "udp",
            "storageId": 94336,
            "jump_target": "ACCEPT"
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "error": "Iptables rule not found"
}
PUT /v2/storage/(uuid)/iptables/export/(rack)

Export iptables rules by rack

Status Codes:

Example request:

PUT /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/export/r1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "task_id": "bfcfc866-b633-447f-b2fa-81658c9b2599"
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Rack: r13 not found"
}

Nginx waf allowlist

Manage nginx waf allowlist rules.

Resource

Operation

Description

Nginx waf allowlist

GET /v2/storage/(uuid)/nginx-waf

List nginx waf allowlist rules

GET /v2/storage/(uuid)/nginx-waf/(int:rule_id)

Show one nginx waf allowlist rule

POST /v2/storage/(uuid)/nginx-waf

Create new nginx waf allowlist rule

PUT /v2/storage/(uuid)/nginx-waf/(int:rule_id)

Update nginx waf allowlist rule

PUT /v2/storage/nginx-waf/deploy/(rack)/(server)

Deploy nginx waf allowlist rules

DELETE /v2/storage/(uuid)/nginx-waf/(int:rule_id)

Delete nginx waf allowlist rule

GET /v2/storage/(uuid)/nginx-waf

List nginx waf allowlist rules.

Status Codes:

Example request:

GET /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "items":
        [
            {
                "comment": "some nginx waf rule",
                "id": 1,
                "storageId": 1,
                "domain": "some\.domain\.sk$",
            }
        ]
}
GET /v2/storage/(uuid)/nginx-waf/(int: rule_id)

Show nginx waf allowlist rule

Status Codes:

Example request:

GET /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item":
        {
            "comment": "some nginx waf rule",
            "id": 1,
            "storageId": 1,
            "domain": "some\.domain\.sk$",
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Nginx waf allowlist rule not found"
}
POST /v2/storage/(uuid)/nginx-waf

Create new nginx waf allowlist rule

Status Codes:
Request JSON Object:
  • domain (str) – nginx waf rule to be allowed

  • comment (str) – why the rule exists

Example request:

POST /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "domain": "some\.domain\.sk$",
    "comment": "some nginx waf rule",
}

Example response - success:

HTTP/1.1 201 Created
Content-Type: application/json

{
    "status": "success",
    "item":
        {
            "comment": "some nginx waf rule",
            "id": 1,
            "storageId": 1,
            "domain": "some\.domain\.sk$",
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Nginx waf allowlist rule not found"
}
PUT /v2/storage/(uuid)/nginx-waf/(int: rule_id)

Update nginx waf allowlist rule

Status Codes:
Request JSON Object:
  • domain (str) – nginx waf rule to be allowed, optional

  • comment (str) – why the rule exists, optional

Example request:

PUT /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "domain": "some\.domain\.sk$"
}

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item":
    {
        "comment": "some nginx waf rule",
        "id": 1,
        "storageId": 1,
        "domain": "some\.domain\.sk$",
    }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Nginx waf allowlist rule not found"
}
PUT /v2/storage/nginx-waf/deploy/(rack)/(server)

Deploy nginx waf allowlist rules to server

Status Codes:

Example request:

PUT /v2/storage/nginx-waf/deploy/in-1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "result":
        {
            "some": "result"
        }
}
DELETE /v2/storage/(uuid)/nginx-waf/(int: rule_id)

Delete nginx waf allowlist rule

Status Codes:

Example request:

DELETE /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1
Content-Type: application/json
Accept: application/json

Example response - success:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "item":
        {
            "comment": "some nginx waf rule",
            "id": 1,
            "storageId": 1,
            "domain": "some\.domain\.sk$",
        }
}

Example response - Not found:

HTTP/1.1 404 OK
Content-Type: application/json

{
    "status": "error",
    "error": "Nginx waf allowlist rule not found"
}