curl --request POST \
--url https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_job_id": "<string>",
"lease_id": "<string>",
"owner_approved": true,
"candidate_spec": {},
"current_spec_hash": "<string>"
}
'import requests
url = "https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout"
payload = {
"source_job_id": "<string>",
"lease_id": "<string>",
"owner_approved": True,
"candidate_spec": {},
"current_spec_hash": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
source_job_id: '<string>',
lease_id: '<string>',
owner_approved: true,
candidate_spec: {},
current_spec_hash: '<string>'
})
};
fetch('https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout', 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}/retry-rollout",
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([
'source_job_id' => '<string>',
'lease_id' => '<string>',
'owner_approved' => true,
'candidate_spec' => [
],
'current_spec_hash' => '<string>'
]),
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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout"
payload := strings.NewReader("{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"success": true,
"message": "<string>",
"stack_id": "<string>",
"job_id": "<string>",
"source_job_id": "<string>",
"lease_id": "<string>",
"server_id": "<string>",
"idempotent_replay": true,
"provider_vm_create_requested": false,
"bootstrap_token": "<string>",
"bootstrap_token_expires_at": "2023-11-07T05:31:56Z",
"owner_spec_endpoint": "<string>",
"owner_spec_scopes": [
"<string>"
]
},
"meta": {
"total": 123,
"page": 123,
"per_page": 123,
"managed_runtime_inventory_complete": true,
"worker_inventory_sha256": "<string>",
"managed_runtime_active_lease_ids": [
"<string>"
],
"managed_runtime_inactive_lease_ids": [
"<string>"
],
"managed_runtime_lease_generation_digests": [
{
"lease_id": "<string>",
"resource_generation_digest": "<string>"
}
],
"managed_runtime_duplicate_lease_ids": [
"<string>"
],
"managed_runtime_attachment_conflict_lease_ids": [
"<string>"
]
}
}{
"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>"
}
}Retry one failed StackKit deployment rollout on its exact existing managed VM
Validates the owned failed deploy, its exact active foundation lease,
and canonical Node in one server-side operation. The deterministic
durable replacement bypasses provider VM creation, wins a durable
tenant/stack compatibility execution claim before handler entry, and is
replayed on repeated calls to this operation. The claim serializes different
jobs for the same StackKit deployment across replicas and remains
fail-closed as running after a process crash until operator reconciliation.
curl --request POST \
--url https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_job_id": "<string>",
"lease_id": "<string>",
"owner_approved": true,
"candidate_spec": {},
"current_spec_hash": "<string>"
}
'import requests
url = "https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout"
payload = {
"source_job_id": "<string>",
"lease_id": "<string>",
"owner_approved": True,
"candidate_spec": {},
"current_spec_hash": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
source_job_id: '<string>',
lease_id: '<string>',
owner_approved: true,
candidate_spec: {},
current_spec_hash: '<string>'
})
};
fetch('https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout', 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}/retry-rollout",
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([
'source_job_id' => '<string>',
'lease_id' => '<string>',
'owner_approved' => true,
'candidate_spec' => [
],
'current_spec_hash' => '<string>'
]),
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://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout"
payload := strings.NewReader("{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kombify.io/v1/techstack/api/v1/stacks/{id}/retry-rollout")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"source_job_id\": \"<string>\",\n \"lease_id\": \"<string>\",\n \"owner_approved\": true,\n \"candidate_spec\": {},\n \"current_spec_hash\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"success": true,
"message": "<string>",
"stack_id": "<string>",
"job_id": "<string>",
"source_job_id": "<string>",
"lease_id": "<string>",
"server_id": "<string>",
"idempotent_replay": true,
"provider_vm_create_requested": false,
"bootstrap_token": "<string>",
"bootstrap_token_expires_at": "2023-11-07T05:31:56Z",
"owner_spec_endpoint": "<string>",
"owner_spec_scopes": [
"<string>"
]
},
"meta": {
"total": 123,
"page": 123,
"per_page": 123,
"managed_runtime_inventory_complete": true,
"worker_inventory_sha256": "<string>",
"managed_runtime_active_lease_ids": [
"<string>"
],
"managed_runtime_inactive_lease_ids": [
"<string>"
],
"managed_runtime_lease_generation_digests": [
{
"lease_id": "<string>",
"resource_generation_digest": "<string>"
}
],
"managed_runtime_duplicate_lease_ids": [
"<string>"
],
"managed_runtime_attachment_conflict_lease_ids": [
"<string>"
]
}
}{
"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>"
}
}Autorizaciones
OIDC/JWKS bearer token. Self-hosted defaults to Pocket ID; SaaS uses Auth0 through the edge. PocketBase JWT is legacy migration compatibility only.
Parámetros de ruta
Stack ID
Cuerpo
Exact failed deploy job used as immutable retry evidence.
1Exact active managed foundation lease bound to the failed job.
1Required true when supplying a canonical initial-rollout repair candidate.
Optional canonical StackSpec repairing missing route, access and data dependencies of already admitted modules. The pinned CLI validates it; revision CAS and candidate digest bind retries. Applied installations must use their existing change-set authority.
Normalized current node intent hash for an exact failed INIT whose immutable retry lineage proves a prior failed APPLY on this runtime. Required only for that partial INIT recovery; rejected on other paths. This is solely the CLI atomic CAS precondition, never authorization. Obtain through the pinned CLI resolve on the same current canonical node document. The durable receipt seals this value and lineage against changed replay.
^sha256:[a-f0-9]{64}$