curl --request POST \
--url https://rdp.sh/api/v1/servers/{server}/region-changes \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"region_id": 6,
"distro_id": 123,
"ssh_key_id": 123
}
'import requests
url = "https://rdp.sh/api/v1/servers/{server}/region-changes"
payload = {
"region_id": 6,
"distro_id": 123,
"ssh_key_id": 123
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({region_id: 6, distro_id: 123, ssh_key_id: 123})
};
fetch('https://rdp.sh/api/v1/servers/{server}/region-changes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://rdp.sh/api/v1/servers/{server}/region-changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'region_id' => 6,
'distro_id' => 123,
'ssh_key_id' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://rdp.sh/api/v1/servers/{server}/region-changes"
payload := strings.NewReader("{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://rdp.sh/api/v1/servers/{server}/region-changes")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://rdp.sh/api/v1/servers/{server}/region-changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}"
response = http.request(request)
puts response.read_body{
"status": true,
"message": "The move to New York has been queued",
"invoice_id": 5012,
"amount_charged": 2.5,
"region_change": {
"id": 17,
"server_id": 123,
"status": "running",
"mode": "transfer",
"step": "Copying the disk",
"progress": 46,
"from_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"to_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"distro": "Ubuntu 24.04",
"old_ip": "45.138.16.20",
"new_ip": "147.90.219.31",
"new_server_id": 123,
"deployment_id": 123,
"invoice_id": 123,
"refunded": true,
"error": "<string>",
"created_at": "2026-10-21T12:00:00+00:00",
"finished_at": "<string>"
}
}{
"status": false,
"error": "Insufficient balance",
"required": 2.5,
"available": 1
}{
"status": false,
"error": "This action is unauthorized"
}{
"status": false,
"error": "New York is out of stock for this server's plan right now. Please try again later or choose another location.",
"region_change": {
"id": 17,
"server_id": 123,
"status": "running",
"mode": "transfer",
"step": "Copying the disk",
"progress": 46,
"from_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"to_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"distro": "Ubuntu 24.04",
"old_ip": "45.138.16.20",
"new_ip": "147.90.219.31",
"new_server_id": 123,
"deployment_id": 123,
"invoice_id": 123,
"refunded": true,
"error": "<string>",
"created_at": "2026-10-21T12:00:00+00:00",
"finished_at": "<string>"
}
}Change Server Region
Moves a server to another location for a one-time fee of €2.50 (VAT of your country included), paid from your account balance. The live stock of the location is checked before anything is charged.
The move then runs on its own; follow it with GET /region-changes/{regionChange}.
Either way the server gets an IP address of the new location, and its old
address is released. A move that fails is credited back to your balance.
- transfer keeps the server, its ID and its data. It is stopped while the disk is copied, usually 15 to 60 minutes, and started again in the new location if it was running. A Linux server boots with new SSH host keys.
- fresh replaces the server with a new one carrying the same expiry date
and name. The response’s
region_change.new_server_idanddeployment_idare set once the setup has started.
curl --request POST \
--url https://rdp.sh/api/v1/servers/{server}/region-changes \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"region_id": 6,
"distro_id": 123,
"ssh_key_id": 123
}
'import requests
url = "https://rdp.sh/api/v1/servers/{server}/region-changes"
payload = {
"region_id": 6,
"distro_id": 123,
"ssh_key_id": 123
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({region_id: 6, distro_id: 123, ssh_key_id: 123})
};
fetch('https://rdp.sh/api/v1/servers/{server}/region-changes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://rdp.sh/api/v1/servers/{server}/region-changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'region_id' => 6,
'distro_id' => 123,
'ssh_key_id' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://rdp.sh/api/v1/servers/{server}/region-changes"
payload := strings.NewReader("{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://rdp.sh/api/v1/servers/{server}/region-changes")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://rdp.sh/api/v1/servers/{server}/region-changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"region_id\": 6,\n \"distro_id\": 123,\n \"ssh_key_id\": 123\n}"
response = http.request(request)
puts response.read_body{
"status": true,
"message": "The move to New York has been queued",
"invoice_id": 5012,
"amount_charged": 2.5,
"region_change": {
"id": 17,
"server_id": 123,
"status": "running",
"mode": "transfer",
"step": "Copying the disk",
"progress": 46,
"from_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"to_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"distro": "Ubuntu 24.04",
"old_ip": "45.138.16.20",
"new_ip": "147.90.219.31",
"new_server_id": 123,
"deployment_id": 123,
"invoice_id": 123,
"refunded": true,
"error": "<string>",
"created_at": "2026-10-21T12:00:00+00:00",
"finished_at": "<string>"
}
}{
"status": false,
"error": "Insufficient balance",
"required": 2.5,
"available": 1
}{
"status": false,
"error": "This action is unauthorized"
}{
"status": false,
"error": "New York is out of stock for this server's plan right now. Please try again later or choose another location.",
"region_change": {
"id": 17,
"server_id": 123,
"status": "running",
"mode": "transfer",
"step": "Copying the disk",
"progress": 46,
"from_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"to_region": {
"id": 1,
"region": "nl",
"location": "Amsterdam"
},
"distro": "Ubuntu 24.04",
"old_ip": "45.138.16.20",
"new_ip": "147.90.219.31",
"new_server_id": 123,
"deployment_id": 123,
"invoice_id": 123,
"refunded": true,
"error": "<string>",
"created_at": "2026-10-21T12:00:00+00:00",
"finished_at": "<string>"
}
}Authorizations
Path Parameters
Body
The location to move to, from regions in the options.
6
transfer copies the server's disk to the new location, so files,
applications and settings come along. The server is stopped while
the disk is copied. fresh replaces the server with a new
installation in the new location; everything on its disk is erased.
transfer, fresh Required for fresh: the operating system to install. Accepts a
Linux distro ID or a Windows iso ID, as on reinstall.
Optional for a fresh Linux server, one of your SSH keys.
Response
The move was paid from your balance and queued.