Code Samples #
curl --request POST \
--url 'https://app.xcloud.host/api/v1/servers/{uuid}/sites/git' \
--header 'Authorization: Bearer YOUR_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
}'
const response = await fetch('https://app.xcloud.host/api/v1/servers/{uuid}/sites/git', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
})
});
const data = await response.json();
console.log(data);
import requests
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
}
payload = {
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
}
response = requests.post("https://app.xcloud.host/api/v1/servers/{uuid}/sites/git", headers=headers, json=payload)
print(response.json())
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://app.xcloud.host/api/v1/servers/{uuid}/sites/git',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN',
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => '{
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
}',
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
using System.Net.Http;
using System.Text;
var client = new HttpClient();
var request = new HttpRequestMessage(new HttpMethod("POST"), "https://app.xcloud.host/api/v1/servers/{uuid}/sites/git");
request.Headers.Add("Authorization", "Bearer YOUR_TOKEN");
request.Content = new StringContent(@"{
""site_type"": ""laravel"",
""repository"": {
""provider_uuid"": ""123e4567-e89b-12d3-a456-426614174000"",
""full_name"": ""my-org/my-app"",
""url"": ""https://github.com/laravel/laravel.git"",
""branch"": ""main""
},
""domain"": {
""mode"": ""staging"",
""name"": ""app.example.com"",
""staging_domain"": ""string"",
""title"": ""string"",
""ssl_provider"": ""xcloud""
},
""php_version"": ""8.3"",
""node_version"": ""20"",
""database"": {
""provider"": ""in_server"",
""engine"": ""mysql"",
""version"": ""string"",
""name"": ""string"",
""user"": ""string"",
""password"": ""string""
},
""deploy_script"": ""string"",
""env_file_content"": ""string"",
""env_file_path"": ""string"",
""enable_push_deploy"": false,
""install_redis"": false,
""web_root"": ""public"",
""serving_mode"": ""static"",
""install_command"": ""string"",
""build_command"": ""string"",
""start_command"": ""string"",
""port"": 1
}", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.*;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.xcloud.host/api/v1/servers/{uuid}/sites/git"))
.header("Authorization", "Bearer YOUR_TOKEN")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
}
"""))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response #
{
"success": true,
"message": "Git site deployment initiated.",
"data": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"domain": "app.example.com",
"type": "laravel",
"branch": "main",
"status": "migration_init",
"server_uuid": "123e4567-e89b-12d3-a456-426614174000"
}
}
{
"success": false,
"message": "The given data was invalid.",
"data": null,
"errors": {
"domain": [
"The domain field is required when mode is live."
]
}
}
{
"success": false,
"message": "Unauthenticated.",
"data": null
}
{
"success": false,
"message": "This action is unauthorized. Your token is missing the required scope.",
"data": null
}
{
"success": false,
"message": "Private SSH repositories are not supported by this endpoint. Connect a git provider and pass repository.provider_uuid, or use a public HTTPS repository URL.",
"data": null
}
Creates a site on the Server and deploys it from a git repository. This is an asynchronous operation — the response returns as soon as the deployment has been accepted, and the site remains in a provisioning state until the first deploy finishes. The whole creation is atomic: if any step fails, no partial site is left behind.
Choosing a repository source
- Connected provider — send
repository.provider_uuid+repository.full_name. Use this for private repositories: xCloud authorises the deploy key on the repo for you, and can install a push-to-deploy webhook (enable_push_deploy). - Public URL — send
repository.url(anhttps://clone URL). Cloned anonymously; no key required. The.gitsuffix is added for you if you omit it.
Private SSH URLs (git@…) are rejected. A deploy key has to be authorised on the remote before the first clone, and that handshake cannot be completed inside a single API call — a key minted here would not exist on the remote, so the deploy would fail later at clone time rather than failing now. Connect a git provider instead.
Defaults worth knowing
repository.branch— omit to use the repository’s default branch. –database— only WordPress gets a database by default. Everything else defaults to none; passdatabase.provider: in_serverto request one.php_version— falls back to the Server’s version. –site_user, and the database name/user/password when not supplied, are derived for you.
Requires the write:servers scope.
Path Parameters #
| Name | Type | Required | Description |
|---|---|---|---|
uuid | string (uuid) | Required | UUID of the Server |
Request Body #
Content type: application/json — required
| Field | Type | Required | Description |
|---|---|---|---|
site_type | string | Required | The application type to provision for. Allowed: laravel, nodejs, custom-php, wordpress, lovable |
repository | object | Required | Supply EITHER `provider_uuid` + `full_name` (a connected provider — required for private repositories) OR `url` (a public HTTPS clone URL). Private SSH URLs (`git@…`) are rejected; see the endpoint description. |
repository.provider_uuid | string (uuid) | Optional | UUID of a connected git provider. Required unless `url` is given. |
repository.full_name | string | Optional | `owner/repo` on the provider. Required with `provider_uuid`. |
repository.url | string | Optional | Public HTTPS clone URL. Required unless `provider_uuid` is given. The `.git` suffix is added if omitted. |
repository.branch | string | Optional | Defaults to the repository's default branch. |
domain | object | Required | |
domain.mode | string | Required | `staging` puts the site on a free xCloud hostname; `live` uses a domain you control. Allowed: staging, live |
domain.name | string | Required | For `staging`, the hostname label. For `live`, the full domain. |
domain.staging_domain | string | Optional | Staging suffix to use (defaults to the Server's). |
domain.title | string | Optional | Site title (`live` only; defaults to the domain). |
domain.ssl_provider | string | Optional | Allowed: xcloud, custom, cloudflare |
php_version | string | Optional | Defaults to the Server's PHP version. |
node_version | string | Optional | |
database | object | Optional | Only WordPress provisions a database by default; other types default to none. |
database.provider | string | Optional | Allowed: in_server, null |
database.engine | string | Optional | Engine to install when the Server has no database yet. |
database.version | string | Optional | |
database.name | string | Optional | Generated if omitted. |
database.user | string | Optional | Generated if omitted. |
database.password | string | Optional | Generated if omitted. |
deploy_script | string | Optional | Runs after every deployment. |
env_file_content | string | Optional | Contents of the site's .env file. |
env_file_path | string | Optional | Subdirectory for the .env file (Node only). |
enable_push_deploy | boolean | Optional | Deploy on push. Requires a connected provider. |
install_redis | boolean | Optional | |
web_root | string | Optional | |
serving_mode | string | Optional | Node apps only. `ssr`/`hybrid` require `start_command` and `port`. Allowed: static, ssr, hybrid |
install_command | string | Optional | |
build_command | string | Optional | |
start_command | string | Optional | Required for `ssr`/`hybrid` Node apps. |
port | integer | Optional | Required for `ssr`/`hybrid` Node apps. |
{
"site_type": "laravel",
"repository": {
"provider_uuid": "123e4567-e89b-12d3-a456-426614174000",
"full_name": "my-org/my-app",
"url": "https://github.com/laravel/laravel.git",
"branch": "main"
},
"domain": {
"mode": "staging",
"name": "app.example.com",
"staging_domain": "string",
"title": "string",
"ssl_provider": "xcloud"
},
"php_version": "8.3",
"node_version": "20",
"database": {
"provider": "in_server",
"engine": "mysql",
"version": "string",
"name": "string",
"user": "string",
"password": "string"
},
"deploy_script": "string",
"env_file_content": "string",
"env_file_path": "string",
"enable_push_deploy": false,
"install_redis": false,
"web_root": "public",
"serving_mode": "static",
"install_command": "string",
"build_command": "string",
"start_command": "string",
"port": 1
}
Responses #
202 — Deployment accepted #
| Field | Type | Required | Description |
|---|---|---|---|
success | boolean | Optional | |
message | string | Optional | |
data | object | Optional | |
data.uuid | string (uuid) | Optional | |
data.domain | string | Optional | |
data.type | string | Optional | |
data.branch | string | Optional | |
data.status | string | Optional | |
data.server_uuid | string (uuid) | Optional |
{
"success": true,
"message": "Git site deployment initiated.",
"data": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"domain": "app.example.com",
"type": "laravel",
"branch": "main",
"status": "migration_init",
"server_uuid": "123e4567-e89b-12d3-a456-426614174000"
}
}
400 — Request validation failed #
| Field | Type | Required | Description |
|---|---|---|---|
success | boolean | Optional | |
message | string | Optional | |
data | object | Optional | |
errors | object | Optional |
{
"success": false,
"message": "The given data was invalid.",
"data": null,
"errors": {
"domain": [
"The domain field is required when mode is live."
]
}
}
401 — Missing or invalid authentication token #
| Field | Type | Required | Description |
|---|---|---|---|
success | boolean | Optional | |
message | string | Optional | |
data | object | Optional |
{
"success": false,
"message": "Unauthenticated.",
"data": null
}
403 — Token lacks the required scope #
| Field | Type | Required | Description |
|---|---|---|---|
success | boolean | Optional | |
message | string | Optional | |
data | object | Optional |
{
"success": false,
"message": "This action is unauthorized. Your token is missing the required scope.",
"data": null
}
404 — Server or git provider not found #
422 — Validation error, or a business rule Violation — an unprovisioned Server, a private SSH repository URL, or a Docker Server (use docker-compose deployment). #
{
"success": false,
"message": "Private SSH repositories are not supported by this endpoint. Connect a git provider and pass repository.provider_uuid, or use a public HTTPS repository URL.",
"data": null
}
