curl --request PUT \
--url https://app.sandywp.com/api/app/sites/{id}/domain \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"hostname": "demo.example.com"
}
'import requests
url = "https://app.sandywp.com/api/app/sites/{id}/domain"
payload = { "hostname": "demo.example.com" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({hostname: 'demo.example.com'})
};
fetch('https://app.sandywp.com/api/app/sites/{id}/domain', 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://app.sandywp.com/api/app/sites/{id}/domain",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'hostname' => 'demo.example.com'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.sandywp.com/api/app/sites/{id}/domain"
payload := strings.NewReader("{\n \"hostname\": \"demo.example.com\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://app.sandywp.com/api/app/sites/{id}/domain")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"hostname\": \"demo.example.com\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sandywp.com/api/app/sites/{id}/domain")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"hostname\": \"demo.example.com\"\n}"
response = http.request(request)
puts response.read_body{
"domain": {
"hostname": "demo.example.com",
"status": "pending_dns",
"verifiedAt": "2023-11-07T05:31:56Z",
"url": "https://demo.example.com",
"target": "domains.sandywp.dev",
"records": [
{
"type": "CNAME",
"name": "<string>",
"value": "<string>"
}
],
"lastError": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "auth_required",
"message": "A logged-in user is required.",
"details": {}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "capability_required",
"message": "Your role does not allow this.",
"details": {
"capability": "internals"
}
}
}{
"error": {
"code": "site_not_found",
"message": "Site not found.",
"details": {}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}Connect a custom domain
Connects a domain you own to a ready sandbox. Requires a Workspace plan. Point the domain at target first (a CNAME for a subdomain, or the listed A records for a root domain, DNS-only / not proxied). If DNS already resolves to the sandbox’s server the domain is verified at once and goes live async (status activating, then active); otherwise the status is pending_dns and lastError says what is missing. SSL is issued automatically. A sandbox holds one domain; remove it before connecting another.
curl --request PUT \
--url https://app.sandywp.com/api/app/sites/{id}/domain \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"hostname": "demo.example.com"
}
'import requests
url = "https://app.sandywp.com/api/app/sites/{id}/domain"
payload = { "hostname": "demo.example.com" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({hostname: 'demo.example.com'})
};
fetch('https://app.sandywp.com/api/app/sites/{id}/domain', 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://app.sandywp.com/api/app/sites/{id}/domain",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'hostname' => 'demo.example.com'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.sandywp.com/api/app/sites/{id}/domain"
payload := strings.NewReader("{\n \"hostname\": \"demo.example.com\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://app.sandywp.com/api/app/sites/{id}/domain")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"hostname\": \"demo.example.com\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sandywp.com/api/app/sites/{id}/domain")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"hostname\": \"demo.example.com\"\n}"
response = http.request(request)
puts response.read_body{
"domain": {
"hostname": "demo.example.com",
"status": "pending_dns",
"verifiedAt": "2023-11-07T05:31:56Z",
"url": "https://demo.example.com",
"target": "domains.sandywp.dev",
"records": [
{
"type": "CNAME",
"name": "<string>",
"value": "<string>"
}
],
"lastError": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "auth_required",
"message": "A logged-in user is required.",
"details": {}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "capability_required",
"message": "Your role does not allow this.",
"details": {
"capability": "internals"
}
}
}{
"error": {
"code": "site_not_found",
"message": "Site not found.",
"details": {}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
}
}Authorizations
Personal API token, sent as Authorization: Bearer <SANDYWP_API_KEY>. Obtain one from the dashboard account menu (API keys), sandywp auth login, or POST /api/account/tokens. A missing or invalid token returns 401 auth_required. Scoped OAuth tokens are limited to the Imports family and GET /api/account/me; see the top-level conventions.
Headers
Selects which of the caller's workspaces to act in, for accounts belonging to more than one (legacy alias: X-SandyWP-Organization). Defaults to the caller's own personal workspace when omitted. Every id in this API (sandboxes, Templates, repositories) is scoped to a single workspace, so this header changes which set of resources is visible.
Path Parameters
The sandbox id.
Body
The domain to connect, without scheme or path.
"demo.example.com"
Response
The custom domain state after the change.
Show child attributes
Show child attributes

