curl --request PUT \
--url https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"server_id": "<string>",
"mode": "custom-domain",
"domain": "example.com",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"lease_id": "<string>",
"ensure_rollout": false
}
'import requests
url = "https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing"
payload = {
"server_id": "<string>",
"mode": "custom-domain",
"domain": "example.com",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"lease_id": "<string>",
"ensure_rollout": False
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
server_id: '<string>',
mode: 'custom-domain',
domain: 'example.com',
provenance: {
source: 'kombify-cloud',
dns_provider: 'cloudflare',
zone_id: '<string>',
external_domain_id: '<string>'
},
lease_id: '<string>',
ensure_rollout: false
})
};
fetch('https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing', 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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing",
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([
'server_id' => '<string>',
'mode' => 'custom-domain',
'domain' => 'example.com',
'provenance' => [
'source' => 'kombify-cloud',
'dns_provider' => 'cloudflare',
'zone_id' => '<string>',
'external_domain_id' => '<string>'
],
'lease_id' => '<string>',
'ensure_rollout' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing"
payload := strings.NewReader("{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}"
response = http.request(request)
puts response.read_body{
"data": {
"desired": {
"stack_id": "<string>",
"server_id": "<string>",
"revision": 2,
"mode": "custom-domain",
"domain": "<string>",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"rollout_status": "not_requested",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"lease_id": "<string>",
"rollout_job_id": "<string>",
"reason_code": "<string>"
},
"observed": {
"status": "unknown",
"applied": true,
"applied_revision": 1
},
"rollout": {
"status": "not_requested",
"job_id": "<string>",
"reason_code": "<string>"
},
"idempotent_replay": true
},
"meta": {}
}{
"data": {
"desired": {
"stack_id": "<string>",
"server_id": "<string>",
"revision": 2,
"mode": "custom-domain",
"domain": "<string>",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"rollout_status": "not_requested",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"lease_id": "<string>",
"rollout_job_id": "<string>",
"reason_code": "<string>"
},
"observed": {
"status": "unknown",
"applied": true,
"applied_revision": 1
},
"rollout": {
"status": "not_requested",
"job_id": "<string>",
"reason_code": "<string>"
},
"idempotent_replay": true
},
"meta": {}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}Ensure the desired routing overlay for one exact StackKit deployment and Node
Atomically persists an idempotent, revisioned routing overlay without mutating the user’s immutable intent. server_id is always exact and mandatory. lease_id is mandatory for managed runtimes and omitted for a local/Basement runtime which has no lease. For a managed target, a true ensure_rollout request dispatches the existing deploy pipeline only after proving that its selected active foundation lease and canonical Node equal this exact target. The API never reports the resulting job as already applied. The overlay is consumed only while deriving StackKits artifacts and this path never creates or selects a replacement VM.
curl --request PUT \
--url https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"server_id": "<string>",
"mode": "custom-domain",
"domain": "example.com",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"lease_id": "<string>",
"ensure_rollout": false
}
'import requests
url = "https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing"
payload = {
"server_id": "<string>",
"mode": "custom-domain",
"domain": "example.com",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"lease_id": "<string>",
"ensure_rollout": False
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
server_id: '<string>',
mode: 'custom-domain',
domain: 'example.com',
provenance: {
source: 'kombify-cloud',
dns_provider: 'cloudflare',
zone_id: '<string>',
external_domain_id: '<string>'
},
lease_id: '<string>',
ensure_rollout: false
})
};
fetch('https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing', 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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing",
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([
'server_id' => '<string>',
'mode' => 'custom-domain',
'domain' => 'example.com',
'provenance' => [
'source' => 'kombify-cloud',
'dns_provider' => 'cloudflare',
'zone_id' => '<string>',
'external_domain_id' => '<string>'
],
'lease_id' => '<string>',
'ensure_rollout' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing"
payload := strings.NewReader("{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/routing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"server_id\": \"<string>\",\n \"mode\": \"custom-domain\",\n \"domain\": \"example.com\",\n \"provenance\": {\n \"source\": \"kombify-cloud\",\n \"dns_provider\": \"cloudflare\",\n \"zone_id\": \"<string>\",\n \"external_domain_id\": \"<string>\"\n },\n \"lease_id\": \"<string>\",\n \"ensure_rollout\": false\n}"
response = http.request(request)
puts response.read_body{
"data": {
"desired": {
"stack_id": "<string>",
"server_id": "<string>",
"revision": 2,
"mode": "custom-domain",
"domain": "<string>",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"rollout_status": "not_requested",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"lease_id": "<string>",
"rollout_job_id": "<string>",
"reason_code": "<string>"
},
"observed": {
"status": "unknown",
"applied": true,
"applied_revision": 1
},
"rollout": {
"status": "not_requested",
"job_id": "<string>",
"reason_code": "<string>"
},
"idempotent_replay": true
},
"meta": {}
}{
"data": {
"desired": {
"stack_id": "<string>",
"server_id": "<string>",
"revision": 2,
"mode": "custom-domain",
"domain": "<string>",
"provenance": {
"source": "kombify-cloud",
"dns_provider": "cloudflare",
"zone_id": "<string>",
"external_domain_id": "<string>"
},
"rollout_status": "not_requested",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"lease_id": "<string>",
"rollout_job_id": "<string>",
"reason_code": "<string>"
},
"observed": {
"status": "unknown",
"applied": true,
"applied_revision": 1
},
"rollout": {
"status": "not_requested",
"job_id": "<string>",
"reason_code": "<string>"
},
"idempotent_replay": true
},
"meta": {}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "<string>",
"details": "<unknown>"
}
}प्राधिकरण
OIDC/JWKS bearer token. Self-hosted defaults to Pocket ID; SaaS uses Auth0 through the edge. PocketBase JWT is legacy migration compatibility only.
हेडर
Stable key for safely replaying this exact routing mutation.
1 - 256Optional optimistic-concurrency routing revision, for example "3".
पथ पैरामीटर
Stack ID
बॉडी
Exact canonical ServerRuntime target belonging to the stack and owner. For a managed lease this is the server_id exposed by the operations/ worker projection. If that read-model row is not present yet, TechStack may create only this deterministic ID from the validated exact lease.
1custom-domain Normalized custom domain; schemes, paths, ports, and wildcards are rejected.
1"example.com"
Show child attributes
Show child attributes
Exact RuntimeLease for a managed target. Omit for a local/Basement ServerRuntime that genuinely has no lease; invented leases are rejected.
1Request reconciliation without implying that it has already been dispatched or applied.
