curl --request POST \
--url https://api.getfloo.com/v1/apps/{app_id}/preflight \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"managed_services": [
{
"name": "default",
"tier": "<string>"
}
],
"env": "dev",
"services": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"min_instances": 1,
"max_instances": 1,
"instances": 1,
"env_managed": [
"<string>"
]
}
]
}
'import requests
url = "https://api.getfloo.com/v1/apps/{app_id}/preflight"
payload = {
"managed_services": [
{
"name": "default",
"tier": "<string>"
}
],
"env": "dev",
"services": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"min_instances": 1,
"max_instances": 1,
"instances": 1,
"env_managed": ["<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({
managed_services: [{name: 'default', tier: '<string>'}],
env: 'dev',
services: [
{
name: '<string>',
cpu: '<string>',
memory: '<string>',
min_instances: 1,
max_instances: 1,
instances: 1,
env_managed: ['<string>']
}
]
})
};
fetch('https://api.getfloo.com/v1/apps/{app_id}/preflight', 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.getfloo.com/v1/apps/{app_id}/preflight",
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([
'managed_services' => [
[
'name' => 'default',
'tier' => '<string>'
]
],
'env' => 'dev',
'services' => [
[
'name' => '<string>',
'cpu' => '<string>',
'memory' => '<string>',
'min_instances' => 1,
'max_instances' => 1,
'instances' => 1,
'env_managed' => [
'<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.getfloo.com/v1/apps/{app_id}/preflight"
payload := strings.NewReader("{\n \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\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.getfloo.com/v1/apps/{app_id}/preflight")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getfloo.com/v1/apps/{app_id}/preflight")
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 \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"managed_services": {
"to_provision": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_retry": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_retain": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_orphan": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_deprovision": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"in_flight_deprovisioning": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
]
},
"runtime_services": [
{
"name": "<string>",
"runtime_plan": {
"env": "<string>",
"service_type": "<string>",
"availability": "<string>",
"declared": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": 123,
"max_instances": 123,
"instances": 123
},
"effective": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": 123,
"max_instances": 123,
"instances": 123
},
"sources": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": "<string>",
"max_instances": "<string>",
"instances": "<string>"
},
"components": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"source": "<string>"
}
],
"instance_total": {
"cpu": "<string>",
"memory": "<string>"
},
"cpu_allocation": "<string>",
"cpu_allocation_reason": "<string>",
"warnings": [
"<string>"
]
},
"generated_env_keys": [
"<string>"
]
}
],
"scheduled_deprovisions": [
{
"type": "postgres",
"name": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"dev_deprovision_after": "2023-11-07T05:31:56Z",
"prod_deprovision_after": "2023-11-07T05:31:56Z"
}
],
"summary": {
"action_count": 0,
"destructive_count": 0,
"estimated_duration_seconds": 123
},
"destructive": false,
"data_loss": false
}{
"detail": {
"code": "<string>",
"message": "<string>"
}
}Run Preflight
Compute the preflight plan for declared state against deployed state.
Read-only. Returns a PreflightPlan describing every action deploy would take (provision) and every orphan that would remain (destruction requires explicit CLI command).
curl --request POST \
--url https://api.getfloo.com/v1/apps/{app_id}/preflight \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"managed_services": [
{
"name": "default",
"tier": "<string>"
}
],
"env": "dev",
"services": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"min_instances": 1,
"max_instances": 1,
"instances": 1,
"env_managed": [
"<string>"
]
}
]
}
'import requests
url = "https://api.getfloo.com/v1/apps/{app_id}/preflight"
payload = {
"managed_services": [
{
"name": "default",
"tier": "<string>"
}
],
"env": "dev",
"services": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"min_instances": 1,
"max_instances": 1,
"instances": 1,
"env_managed": ["<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({
managed_services: [{name: 'default', tier: '<string>'}],
env: 'dev',
services: [
{
name: '<string>',
cpu: '<string>',
memory: '<string>',
min_instances: 1,
max_instances: 1,
instances: 1,
env_managed: ['<string>']
}
]
})
};
fetch('https://api.getfloo.com/v1/apps/{app_id}/preflight', 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.getfloo.com/v1/apps/{app_id}/preflight",
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([
'managed_services' => [
[
'name' => 'default',
'tier' => '<string>'
]
],
'env' => 'dev',
'services' => [
[
'name' => '<string>',
'cpu' => '<string>',
'memory' => '<string>',
'min_instances' => 1,
'max_instances' => 1,
'instances' => 1,
'env_managed' => [
'<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.getfloo.com/v1/apps/{app_id}/preflight"
payload := strings.NewReader("{\n \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\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.getfloo.com/v1/apps/{app_id}/preflight")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getfloo.com/v1/apps/{app_id}/preflight")
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 \"managed_services\": [\n {\n \"name\": \"default\",\n \"tier\": \"<string>\"\n }\n ],\n \"env\": \"dev\",\n \"services\": [\n {\n \"name\": \"<string>\",\n \"cpu\": \"<string>\",\n \"memory\": \"<string>\",\n \"min_instances\": 1,\n \"max_instances\": 1,\n \"instances\": 1,\n \"env_managed\": [\n \"<string>\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"managed_services": {
"to_provision": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_retry": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_retain": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_orphan": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"to_deprovision": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
],
"in_flight_deprovisioning": [
{
"type": "postgres",
"name": "<string>",
"risk": {
"tier": 1,
"destructive": true,
"data_loss": true
},
"tier": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"data_impact": "<string>"
}
]
},
"runtime_services": [
{
"name": "<string>",
"runtime_plan": {
"env": "<string>",
"service_type": "<string>",
"availability": "<string>",
"declared": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": 123,
"max_instances": 123,
"instances": 123
},
"effective": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": 123,
"max_instances": 123,
"instances": 123
},
"sources": {
"cpu": "<string>",
"memory": "<string>",
"min_instances": "<string>",
"max_instances": "<string>",
"instances": "<string>"
},
"components": [
{
"name": "<string>",
"cpu": "<string>",
"memory": "<string>",
"source": "<string>"
}
],
"instance_total": {
"cpu": "<string>",
"memory": "<string>"
},
"cpu_allocation": "<string>",
"cpu_allocation_reason": "<string>",
"warnings": [
"<string>"
]
},
"generated_env_keys": [
"<string>"
]
}
],
"scheduled_deprovisions": [
{
"type": "postgres",
"name": "<string>",
"managed_service_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"dev_deprovision_after": "2023-11-07T05:31:56Z",
"prod_deprovision_after": "2023-11-07T05:31:56Z"
}
],
"summary": {
"action_count": 0,
"destructive_count": 0,
"estimated_duration_seconds": 123
},
"destructive": false,
"data_loss": false
}{
"detail": {
"code": "<string>",
"message": "<string>"
}
}Authorizations
A floo_ API key.
Headers
Organization to act in; defaults to the one joined most recently.
Path Parameters
Body
Payload the CLI sends to POST /v1/apps/{app_id}/preflight.
Strict field validation: a misspelled field from a CLI/API version skew must fail loud (422) rather than silently route the user into a bad plan.
Response
Successful Response
Top-level preflight plan.
Additional domain plans (services, env vars, routes, crons, domains) are added as the planner grows. The shape is deliberately additive, with new fields defaulting to empty plans so existing consumers keep working.
destructive is true iff acting on this plan would modify or destroy
existing state. Pure provisioning is additive and not destructive.
scheduled_deprovisions is a sibling status readout, not an action bin.
Reconciliation plan for managed services (postgres, redis, storage).
Managed services are stateful and CLI-canonical. Deploy creates to_provision, retries to_retry (FAILED rows that the user has redeclared), retains to_retain, and NEVER acts on to_orphan — orphans require explicit removal. Rows currently being deprovisioned surface in in_flight_deprovisioning so they remain visible to operators instead of silently disappearing from the plan.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Aggregate counts and risk flags for a preflight plan.
Show child attributes
Show child attributes