Routing booleans for the SPA — is the instance claimed, is setup finished.
GET
/v1/setup/status
const url = 'http://localhost:8080/v1/setup/status';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}use reqwest;
#[tokio::main]pub async fn main() { let url = "http://localhost:8080/v1/setup/status";
let client = reqwest::Client::new(); let response = client.get(url) .send() .await;
let results = response.unwrap() .json::<serde_json::Value>() .await .unwrap();
dbg!(results);}curl --request GET \ --url http://localhost:8080/v1/setup/statusUnauthenticated and deliberately minimal: returns only whether an admin exists and whether the setup flow has been completed, so the SPA can send a virgin instance to /setup instead of a login screen no one can satisfy. Exposes nothing an attacker can use beyond those two booleans.
Responses
Section titled “Responses”OK.
Media typeapplication/json
object
admin_exists
required
True once any admin account exists (env-bootstrap or claim).
boolean
setup_completed
required
True once the wizard finished or was explicitly skipped.
boolean
Examplegenerated
{ "admin_exists": true, "setup_completed": true}