{"openapi":"3.1.0","info":{"title":"PanelNew Public API","version":"1.0.0","description":"Frozen safe scopes. Tokens do not satisfy MFA. Pages are ordered by opaque ID; next is the exclusive cursor. Job payloads and results are omitted. POST accepts {}. Credential creation and sensitive operations require the session UI."},"servers":[{"url":"/api/v1"}],"components":{"securitySchemes":{"scopedToken":{"type":"http","scheme":"bearer","bearerFormat":"pn1_<32 random bytes>","description":"host.read, sites.read, jobs.read, host.refresh, sites.health"}}},"paths":{"/host":{"get":{"summary":"Latest host observation","x-panelnew-scope":"host.read","security":[{"scopedToken":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/host/refresh":{"post":{"summary":"Queue safe host observation","x-panelnew-scope":"host.refresh","security":[{"scopedToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"string","format":"uuid"}},"additionalProperties":false}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/sites":{"get":{"summary":"Visible sites","x-panelnew-scope":"sites.read","security":[{"scopedToken":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["items","next"],"properties":{"items":{"type":"array","maxItems":100,"items":{"type":"object","required":["id","name","domain","runtime","state","updated_at"],"properties":{"id":{"type":"string","pattern":"^s[a-f0-9]{16}$"},"name":{"type":"string"},"domain":{"type":"string"},"runtime":{"type":"string"},"state":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":false}},"next":{"type":["string","null"]}},"additionalProperties":false}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"after","schema":{"type":"string","maxLength":128}}]}},"/sites/{id}":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","pattern":"^s[a-f0-9]{16}$"}}],"get":{"summary":"Read visible site","x-panelnew-scope":"sites.read","security":[{"scopedToken":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["site"],"properties":{"site":{"type":"object","required":["id","name","domain","runtime","state","updated_at"],"properties":{"id":{"type":"string","pattern":"^s[a-f0-9]{16}$"},"name":{"type":"string"},"domain":{"type":"string"},"runtime":{"type":"string"},"state":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":false}}}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/sites/{id}/health":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","pattern":"^s[a-f0-9]{16}$"}}],"post":{"summary":"Queue site health probe","x-panelnew-scope":"sites.health","security":[{"scopedToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"string","format":"uuid"}},"additionalProperties":false}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/jobs":{"get":{"summary":"Visible host and site jobs","x-panelnew-scope":"jobs.read","security":[{"scopedToken":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["items","next"],"properties":{"items":{"type":"array","maxItems":100,"items":{"type":"object","required":["id","job_type","state","resource_type","resource_id","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"job_type":{"type":"string"},"state":{"type":"string"},"resource_type":{"type":"string","enum":["host","site"]},"resource_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":false}},"next":{"type":["string","null"]}},"additionalProperties":false}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"after","schema":{"type":"string","maxLength":128}}]}},"/jobs/{id}":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"summary":"Read safe job status","x-panelnew-scope":"jobs.read","security":[{"scopedToken":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["job"],"properties":{"job":{"type":"object","required":["id","job_type","state","resource_type","resource_id","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"job_type":{"type":"string"},"state":{"type":"string"},"resource_type":{"type":"string","enum":["host","site"]},"resource_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":false}}}}}},"400":{"description":"Invalid bounded input","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient scope or current owner permissions","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Minute rate limit reached","content":{"application/json":{"schema":{"type":"object"}}}}}}}}}