{"openapi":"3.1.0","info":{"title":"floo API","version":"0.1.0"},"servers":[{"url":"https://api.getfloo.com"}],"paths":{"/v1/apps/{app_id}/consumers":{"get":{"tags":["app-api-keys"],"summary":"List App Consumers","description":"List all machine consumers for an app.","operationId":"app_api_keys_list_app_consumers","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"post":{"tags":["app-api-keys"],"summary":"Create App Consumer","description":"Create a machine consumer for an app.","operationId":"app_api_keys_create_app_consumer","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConsumerRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/consumers/{consumer_id}":{"delete":{"tags":["app-api-keys"],"summary":"Delete App Consumer","description":"Delete a machine consumer and soft-revoke all its keys.","operationId":"app_api_keys_delete_app_consumer","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"consumer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Consumer Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/consumers/{consumer_id}/keys":{"get":{"tags":["app-api-keys"],"summary":"List Consumer Keys","description":"List active (non-revoked) keys for a consumer.","operationId":"app_api_keys_list_consumer_keys","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerKeyListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"consumer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Consumer Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"post":{"tags":["app-api-keys"],"summary":"Mint Consumer Api Key","description":"Mint a new consumer API key. The raw key is returned exactly once.","operationId":"app_api_keys_mint_consumer_api_key","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintConsumerKeyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintedAppConsumerApiKeyResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"consumer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Consumer Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/api-keys/{key_id}":{"delete":{"tags":["app-api-keys"],"summary":"Admin Revoke Key","description":"Admin revoke a consumer key by id.\n\nReturns 204 whether the key was already revoked or active (idempotent).\nReturns 404 if the key_id does not belong to this app.","operationId":"app_api_keys_admin_revoke_key","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/alerts":{"post":{"tags":["alerts"],"summary":"Create Alert Rule","description":"Create an alert rule for an app.","operationId":"alerts_create_alert_rule","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlertRuleRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["alerts"],"summary":"List Alert Rules","description":"List all alert rules for an app.","operationId":"alerts_list_alert_rules","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/alerts/{alert_id}":{"patch":{"tags":["alerts"],"summary":"Update Alert Rule","description":"Update an alert rule.","operationId":"alerts_update_alert_rule","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Alert Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["alerts"],"summary":"Delete Alert Rule","description":"Delete an alert rule.","operationId":"alerts_delete_alert_rule","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Alert Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/invites":{"post":{"tags":["app-memberships"],"summary":"Create Invite","description":"Create durable app-bound invitation intent before attempting delivery.","operationId":"app_memberships_create_invite","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAppInviteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAppInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["app-memberships"],"summary":"List Invites","description":"List the newest bounded page of invitation history.","operationId":"app_memberships_list_invites","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppInviteListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cursor"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/invites/{invite_id}/resend":{"post":{"tags":["app-memberships"],"summary":"Resend Invite","description":"Rotate and redeliver a pending invitation.","operationId":"app_memberships_resend_invite","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAppInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invite Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/invites/{invite_id}":{"delete":{"tags":["app-memberships"],"summary":"Revoke Invite","description":"Revoke pending invitation intent.","operationId":"app_memberships_revoke_invite","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invite Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/members":{"get":{"tags":["app-memberships"],"summary":"List Members","description":"List active global identities explicitly authorized for an app.","operationId":"app_memberships_list_members","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppMembershipListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cursor"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/members/{membership_id}":{"patch":{"tags":["app-memberships"],"summary":"Update Member Role","description":"Change tenant role and revoke sessions that carry the old role.","operationId":"app_memberships_update_member_role","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppMembershipRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppMembershipResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"membership_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Membership Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["app-memberships"],"summary":"Remove Member","description":"Revoke app membership, sessions, and user-bound API keys atomically.","operationId":"app_memberships_remove_member","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"membership_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Membership Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/app-invites/preview":{"post":{"tags":["app-memberships"],"summary":"Preview Invite","description":"Return PII-minimized invitation context without granting authority.","operationId":"app_memberships_preview_invite","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppInviteTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppInvitePreviewResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/apps/{app_id}/analytics":{"get":{"tags":["analytics"],"summary":"Get App Analytics","description":"Return analytics for a single app, tier-gated by org plan.","operationId":"analytics_get_app_analytics","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppAnalyticsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(7d|30d|90d)$","default":"30d","title":"Period"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/analytics":{"get":{"tags":["analytics"],"summary":"Get Org Analytics","description":"Return analytics across all apps in the org, tier-gated by org plan.","operationId":"analytics_get_org_analytics","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgAnalyticsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(7d|30d|90d)$","default":"30d","title":"Period"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/app-memberships":{"get":{"tags":["app-memberships"],"summary":"List Org App Memberships","description":"List global users with active app memberships in the current organization.","operationId":"app_memberships_list_org_app_memberships","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgAppMemberListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/audit":{"get":{"tags":["audit"],"summary":"List Audit Events","description":"List audit events for an organization. Requires admin role.","operationId":"audit_list_audit_events","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Per Page"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditAction"},{"type":"null"}],"title":"Action"}},{"name":"actor_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"}},{"name":"actor_api_key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Api Key Id"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/audit/export.csv":{"get":{"tags":["audit"],"summary":"Export Audit Events Csv","description":"Export audit events as CSV. Requires admin role.\n\nReturns up to 10,000 events matching the filters, ordered by created_at desc.","operationId":"audit_export_audit_events_csv","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditAction"},{"type":"null"}],"title":"Action"}},{"name":"actor_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"}},{"name":"actor_api_key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Api Key Id"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/device":{"post":{"tags":["auth"],"summary":"Device Authorize","description":"Initiate device code flow for CLI authentication.","operationId":"auth_device_authorize","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceAuthResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/auth/device/token":{"post":{"tags":["auth"],"summary":"Device Token","description":"Poll for device code completion. Returns 202 while pending.","operationId":"auth_device_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"202":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenPendingResponse"}}}}},"security":[]}},"/v1/auth/api-keys":{"post":{"tags":["auth"],"summary":"Create Api Key","description":"Create a named API key. Returns the raw key once.","operationId":"auth_create_api_key","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["auth"],"summary":"List Api Keys","description":"List all API keys for the authenticated user (masked).","operationId":"auth_list_api_keys","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/api-keys/{key_id}":{"delete":{"tags":["auth"],"summary":"Revoke Api Key","description":"Revoke (delete) an API key. Returns 404 if not found or not owned.","operationId":"auth_revoke_api_key","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/whoami":{"get":{"tags":["auth"],"summary":"Whoami","description":"Return the identity of the authenticated user.","operationId":"auth_whoami","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoamiResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/dashboard-bootstrap":{"get":{"tags":["auth"],"summary":"Dashboard Bootstrap","description":"Authorize and hydrate the dashboard's bounded first view in one request.\n\nThe identity-only result is returned before any organization read for\nwaitlisted and app-only users. Only an admitted control-plane identity may\nresolve org authority, consume its effective read scope, and hydrate the\ninitial org/app projection.","operationId":"auth_dashboard_bootstrap","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardBootstrapResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/me":{"patch":{"tags":["auth"],"summary":"Update Profile","description":"Update the authenticated user's profile.","operationId":"auth_update_profile","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoamiResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps":{"post":{"tags":["apps"],"summary":"Create App","description":"Create a new app.","operationId":"apps_create_app","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAppRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["apps"],"summary":"List Apps","description":"List apps owned by the current org.","operationId":"apps_list_apps","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, 1-100. Default 20 to keep dashboards snappy. The cap is an ordinary pagination bound, not a perf-cliff guard: this endpoint hydrates at most three deploy rows per app, so the work it does scales with the page, not with an app's deploy history.","default":20,"title":"Per Page"},"description":"Page size, 1-100. Default 20 to keep dashboards snappy. The cap is an ordinary pagination bound, not a perf-cliff guard: this endpoint hydrates at most three deploy rows per app, so the work it does scales with the page, not with an app's deploy history."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}":{"get":{"tags":["apps"],"summary":"Get App","description":"Get a single app by ID.\n\nPasses ``user`` to ``get_user_app`` so a 404 for an app that lives in\none of the caller's *other* orgs surfaces with ``owning_org`` in the\nerror detail, letting the dashboard render a \"switch to org X\"\naffordance instead of a raw 404.","operationId":"apps_get_app","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["apps"],"summary":"Update App","description":"Update an app. Changing its access mode needs admin scope, like the deploy path.","operationId":"apps_update_app","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["apps"],"summary":"Delete App","description":"Delete an app. Requires org admin role.","operationId":"apps_delete_app","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/projects":{"post":{"tags":["projects"],"summary":"Create Project","description":"Create a managed project for the authorized organization through the project service.","operationId":"projects_create_project","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["projects"],"summary":"List Projects","description":"Return connected projects whose managed repository identity matches the organization.","operationId":"projects_list_projects","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/projects/{app_id}/git-token":{"post":{"tags":["projects"],"summary":"Git Token","description":"Issue a repository-scoped write token or reject missing projects and GitHub failures.","operationId":"projects_git_token","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitTokenResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/envs":{"get":{"tags":["environments"],"summary":"List Environments","description":"List all environments for an app.","operationId":"environments_list_environments","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"post":{"tags":["environments"],"summary":"Create Environment","description":"Create a new environment (ADMIN only).","operationId":"environments_create_environment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEnvironmentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/envs/{env_id}":{"patch":{"tags":["environments"],"summary":"Update Environment","description":"Update an environment's settings (e.g. access_mode).","operationId":"environments_update_environment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvironmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Env Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["environments"],"summary":"Delete Environment","description":"Delete an environment and tear down its Cloud Run services.\n\nPreview envs delete freely; dev and prod require `force=true` since\nlosing them affects every future push/release. An app's last remaining\nenvironment cannot be deleted — use DELETE /v1/apps/{id} instead.","operationId":"environments_delete_environment","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Environments Delete Environment"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Env Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Required to delete non-preview (dev/prod) environments.","default":false,"title":"Force"},"description":"Required to delete non-preview (dev/prod) environments."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout","description":"Open Stripe Checkout (new plan) or Customer Portal (manage billing). Admin only.","operationId":"billing_create_checkout","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/checkout/confirm":{"post":{"tags":["billing"],"summary":"Confirm Checkout","description":"Confirm a completed Stripe Session for its currently authorized org admin.\n\nStripe's customer and client reference must agree with stored org authority.\nMembership is rechecked under the writer lock before any reconciliation.\nSubscription reconciliation retains its org lock and webhook-race semantics.\n\nStripe failures return retryable 502 CHECKOUT_CONFIRM_FAILED. Pending\nSessions or subscription propagation return 409 CHECKOUT_CONFIRM_PENDING\nonly after authorization. A reconciled org still without a billable plan\nemits the ERROR-level CHECKOUT_CONFIRM_NO_PLAN marker: brief propagation\nraces are retryable, but persistent absence strands a paying customer and\nmust be loud rather than silently bouncing them back to the paywall.","operationId":"billing_confirm_checkout","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutConfirmRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Create Portal","description":"Create a Stripe Customer Portal Session. Admin only.","operationId":"billing_create_portal","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/balance":{"get":{"tags":["billing"],"summary":"Get Paygo Balance","description":"Read money and admission inputs under the canonical authority lock order.","operationId":"billing_get_paygo_balance","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoBalanceResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/saved-card":{"get":{"tags":["billing"],"summary":"Get Paygo Saved Card","description":"Read the organization's consented overage card details from Stripe for admins.","operationId":"billing_get_paygo_saved_card","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoSavedCardResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/history":{"get":{"tags":["billing"],"summary":"Get Paygo History","description":"Page only the authenticated organization's immutable events by append order.","operationId":"billing_get_paygo_history","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoHistoryResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"before_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":9223372036854775807,"minimum":1},{"type":"null"}],"title":"Before Sequence"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/notifications":{"get":{"tags":["billing"],"summary":"Get Paygo Notifications","description":"Read only this organization's frozen notice evidence, without sending mail.","operationId":"billing_get_paygo_notifications","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoNotificationsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"before_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Before Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/funding-sessions":{"post":{"tags":["billing"],"summary":"Create Funding Session","description":"Create or resume a Stripe Checkout credit purchase for an org admin.","operationId":"billing_create_funding_session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoFundingSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoFundingSessionResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/funding-attempts/{attempt_id}":{"get":{"tags":["billing"],"summary":"Get Funding Attempt","description":"Return server-observed state after a browser redirect or later resume.","operationId":"billing_get_funding_attempt","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaygoFundingAttemptResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"attempt_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Attempt Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/spend-cap":{"get":{"tags":["billing"],"summary":"Get Spend Cap","description":"Get the current spend cap for the org. Admin only.","operationId":"billing_get_spend_cap","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendCapResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"post":{"tags":["billing"],"summary":"Set Spend Cap","description":"Set budget protection for the org. Admin only.","operationId":"billing_set_spend_cap","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendCapRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendCapResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/paygo/auto-top-up":{"get":{"tags":["billing"],"summary":"Get Auto Top Up","description":"Read the org's auto top-up state. Admin only.","operationId":"billing_get_auto_top_up","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTopUpResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"post":{"tags":["billing"],"summary":"Set Auto Top Up","description":"Change the org's auto top-up switch and audit it atomically. Admin only.","operationId":"billing_set_auto_top_up","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTopUpRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTopUpResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/limits":{"get":{"tags":["billing"],"summary":"Get Plan Limits","description":"Return the resource limits for the org's current plan.","operationId":"billing_get_plan_limits","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanLimitsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/apps/{app_id}/cost-breakdown":{"get":{"tags":["billing"],"summary":"App Cost Breakdown","description":"Return a per-service cost breakdown for an app over a billing period.","operationId":"billing_app_cost_breakdown","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppCostBreakdownResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Period to query: \"current_billing_period\", \"current_month\", \"last_month\", or \"last_7d\".","default":"current_billing_period","title":"Period"},"description":"Period to query: \"current_billing_period\", \"current_month\", \"last_month\", or \"last_7d\"."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/billing/orgs/me/cost-breakdown":{"get":{"tags":["billing"],"summary":"Org Cost Breakdown","description":"Return per-app compute cost totals for the org over a billing period.","operationId":"billing_org_cost_breakdown","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCostBreakdownResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Period to query: \"current_billing_period\", \"current_month\", \"last_month\", or \"last_7d\".","default":"current_billing_period","title":"Period"},"description":"Period to query: \"current_billing_period\", \"current_month\", \"last_month\", or \"last_7d\"."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/cron":{"get":{"tags":["cron"],"summary":"List Cron Jobs","description":"List all cron jobs for an app environment.","operationId":"cron_list_cron_jobs","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronJobListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/cron/{name}":{"get":{"tags":["cron"],"summary":"Get Cron Job","description":"Get a single cron job by name.","operationId":"cron_get_cron_job","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronJobResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"env","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/cron/{name}/run":{"post":{"tags":["cron"],"summary":"Run Cron Job","description":"Manually trigger a cron job.","operationId":"cron_run_cron_job","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronJobRunResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"env","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys":{"post":{"tags":["deploys"],"summary":"Create Deploy","description":"Create a deploy from a commit SHA (source downloaded from GitHub).","operationId":"deploys_create_deploy","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeployRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["deploys"],"summary":"List Deploys","description":"List deploys for an app, optionally filtered by service and/or environment.","operationId":"deploys_list_deploys","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":1},{"type":"null"}],"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor returned as `next_cursor`. Existing `page`/`per_page` parameters remain supported for older clients.","title":"Cursor"},"description":"Opaque pagination cursor returned as `next_cursor`. Existing `page`/`per_page` parameters remain supported for older clients."},{"name":"service_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentName"},{"type":"null"}],"title":"Env"}},{"name":"commit_sha","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[0-9a-f]{40}$"},{"type":"null"}],"description":"Full 40-character lowercase Git commit SHA (`git rev-parse HEAD`). Returns the deploys built from exactly that commit; when none exists, the deploy a coalesced push of it was folded into (its `coalesced_commits` lists the SHA). After `git push`, an empty page means the push has not registered yet: retry shortly, then GET the deploy with `wait` until `status` is terminal.","title":"Commit Sha"},"description":"Full 40-character lowercase Git commit SHA (`git rev-parse HEAD`). Returns the deploys built from exactly that commit; when none exists, the deploy a coalesced push of it was folded into (its `coalesced_commits` lists the SHA). After `git push`, an empty page means the push has not registered yet: retry shortly, then GET the deploy with `wait` until `status` is terminal."},{"name":"include_build_logs","in":"query","required":false,"schema":{"type":"boolean","description":"When true, includes `build_logs` in every deploy row. The default is false so deploy history stays compact and agent-safe. Note: `null` is ambiguous when false — it may mean \"no logs were captured\" (the underlying column is null) or \"logs exist but this query suppressed them\". Fetch `GET /v1/apps/{app_id}/deploys/{deploy_id}` for the canonical per-deploy `build_logs` value.","default":false,"title":"Include Build Logs"},"description":"When true, includes `build_logs` in every deploy row. The default is false so deploy history stays compact and agent-safe. Note: `null` is ambiguous when false — it may mean \"no logs were captured\" (the underlying column is null) or \"logs exist but this query suppressed them\". Fetch `GET /v1/apps/{app_id}/deploys/{deploy_id}` for the canonical per-deploy `build_logs` value."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys/{deploy_id}":{"get":{"tags":["deploys"],"summary":"Get Deploy","description":"Get a deploy, optionally holding the request until its watch finishes.","operationId":"deploys_get_deploy","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"deploy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Deploy Id"}},{"name":"wait","in":"query","required":false,"schema":{"type":"integer","maximum":1650,"minimum":0,"description":"Seconds (0-1650) to hold the request until `status` is terminal (`live`, `failed`, `superseded`, `cancelled`) or `awaiting_approval` (a human must approve). 0 returns at once. After `git push`, list deploys with `commit_sha` (empty means the push has not registered yet; retry shortly), then GET the deploy with `wait`; if `status` is still in progress when the wait ends, GET again.","default":0,"title":"Wait"},"description":"Seconds (0-1650) to hold the request until `status` is terminal (`live`, `failed`, `superseded`, `cancelled`) or `awaiting_approval` (a human must approve). 0 returns at once. After `git push`, list deploys with `commit_sha` (empty means the push has not registered yet; retry shortly), then GET the deploy with `wait`; if `status` is still in progress when the wait ends, GET again."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys/{deploy_id}/steps":{"get":{"tags":["deploys"],"summary":"List Deploy Steps","description":"List all pipeline steps for a deploy, with per-step logs.","operationId":"deploys_list_deploy_steps","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeployStepDetailResponse"},"title":"Response Deploys List Deploy Steps"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"deploy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Deploy Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys/{deploy_id}/logs/stream":{"get":{"tags":["deploys"],"summary":"Stream Deploy Logs","description":"Stream build logs via Server-Sent Events.","operationId":"deploys_stream_deploy_logs","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"deploy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Deploy Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys/{deploy_id}/cancel":{"post":{"tags":["deploys"],"summary":"Cancel Deploy","description":"Cancel an in-progress deploy, marking it and its services as FAILED.","operationId":"deploys_cancel_deploy","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"deploy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Deploy Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/deploys/{deploy_id}/approval":{"get":{"tags":["deploys"],"summary":"Get Deploy Approval","description":"The approval record for a deploy (the gated plan to render) — any org member reads.","operationId":"deploys_get_deploy_approval","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequestResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"deploy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Deploy Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/pr-approvals/{approval_id}":{"get":{"tags":["pr-approvals"],"summary":"Get Pr Approval","description":"Read a PR approval record (any org member) for the dashboard to render.","operationId":"pr_approvals_get_pr_approval","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrApprovalRequestResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Approval Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/dev-session":{"post":{"tags":["dev-session"],"summary":"Create Dev Session","description":"Create a dev session and return the caller's Neon-backed env vars.","operationId":"dev_session_create_dev_session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDevSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDevSessionResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/dev-session/{session_id}":{"delete":{"tags":["dev-session"],"summary":"Delete Dev Session","description":"End a dev session by shortening its data-preserving lease.","operationId":"dev_session_delete_dev_session","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/doctor/managed-services":{"get":{"tags":["doctor"],"summary":"Diagnose Managed Services","description":"Report failed provisions and teardowns of canonical and preview managed resources.","operationId":"doctor_diagnose_managed_services","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedServicesDoctorResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/doctor/drift":{"get":{"tags":["doctor"],"summary":"Diagnose Resource Drift","description":"Check row membership against LIVE evidence, without probing providers.","operationId":"doctor_diagnose_resource_drift","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceDoctorResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/doctor/accounts":{"get":{"tags":["doctor"],"summary":"Diagnose Accounts","description":"Diagnose an app's accounts-mode posture in one round trip.\n\nReturns six things the user asked for in feedback 64268e05:\n  (a) what config requests (apps.access_mode + access_policy)\n  (b) what the gateway is actually serving (per gateway_routes row)\n  (c) which /__floo/* endpoints are wired (derived: accounts-mode routes\n      handle these intercepts; public-mode routes pass them through)\n  (d) whether identity headers will reach the app (derived: same\n      condition as floo-endpoints-wired — accounts-mode gateway routes\n      inject X-Floo-User-* on every proxied request)\n  (e) latest deploy's per-environment request map and whether its target propagated\n\nThe drift list highlights mismatches the platform can detect without\nout-of-band probing — anything more involved (curling the runtime URL,\ninspecting WorkOS state) belongs in a separate runbook, not here.","operationId":"doctor_diagnose_accounts","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountsDoctorResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/edge/routes":{"get":{"tags":["edge"],"summary":"List Edge Routes","description":"List the customer-safe edge route table for one app.","operationId":"edge_list_edge_routes","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgeRouteListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentName"},{"type":"null"}],"description":"Optional environment filter. Omit to inspect every app route.","title":"Env"},"description":"Optional environment filter. Omit to inspect every app route."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/env":{"post":{"tags":["env"],"summary":"Set Env Var","description":"Set (create or update) an environment variable.","operationId":"env_set_env_var","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetEnvVarRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVarResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["env"],"summary":"List Env Vars","description":"List environment variables for an app's environment.\n\nWhen service_id is provided, returns vars scoped to that service\nplus app-level vars (those with no service assignment).\nWhen omitted, returns ALL vars (all services + unassigned).","operationId":"env_list_env_vars","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVarListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"name":"service_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/env/{key}":{"get":{"tags":["env"],"summary":"Get Env Var","description":"Get a single env var's plaintext value. Write-scoped.\n\nWhen ``service_id`` is provided, returns the value the service would see\nat runtime — service-scoped var if one exists, otherwise the app-level\n(``service_id=None``) var. This mirrors ``list_env_vars``: anything\n``list`` would show for the service must also be reachable via ``get``.","operationId":"env_get_env_var","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVarPlaintextResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"name":"service_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["env"],"summary":"Delete Env Var","description":"Delete an environment variable.","operationId":"env_delete_env_var","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"name":"service_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/env/import":{"post":{"tags":["env"],"summary":"Import Env Vars","description":"Bulk upsert environment variables.\n\nGenerated service-location keys are skipped and reported in ``skipped``;\nthey never mutate stored values.","operationId":"env_import_env_vars","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportEnvVarsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportEnvVarsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/db/query":{"post":{"tags":["db"],"summary":"Query Database","description":"Execute a SQL query against the app's provisioned database.","operationId":"db_query_database","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DbQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DbQueryResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/db/schema":{"get":{"tags":["db"],"summary":"Get Schema","description":"Return the database schema (tables, columns, types) for the app's database.","operationId":"db_get_schema","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DbSchemaResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","default":"dev","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services":{"post":{"tags":["managed-services"],"summary":"Create Managed Service","description":"Provision a managed service for an app.\n\nRequires WRITE scope because the response returns fresh credential material.","operationId":"managed_services_create_managed_service","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateManagedServiceRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedServiceDetailResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["managed-services"],"summary":"List Managed Services","description":"List all managed services for an app.","operationId":"managed_services_list_managed_services","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedServiceListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}":{"get":{"tags":["managed-services"],"summary":"Get Managed Service","description":"Get details for a specific managed service, including credentials.\n\nRequires WRITE scope — returns decrypted credentials.","operationId":"managed_services_get_managed_service","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedServiceDetailResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["managed-services"],"summary":"Delete Managed Service","description":"Resume serialized provider cleanup with short app lifecycle transitions.","operationId":"managed_services_delete_managed_service","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/redis/stats":{"get":{"tags":["managed-services"],"summary":"Get Redis Stats","description":"Return key and memory metrics for a managed Redis instance.","operationId":"managed_services_get_redis_stats","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedisStatsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"enum":["dev","prod"],"type":"string","default":"dev","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/redis/keys":{"get":{"tags":["managed-services"],"summary":"List Redis Keys","description":"List keys from a managed Redis instance.","operationId":"managed_services_list_redis_keys","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedisKeysResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"enum":["dev","prod"],"type":"string","default":"dev","title":"Env"}},{"name":"prefix","in":"query","required":false,"schema":{"type":"string","default":"","title":"Prefix"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":75,"minimum":1,"default":75,"title":"Limit"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/redis/value":{"get":{"tags":["managed-services"],"summary":"Get Redis Key Detail","description":"Return a preview of one Redis key.","operationId":"managed_services_get_redis_key_detail","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedisKeyDetailResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"key","in":"query","required":true,"schema":{"type":"string","title":"Key"}},{"name":"env","in":"query","required":false,"schema":{"enum":["dev","prod"],"type":"string","default":"dev","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/signed-url":{"post":{"tags":["managed-services"],"summary":"Generate Signed Url","description":"Generate a signed read URL or signed upload policy for a storage object.\n\nRequires WRITE scope because the URL grants direct storage-object access.\nThe ``env`` query parameter selects between the dev and prod buckets that\nStage 1 provisions per managed service. Defaults to ``dev`` for callers\nthat haven't been updated to pass the parameter explicitly.","operationId":"managed_services_generate_signed_url","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUrlRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUrlResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","pattern":"^(dev|prod|preview)$","default":"dev","title":"Env"}},{"name":"preview","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/usage":{"get":{"tags":["managed-services"],"summary":"Get Storage Usage","description":"Get usage metrics for a storage bucket.","operationId":"managed_services_get_storage_usage","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageUsageResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"env","in":"query","required":true,"schema":{"enum":["dev","prod"],"type":"string","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/objects":{"get":{"tags":["managed-services"],"summary":"List Storage Objects","description":"List objects inside a managed storage bucket.","operationId":"managed_services_list_storage_objects","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"env","in":"query","required":true,"schema":{"enum":["dev","prod"],"type":"string","title":"Env"}},{"name":"prefix","in":"query","required":false,"schema":{"type":"string","default":"","title":"Prefix"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":75,"minimum":1,"default":75,"title":"Limit"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["managed-services"],"summary":"Delete Storage Object","description":"Delete one live object, retaining its noncurrent generation for restore.","operationId":"managed_services_delete_storage_object","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024,"title":"Path"}},{"name":"env","in":"query","required":false,"schema":{"enum":["dev","prod"],"type":"string","default":"dev","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/storage/versions":{"get":{"tags":["managed-services"],"summary":"List Storage Object Versions","description":"List restorable generations for one storage object.\n\nRequires WRITE scope because object generations expose customer object\nmetadata and are the discovery half of a customer-data restore.","operationId":"managed_services_list_storage_object_versions","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectVersionsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"object_path","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024,"description":"Exact object path to inspect for restorable generations.","title":"Object Path"},"description":"Exact object path to inspect for restorable generations."},{"name":"env","in":"query","required":false,"schema":{"type":"string","pattern":"^(dev|prod)$","default":"dev","title":"Env"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":75,"minimum":1,"default":75,"title":"Limit"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/managed-services/{service_id}/storage/restore":{"post":{"tags":["managed-services"],"summary":"Restore Storage Object Generation","description":"Restore one managed-storage object generation over the live object.","operationId":"managed_services_restore_storage_object_generation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectRestoreRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectRestoreResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"env","in":"query","required":false,"schema":{"type":"string","pattern":"^(dev|prod)$","default":"dev","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/preflight":{"post":{"tags":["preflight"],"summary":"Run Preflight","description":"Compute the preflight plan for declared state against deployed state.\n\nRead-only. Returns a PreflightPlan describing every action deploy would\ntake (provision) and every orphan that would remain (destruction requires\nexplicit CLI command).","operationId":"preflight_run_preflight","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclaredState"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflightPlan"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews":{"post":{"tags":["previews"],"summary":"Create Preview","description":"Create or refresh isolated preview infrastructure for a branch.","operationId":"previews_create_preview","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePreviewRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["previews"],"summary":"List Previews","description":"List preview environments for an app.","operationId":"previews_list_previews","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}":{"get":{"tags":["previews"],"summary":"Get Preview","description":"Return one preview environment.","operationId":"previews_get_preview","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["previews"],"summary":"Delete Preview","description":"Tear down a preview environment and its isolated infrastructure.","operationId":"previews_delete_preview","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/resources":{"get":{"tags":["previews"],"summary":"List Preview Managed Resource Branches","description":"List managed resource branches backing one preview.","operationId":"previews_list_preview_managed_resource_branches","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewManagedResourceBranchListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/resources/{resource_key}":{"get":{"tags":["previews"],"summary":"Get Preview Managed Resource Branch","description":"Inspect one managed resource branch backing a preview.","operationId":"previews_get_preview_managed_resource_branch","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewManagedResourceBranchResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"resource_key","in":"path","required":true,"schema":{"type":"string","title":"Resource Key"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/resources/{resource_key}/reset":{"post":{"tags":["previews"],"summary":"Reset Preview Managed Resource Branch Route","description":"Reset one managed resource branch backing a preview.","operationId":"previews_reset_preview_managed_resource_branch_route","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewManagedResourceBranchResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"resource_key","in":"path","required":true,"schema":{"type":"string","title":"Resource Key"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/database-branches":{"get":{"tags":["previews"],"summary":"List Preview Database Branches","description":"List managed Postgres branches backing one preview.","operationId":"previews_list_preview_database_branches","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewDatabaseBranchListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/database-branches/{name}":{"get":{"tags":["previews"],"summary":"Get Preview Database Branch","description":"Inspect one managed Postgres branch backing a preview.","operationId":"previews_get_preview_database_branch","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewDatabaseBranchResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/previews/{slug}/database-branches/{name}/reset":{"post":{"tags":["previews"],"summary":"Reset Preview Database Branch Route","description":"Reset is not yet available for Neon preview database branches.","operationId":"previews_reset_preview_database_branch_route","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewDatabaseBranchResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/domains":{"get":{"tags":["domains"],"summary":"List Domains","description":"List all custom domains for an app.","operationId":"domains_list_domains","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/domains/{hostname}":{"get":{"tags":["domains"],"summary":"Get Domain","description":"Read one app-owned custom domain and its DNS records.","operationId":"domains_get_domain","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"hostname","in":"path","required":true,"schema":{"type":"string","title":"Hostname"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/envs/{env}/edge-policy":{"get":{"tags":["edge-policy"],"summary":"Get Edge Policy","description":"Read the app+environment edge policy.","operationId":"edge_policy_get_edge_policy","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgePolicyResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"path","required":true,"schema":{"type":"string","title":"Env"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/github/connection":{"post":{"tags":["github"],"summary":"Connect Github","description":"Connect an app to GitHub.\n\nCreates the GitHubConnection flag. If repo_full_name is provided,\nresolves installation_id and sets it on all services without a repo.","operationId":"github_connect_github","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubConnectRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubConnectionResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["github"],"summary":"Disconnect Github","description":"Disconnect an app from GitHub.","operationId":"github_disconnect_github","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Github Disconnect Github"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["github"],"summary":"Get Github Connection","description":"Get the GitHub connection status for an app.","operationId":"github_get_github_connection","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubConnectionResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/github/services/{service_name}":{"put":{"tags":["github"],"summary":"Set Service Github","description":"Set GitHub repo on a specific service.","operationId":"github_set_service_github","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceGitHubRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceGitHubInfo"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_name","in":"path","required":true,"schema":{"type":"string","title":"Service Name"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/setup/begin":{"post":{"tags":["github"],"summary":"Setup Begin","description":"Start the GitHub App installation flow.","operationId":"github_setup_begin","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubSetupBeginResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/setup/poll":{"get":{"tags":["github"],"summary":"Setup Poll","description":"Poll for the GitHub App installation status.","operationId":"github_setup_poll","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubSetupPollResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/setup/select":{"post":{"tags":["github"],"summary":"Setup Select","description":"Bind one installation the caller's own OAuth leg already proved.\n\nSelection narrows an existing proof; it never creates one. The candidate\nlist was written by `setup/oauth-callback` under this exact (org, user)\nsession key, so an installation absent from it is refused even for an org\nadmin — otherwise this endpoint would be a way to claim any installation ID.","operationId":"github_setup_select","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubSetupSelectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubSetupSelectResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/check-repo-access":{"get":{"tags":["github"],"summary":"Check Repo Access","description":"Can floo reach this repo, and if not, exactly why?\n\nAnswers the install question without minting a setup token or creating an\napp. Authorization may complete an already observed setup intent. Causes\nare distinguished only inside installations the org is authorized for;\nsee `_authorized_repo_access`.","operationId":"github_check_repo_access","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubRepoAccessResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"repo","in":"query","required":true,"schema":{"type":"string","description":"Full repo name (owner/repo)","title":"Repo"},"description":"Full repo name (owner/repo)"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/installations":{"get":{"tags":["github"],"summary":"List Github Installations","description":"List floo's active org bindings without checking live GitHub access.","operationId":"github_list_github_installations","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallationsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/github/installations/{installation_id}/repos":{"get":{"tags":["github"],"summary":"Get Installation Repos","description":"List repositories accessible to a GitHub App installation.\n\nOnly allows listing repos for installations the org has a proven binding\nfor, or that the current user's observed setup intent completes.","operationId":"github_get_installation_repos","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubReposResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"installation_id","in":"path","required":true,"schema":{"type":"integer","title":"Installation Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/insights/token":{"get":{"tags":["insights"],"summary":"Get Ingest Token","description":"Mint a short-lived origin-bound ingest token for the JS SDK.","operationId":"insights_get_ingest_token","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestTokenResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[],"parameters":[{"name":"app_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}]}},"/v1/insights/events":{"post":{"tags":["insights"],"summary":"Post Events","description":"Accept a batch of visitor events from the floo JS SDK.\n\nUnauthenticated. IP-rate-limited. The body is parsed as JSON\nregardless of the declared Content-Type header — the SDK uses\n`text/plain` specifically so that `navigator.sendBeacon` and\ncross-origin fetch both count as CORS \"simple requests\" and skip\npreflight. The server still validates the body with the same\nPydantic schema as if it were JSON.\n\nThe `app_id` must resolve to an existing app — we don't leak\nwhether the ID was malformed vs missing vs simply unknown.","operationId":"insights_post_events","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/apps/{app_id}/insights":{"get":{"tags":["insights"],"summary":"List Insights","description":"Return aggregated visitor insights for an app over the period.","operationId":"insights_list_insights","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorInsightsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"period","in":"query","required":false,"schema":{"enum":["24h","7d","30d"],"type":"string","default":"7d","title":"Period"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/sdk/floo.js":{"get":{"tags":["insights"],"summary":"Get Sdk Js","description":"Serve the floo JS SDK file for embedding in deployed apps.\n\nThe SDK path is unversioned, so keep the cache short enough that a\nbackend contract change can roll out safely without stranding older\nbrowsers on stale copies for hours.","operationId":"insights_get_sdk_js","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/status":{"get":{"tags":["status"],"summary":"Platform Status","description":"Return the aggregated platform status (public, unauthenticated).\n\nRead through the shared-cache proxy at ``landing/app/status/data/route.ts``.\nDirect callers are rate limited via the public IP bucket. The result is\ncached in-process for 10 seconds (see ``STATUS_CACHE_TTL_SECONDS``), while\nthe landing proxy and its CDN cache prevent visitor count from multiplying\nrequests against that bucket.\n\nReturns CORS-permissive headers because the status page lives on\na different origin (the landing on getfloo.com) than the api\n(api.getfloo.com).","operationId":"status_platform_status","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/apps/{app_id}/logs":{"get":{"tags":["logs"],"summary":"Get Logs","description":"Fetch runtime logs for an app.\n\nIngests from Cloud Logging into Postgres and serves from DB.\nReturns 503 if GCP is not configured (Phase 1 mode).","operationId":"logs_get_logs","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp","title":"Since"},"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp"},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exact severity: DEFAULT, DEBUG, INFO, WARNING, ERROR, CRITICAL","title":"Severity"},"description":"Exact severity: DEFAULT, DEBUG, INFO, WARNING, ERROR, CRITICAL"},{"name":"service","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter logs to a specific service name","title":"Service"},"description":"Filter logs to a specific service name"},{"name":"cron","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter logs to a specific cron job name","title":"Cron"},"description":"Filter logs to a specific cron job name"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"Case-insensitive substring search on log messages","title":"Search"},"description":"Case-insensitive substring search on log messages"},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter logs by environment (dev, prod)","title":"Env"},"description":"Filter logs by environment (dev, prod)"},{"name":"deployment","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter logs by deployment ID, or 'latest' for the app's latest deploy","title":"Deployment"},"description":"Filter logs by deployment ID, or 'latest' for the app's latest deploy"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor from the previous logs response","title":"Cursor"},"description":"Opaque cursor from the previous logs response"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/errors":{"get":{"tags":["errors"],"summary":"Get Error Groups","description":"Fetch error groups for an app, grouped by fingerprint.\n\nReturns 503 if GCP is not configured (Phase 1 mode).","operationId":"errors_get_error_groups","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorGroupsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp","title":"Since"},"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp"},{"name":"service","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter errors to a specific service name","title":"Service"},"description":"Filter errors to a specific service name"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/requests":{"get":{"tags":["requests"],"summary":"Get Request Logs","description":"Fetch gateway-captured HTTP request logs for an app.\n\nSource of truth for what requests hit the public URL, independent of the\napp's own access log. Emits one entry per request proxied or rejected by\nfloo's gateway. Always shows the public URL the caller actually used.","operationId":"requests_get_request_logs","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestLogsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp","title":"Since"},"description":"Duration (e.g. '1h', '30m', '2d') or ISO 8601 timestamp"},{"name":"method","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a specific HTTP method (GET, POST, etc.)","title":"Method"},"description":"Filter to a specific HTTP method (GET, POST, etc.)"},{"name":"status_class","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":5,"minimum":1},{"type":"null"}],"description":"Filter by status-code class: 2=2xx, 3=3xx, 4=4xx, 5=5xx","title":"Status Class"},"description":"Filter by status-code class: 2=2xx, 3=3xx, 4=4xx, 5=5xx"},{"name":"host","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter requests to a specific public hostname","title":"Host"},"description":"Filter requests to a specific public hostname"},{"name":"api_key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by app API key ID, never the raw key","title":"Api Key Id"},"description":"Filter by app API key ID, never the raw key"},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Exclusive end of the time range (ISO 8601)","title":"Until"},"description":"Exclusive end of the time range (ISO 8601)"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"next_cursor from the preceding page","title":"Cursor"},"description":"next_cursor from the preceding page"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/metrics":{"get":{"tags":["metrics"],"summary":"App Metrics","description":"Return real-time metrics for an app over the specified time window.","operationId":"metrics_app_metrics","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppMetricsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"window","in":"query","required":false,"schema":{"enum":["1h","6h","24h","7d"],"type":"string","default":"24h","title":"Window"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/metrics/realtime":{"get":{"tags":["metrics"],"summary":"App Realtime Metrics","description":"Return realtime per-service metrics for an app.\n\nCPU/memory/instance_count fields are always null — they require Cloud\nMonitoring API integration which is not yet implemented.","operationId":"metrics_app_realtime_metrics","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeMetricsResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"period","in":"query","required":false,"schema":{"enum":["5m","1h","24h","7d"],"type":"string","default":"1h","title":"Period"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/health-check":{"post":{"tags":["metrics"],"summary":"App Health Check","description":"Run an on-demand health check against the app's URL.","operationId":"metrics_app_health_check","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthCheckResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs":{"get":{"tags":["orgs"],"summary":"List My Orgs","description":"List the caller's memberships independently of the selected organization.","operationId":"orgs_list_my_orgs","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/me":{"get":{"tags":["orgs"],"summary":"Get Org Me","description":"Return the current user's organization.","operationId":"orgs_get_org_me","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/me/onboarding-complete":{"post":{"tags":["orgs"],"summary":"Complete Onboarding","description":"Mark onboarding as complete for the current org.","operationId":"orgs_complete_onboarding","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}":{"get":{"tags":["orgs"],"summary":"Get Org","description":"Return an organization by ID. Requires membership (platform admins bypass).","operationId":"orgs_get_org","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["orgs"],"summary":"Update Org","description":"Update an organization's name and/or slug. Requires admin role.","operationId":"orgs_update_org","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/members":{"get":{"tags":["orgs"],"summary":"List Members","description":"List all members of an org. Any member can view (platform admins bypass).","operationId":"orgs_list_members","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/members/by-email/{email}":{"get":{"tags":["orgs"],"summary":"Get Member By Email","description":"Look up one member of an org by email address.\n\nResolves email → user_id for member role changes and removals without\nfetching the full member list.\nCaller must be a member of the org (platform admins bypass).\nReturns 404 ``MEMBER_NOT_FOUND`` if no member with that email exists.","operationId":"orgs_get_member_by_email","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/members/{member_user_id}":{"delete":{"tags":["orgs"],"summary":"Remove Member","description":"Remove a member from an org. Admin only.","operationId":"orgs_remove_member","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"member_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Member User Id"}},{"name":"revoke_api_keys","in":"query","required":false,"schema":{"type":"boolean","description":"Also revoke all API keys owned by the removed user.","default":false,"title":"Revoke Api Keys"},"description":"Also revoke all API keys owned by the removed user."},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["orgs"],"summary":"Update Member Role","description":"Update a member's role. Admin only.","operationId":"orgs_update_member_role","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberRoleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"member_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Member User Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/promote":{"post":{"tags":["releases"],"summary":"Promote App","description":"Promote an app to prod.\n\nDeploys the latest dev images to prod Cloud Run services.\nCustomer repositories must publish a GitHub release of a LIVE dev commit instead.\nManaged repositories get a GitHub release after the prod deploy is LIVE.","operationId":"releases_promote_app","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoteRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/releases":{"get":{"tags":["releases"],"summary":"List Releases","description":"List releases for an app, newest first.","operationId":"releases_list_releases","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/releases/{release_id}":{"get":{"tags":["releases"],"summary":"Get Release","description":"Get a single release by ID.","operationId":"releases_get_release","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"release_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Release Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/restart/preflight":{"get":{"tags":["deploys"],"summary":"Preflight Restart","description":"Check current shared restart blockers without reserving a deploy slot.\n\nA 204 response is advisory. A deploy can begin immediately afterward, so\ncallers must still handle every structured error from ``POST /restart``.","operationId":"deploys_preflight_restart","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"services","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"title":"Services"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/restart":{"post":{"tags":["deploys"],"summary":"Restart App","description":"Restart an app by redeploying existing images with fresh env vars.\n\nReturns 202 immediately once the Deploy record is persisted. The actual\nCloud Run redeploy runs out-of-band so the CLI's HTTP timeout never\nfires on a slow restart.","operationId":"deploys_restart_app","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestartRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/invites":{"post":{"tags":["invites"],"summary":"Create Invite","description":"Create an invite for a user to join the org. Admin only.","operationId":"invites_create_invite","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["invites"],"summary":"List Invites","description":"List pending invites for an org. Admin only.","operationId":"invites_list_invites","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/invites/bulk":{"post":{"tags":["invites"],"summary":"Bulk Create Invites","description":"Create multiple invites in one call. Admin only.\n\nEach email is processed independently — duplicates and existing members\nare skipped (not failed). Returns per-email results.","operationId":"invites_bulk_create_invites","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkInviteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/invites/{invite_id}":{"delete":{"tags":["invites"],"summary":"Revoke Invite","description":"Revoke a pending invite. Admin only.","operationId":"invites_revoke_invite","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invite Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/orgs/{org_id}/invites/{invite_id}/resend":{"post":{"tags":["invites"],"summary":"Resend Invite","description":"Resend an invite with a fresh token and extended expiry. Admin only.","operationId":"invites_resend_invite","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invite Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/invites/{token}":{"get":{"tags":["invites"],"summary":"Preview Invite","description":"Preview an invite without accepting. No auth required — lets the\naccept page show the org name before the user signs in.","operationId":"invites_preview_invite","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitePreviewResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}]}},"/v1/invites/{token}/accept":{"post":{"tags":["invites"],"summary":"Accept Invite","description":"Accept an org invite using the token from the invite email.\n\nThis is intentionally identity-only: an app-only or waitlisted user must be\nable to accept the invite that grants control-plane access. API-key owners\nare still capability-gated during credential authentication and require a\nwrite-scoped key for this mutation.","operationId":"invites_accept_invite","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInviteResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/rollback":{"post":{"tags":["deploys"],"summary":"Rollback Deploy","description":"Rollback an app to a previous live deploy image.\n\nRequires ``KeyScope.WRITE``, like promote. Rollback restores\ncode/resources and per-path route declarations, but preserves the target\nenvironment's current app-level access mode. Its deploy row carries no\n``requested_env_access_modes`` map, so historical app-level policy cannot\nsilently replace current policy.","operationId":"deploys_rollback_deploy","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/sales-leads":{"post":{"tags":["sales-leads"],"summary":"Submit Sales Lead","description":"Submit a sales lead from the landing page or dashboard.","operationId":"sales_leads_submit_sales_lead","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitSalesLeadRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesLeadResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/services":{"post":{"tags":["services"],"summary":"Create Service","description":"Create a new service for an app.","operationId":"services_create_service","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["services"],"summary":"List Services","description":"List services for an app.","operationId":"services_list_services","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Environment name (dev, prod)","title":"Env"},"description":"Environment name (dev, prod)"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/services/{service_id}":{"get":{"tags":["services"],"summary":"Get Service","description":"Get a single service by ID.","operationId":"services_get_service","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Environment name (dev, prod)","title":"Env"},"description":"Environment name (dev, prod)"},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["services"],"summary":"Delete Service","description":"Delete an unowned service after its exact runtimes and cron Jobs retire.","operationId":"services_delete_service","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/sessions":{"get":{"tags":["sessions"],"summary":"List Sessions","description":"List active sessions for an app. Requires developer auth + app ownership.","operationId":"sessions_list_sessions","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/auth/sessions/{public_id}":{"delete":{"tags":["sessions"],"summary":"Force Logout Session","description":"Force-logout a session by public_id. Requires developer auth + app ownership.","operationId":"sessions_force_logout_session","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Public Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/topology":{"get":{"tags":["topology"],"summary":"Get App Topology","description":"Return the grouped topology the dashboard should render.","operationId":"topology_get_app_topology","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppTopologyResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"env","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/waitlist":{"post":{"tags":["waitlist"],"summary":"Join Waitlist","description":"Add an email to the pre-GA waitlist.","operationId":"waitlist_join_waitlist","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/v1/notification-preferences":{"get":{"tags":["notification-preferences"],"summary":"List Notification Preferences","description":"Return the current user's effective email notification preferences.\n\nGated on authentication only, not org role: these are a user's own personal\nemail settings, so a viewer (or a user between orgs) can still manage them.","operationId":"notification_preferences_list_notification_preferences","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencesResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["notification-preferences"],"summary":"Update Notification Preference","description":"Turn one category on or off for the current user; return the full updated set.\n\nGated on authentication + a WRITE-capable key, but NOT org role: a viewer can\nstill change their own email settings, while a read-only key cannot.","operationId":"notification_preferences_update_notification_preference","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotificationPreferenceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencesResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/unsubscribe":{"get":{"tags":["notification-preferences"],"summary":"Unsubscribe","description":"Footer-link landing page. Unauthenticated (the HMAC token is the only auth)\nand **non-mutating** — shows a confirm page with a one-click POST button so a\nlink scanner/previewer can't silently unsubscribe the user. The change happens\non POST.","operationId":"notification_preferences_unsubscribe","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"default":{"description":"Error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}]},"post":{"tags":["notification-preferences"],"summary":"Unsubscribe Post","description":"The mutation: the confirm-page button posts here, and it's also the RFC 8058\n``List-Unsubscribe-Post`` target mailbox providers (Gmail/Yahoo) POST for native\none-click. Same token + only-OFF logic; the form body is ignored (token in URL).","operationId":"notification_preferences_unsubscribe_post","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"default":{"description":"Error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}]}},"/v1/notifications/webhooks":{"post":{"tags":["notification-webhooks"],"summary":"Create Webhook Endpoint","description":"Create a notification webhook endpoint for the org.","operationId":"notification_webhooks_create_webhook_endpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreateResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"get":{"tags":["notification-webhooks"],"summary":"List Webhook Endpoints","description":"List all notification webhook endpoints for the org.","operationId":"notification_webhooks_list_webhook_endpoints","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}":{"get":{"tags":["notification-webhooks"],"summary":"Get Webhook Endpoint","description":"Get a single notification webhook endpoint.","operationId":"notification_webhooks_get_webhook_endpoint","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["notification-webhooks"],"summary":"Update Webhook Endpoint","description":"Update a notification webhook endpoint.","operationId":"notification_webhooks_update_webhook_endpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["notification-webhooks"],"summary":"Delete Webhook Endpoint","description":"Delete a notification webhook endpoint.","operationId":"notification_webhooks_delete_webhook_endpoint","responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}/test":{"post":{"tags":["notification-webhooks"],"summary":"Send Webhook Test","description":"Send a test notification to a webhook endpoint.","operationId":"notification_webhooks_send_webhook_test","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestWebhookResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}/deliveries":{"get":{"tags":["notification-webhooks"],"summary":"List Deliveries","description":"List deliveries for a webhook endpoint.","operationId":"notification_webhooks_list_deliveries","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/WebhookDeliveryStatus"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}/deliveries/{delivery_id}":{"get":{"tags":["notification-webhooks"],"summary":"Get Delivery","description":"Get a single delivery with full payload.","operationId":"notification_webhooks_get_delivery","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetailResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Delivery Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}/signing-secret/reveal":{"post":{"tags":["notification-webhooks"],"summary":"Reveal Signing Secret","description":"Reveal the signing secret for a webhook endpoint.","operationId":"notification_webhooks_reveal_signing_secret","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningSecretResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/notifications/webhooks/{endpoint_id}/signing-secret/rotate":{"post":{"tags":["notification-webhooks"],"summary":"Rotate Signing Secret","description":"Generate a new signing secret, replacing the old one.","operationId":"notification_webhooks_rotate_signing_secret","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningSecretResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso":{"get":{"tags":["enterprise-sso"],"summary":"Get Sso Status","description":"Read live, fail-closed SSO connection status.","operationId":"enterprise_sso_get_sso_status","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoStatusResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"delete":{"tags":["enterprise-sso"],"summary":"Remove Sso Binding","description":"Remove floo's binding without deleting WorkOS resources.","operationId":"enterprise_sso_remove_sso_binding","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoStatusResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/refresh":{"post":{"tags":["enterprise-sso"],"summary":"Refresh Sso Status","description":"Explicitly reconcile the local projection from WorkOS.","operationId":"enterprise_sso_refresh_sso_status","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoStatusResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/portal-session":{"post":{"tags":["enterprise-sso"],"summary":"Create Sso Portal Session","description":"Create a five-minute WorkOS Admin Portal session for SSO setup.","operationId":"enterprise_sso_create_sso_portal_session","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoPortalSessionResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/disable":{"post":{"tags":["enterprise-sso"],"summary":"Disable Sso Binding","description":"Disable floo's binding without modifying WorkOS resources.","operationId":"enterprise_sso_disable_sso_binding","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoStatusResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/doctor":{"get":{"tags":["organization-sso"],"summary":"Doctor Sso","description":"Return one live, atomic SSO and current-credential diagnostic.","operationId":"organization_sso_doctor_sso","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoDoctorResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/recovery-code/confirm":{"post":{"tags":["organization-sso"],"summary":"Confirm Sso Recovery Code","description":"Retire the prior token only after the browser confirms the new token.","operationId":"organization_sso_confirm_sso_recovery_code","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoRecoveryCodeConfirmRequest"}}}},"responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/organizations/{org_id}/sso/recovery":{"post":{"tags":["organization-sso"],"summary":"Recover Sso Enforcement","description":"Consume one code to disable enforcement without reading tenant data.","operationId":"organization_sso_recover_sso_enforcement","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSsoRecoveryRequest"}}}},"responses":{"204":{"description":"Successful Response"},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/feedback":{"post":{"tags":["feedback"],"summary":"Submit Feedback","description":"Submit feedback — from CLI, dashboard, or agent.","operationId":"feedback_submit_feedback","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitFeedbackRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/reparo/config":{"get":{"tags":["reparo"],"summary":"Get Reparo Config","description":"Get Reparo configuration for an app.","operationId":"reparo_get_reparo_config","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoConfigResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"No Reparo configuration exists for this app."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"put":{"tags":["reparo"],"summary":"Update Reparo Config","description":"Create or update Reparo configuration for an app.","operationId":"reparo_update_reparo_config","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReparoConfigRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoConfigResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/reparo":{"post":{"tags":["reparo"],"summary":"Trigger Reparo","description":"Manually trigger a Reparo repair event.","operationId":"reparo_trigger_reparo","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerReparoRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoEventResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/reparo/events":{"get":{"tags":["reparo"],"summary":"List Reparo Events","description":"List Reparo events for an app with optional status filter and pagination.","operationId":"reparo_list_reparo_events","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoEventListResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ReparoEventStatus"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/v1/apps/{app_id}/reparo/events/{event_id}":{"get":{"tags":["reparo"],"summary":"Get Reparo Event","description":"Get a single Reparo event by ID.","operationId":"reparo_get_reparo_event","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoEventResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Event Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]},"patch":{"tags":["reparo"],"summary":"Update Event Status","description":"Update a Reparo event status (used by downstream webhook subscribers).","operationId":"reparo_update_event_status","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReparoEventResponse"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Event Id"}},{"$ref":"#/components/parameters/X-Floo-Org-Id"}]}},"/health":{"get":{"summary":"Health","description":"Health check endpoint.\n\n``revision`` echoes Cloud Run's ``K_REVISION`` so the release lane's\ncandidate gate can assert its probe reached the intended revision\n(#1117); omitted outside Cloud Run.","operationId":"health","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"boolean"}]},"type":"object","title":"Response Health"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}}},"components":{"schemas":{"AcceptInviteResponse":{"properties":{"org_id":{"type":"string","format":"uuid","title":"Org Id"},"org_name":{"type":"string","title":"Org Name"},"org_slug":{"type":"string","title":"Org Slug"},"role":{"$ref":"#/components/schemas/OrgRole"}},"type":"object","required":["org_id","org_name","org_slug","role"],"title":"AcceptInviteResponse","description":"Response after accepting an invite."},"AccessMode":{"type":"string","enum":["public","password","accounts","sso"],"title":"AccessMode","description":"Access control mode for an app."},"AccessPolicy":{"type":"string","enum":["invite","domain","open"],"title":"AccessPolicy","description":"Access policy for ACCOUNTS-mode apps."},"AccountsDoctorDrift":{"properties":{"kind":{"type":"string","enum":["no_gateway_routes","access_mode_drift","identity_headers_unreachable","deploy_not_live"],"title":"Kind"},"summary":{"type":"string","title":"Summary"},"likely_fix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Likely Fix"}},"type":"object","required":["kind","summary"],"title":"AccountsDoctorDrift","description":"A single mismatch between requested config and observed serving state.\n\nDrifts are computed inside the doctor route — agents and humans should\nread this list first and treat the per-route detail above as evidence."},"AccountsDoctorLatestDeploy":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"requested_app_access_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested App Access Mode"},"requested_env_access_modes":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Requested Env Access Modes"},"propagated":{"type":"boolean","title":"Propagated"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","status","requested_app_access_mode","propagated","created_at"],"title":"AccountsDoctorLatestDeploy","description":"The most recent deploy and whether its access_mode flip propagated.\n\n`requested_app_access_mode` is non-null when the deploy carried an access-\nmode flip from floo.app.toml. `propagated` is true iff the deploy reached\nLIVE AND every downstream row (apps.access_mode and every gateway_route's\naccess_mode) lands at the requested value. The all-routes check is what\ncatches the canonical bug — apps row got flipped, gateway didn't —\ninstead of declaring success on the apps side alone.\n\nThe LIVE requirement is unconditional: a non-LIVE deploy (FAILED, still\ndeploying, awaiting approval, superseded) reports `propagated:false` even\nwhen it carried no flip, because nothing it requested is in effect yet.\nThat keeps `status` and `propagated` from contradicting each other —\nfeedback #1156 saw `status:failed` + `propagated:true` on one object."},"AccountsDoctorRequested":{"properties":{"access_mode":{"type":"string","title":"Access Mode"},"access_policy":{"type":"string","title":"Access Policy"}},"type":"object","required":["access_mode","access_policy"],"title":"AccountsDoctorRequested","description":"App-level accounts policy seed."},"AccountsDoctorResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"app_name":{"type":"string","title":"App Name"},"requested":{"$ref":"#/components/schemas/AccountsDoctorRequested"},"serving":{"items":{"$ref":"#/components/schemas/AccountsDoctorRoute"},"type":"array","title":"Serving"},"latest_deploy":{"anyOf":[{"$ref":"#/components/schemas/AccountsDoctorLatestDeploy"},{"type":"null"}]},"drift_detected":{"type":"boolean","title":"Drift Detected"},"drift":{"items":{"$ref":"#/components/schemas/AccountsDoctorDrift"},"type":"array","title":"Drift"},"status":{"type":"string","enum":["checked","not_applicable"],"title":"Status"},"checked_routes":{"type":"integer","title":"Checked Routes"}},"type":"object","required":["app_id","app_name","requested","serving","latest_deploy","drift_detected","drift","status","checked_routes"],"title":"AccountsDoctorResponse","description":"Top-level response for `GET /v1/apps/{app_id}/doctor/accounts`.\n\nSix things the user asked for in feedback 64268e05 map directly:\n  (a) requested.access_mode + access_policy\n  (b) serving[*].serving_access_mode\n  (c) serving[*].floo_endpoints_wired\n  (d) serving[*].identity_headers_injected\n  (e) latest_deploy.requested_app_access_mode + .propagated\n\n`drift_detected` is the single health verdict (feedback #1156): True iff\n`drift` is non-empty. It is the one bit a caller branches on, and it is\nwhat the `floo doctor accounts` exit code mirrors (non-zero iff drift was\ndetected), so reading the body and branching on the exit code can never\ndisagree. The `drift` list is the supporting evidence behind the verdict."},"AccountsDoctorRoute":{"properties":{"host":{"type":"string","title":"Host"},"path_prefix":{"type":"string","title":"Path Prefix"},"backend_url":{"type":"string","title":"Backend Url"},"serving_access_mode":{"type":"string","title":"Serving Access Mode"},"expected_access_mode":{"type":"string","title":"Expected Access Mode"},"floo_endpoints_wired":{"type":"boolean","title":"Floo Endpoints Wired"},"identity_headers_injected":{"type":"boolean","title":"Identity Headers Injected"}},"type":"object","required":["host","path_prefix","backend_url","serving_access_mode","expected_access_mode","floo_endpoints_wired","identity_headers_injected"],"title":"AccountsDoctorRoute","description":"One gateway_routes row's view of an app's accounts-mode posture.\n\nApps frequently have multiple routes (per service / per environment), and\nthey can drift independently — that's the failure mode this surface exists\nto expose. Per-route fields are derived (not stored), so the JSON contract\nanswers the user's question without making them join tables themselves.\n\n`expected_access_mode` is the environment's non-null applied mode. Comparing\n`serving_access_mode` against `apps.access_mode` would false-positive on\nlegitimate mixed-mode environments and miss real environment drift."},"AlertMetric":{"type":"string","enum":["error_rate","latency_p95","request_count"],"title":"AlertMetric","description":"Metrics that can be monitored by alert rules."},"AlertOperator":{"type":"string","enum":["gt","lt","gte","lte"],"title":"AlertOperator","description":"Comparison operators for alert thresholds."},"AlertRuleListResponse":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/AlertRuleResponse"},"type":"array","title":"Rules"}},"type":"object","required":["rules"],"title":"AlertRuleListResponse","description":"Response schema for a list of alert rules."},"AlertRuleResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"metric":{"$ref":"#/components/schemas/AlertMetric"},"operator":{"$ref":"#/components/schemas/AlertOperator"},"threshold":{"type":"number","title":"Threshold"},"window_minutes":{"type":"integer","title":"Window Minutes"},"enabled":{"type":"boolean","title":"Enabled"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"cooldown_minutes":{"type":"integer","title":"Cooldown Minutes"},"last_fired_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Fired At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","metric","operator","threshold","window_minutes","enabled","webhook_url","email","cooldown_minutes","last_fired_at","created_at","updated_at"],"title":"AlertRuleResponse","description":"Response schema for a single alert rule."},"ApiKeyListResponse":{"properties":{"api_keys":{"items":{"$ref":"#/components/schemas/ApiKeyResponse"},"type":"array","title":"Api Keys"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["api_keys","total"],"title":"ApiKeyListResponse","description":"Response for listing API keys."},"ApiKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"key_suffix":{"type":"string","title":"Key Suffix"},"scope":{"$ref":"#/components/schemas/KeyScope"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"last_used_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used Ip"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"org_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"},"org_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Name"}},"type":"object","required":["id","name","key_prefix","key_suffix","scope","last_used_at","last_used_ip","created_at","org_id","org_name"],"title":"ApiKeyResponse","description":"Response for a single API key (masked)."},"AppAnalyticsResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"period":{"type":"string","title":"Period"},"summary":{"$ref":"#/components/schemas/AppAnalyticsSummary"},"time_series":{"items":{"$ref":"#/components/schemas/TimeSeriesPoint"},"type":"array","title":"Time Series"},"top_users":{"anyOf":[{"items":{"$ref":"#/components/schemas/TopUser"},"type":"array"},{"type":"null"}],"title":"Top Users"}},"type":"object","required":["app_id","period","summary","time_series","top_users"],"title":"AppAnalyticsResponse","description":"Response for per-app analytics."},"AppAnalyticsSummary":{"properties":{"total_requests":{"type":"integer","title":"Total Requests"},"total_errors":{"type":"integer","title":"Total Errors"},"error_rate":{"type":"number","title":"Error Rate"},"avg_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Latency Ms"},"p95_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"P95 Latency Ms"},"unique_users":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unique Users"},"authenticated_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Authenticated Requests"},"unauthenticated_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unauthenticated Requests"},"gateway_handled_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gateway Handled Requests"},"status_code_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Code Breakdown"},"rejection_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Rejection Breakdown","default":{}}},"type":"object","required":["total_requests","total_errors","error_rate","avg_latency_ms","p95_latency_ms","unique_users","authenticated_requests","unauthenticated_requests","gateway_handled_requests","status_code_breakdown"],"title":"AppAnalyticsSummary","description":"Summary statistics for a single app.\n\nThe auth-count fields are tier-gated (mirroring `unique_users`) and\nadditionally tri-state by aggregator availability:\n- `0` — the aggregator measured zero authenticated requests for this\n  period, OR the period contains no summary data at all (no traffic).\n  Use `total_requests == 0` as the secondary signal to disambiguate\n  \"no data\" from \"measured zero\" if the distinction matters.\n- positive `int` — the aggregator measured it for this period.\n- `None` — either the org's plan does not surface this field (restricted analytics\n  tier), or the period contains at least one summary row that predates\n  the field's introduction. Raw logs are gone for those rows, so the\n  aggregator cannot retroactively populate them; NULL is contagious in\n  the rollup to avoid emitting a falsely-confident integer.\n\nConsumers MUST treat `None` as \"unknown\", not \"zero\". A 0 value with\n`total_requests > 0` carries real signal — for accounts-mode apps it's\nthe asymmetric pattern this field exists to disambiguate from \"no auth\nflow completed\"."},"AppComparisonEntry":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"app_name":{"type":"string","title":"App Name"},"total_requests":{"type":"integer","title":"Total Requests"},"total_errors":{"type":"integer","title":"Total Errors"},"error_rate":{"type":"number","title":"Error Rate"},"avg_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Latency Ms"}},"type":"object","required":["app_id","app_name","total_requests","total_errors","error_rate","avg_latency_ms"],"title":"AppComparisonEntry","description":"A single app entry in the org-level comparison."},"AppConsumerApiKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"consumer_id":{"type":"string","format":"uuid","title":"Consumer Id"},"prefix":{"type":"string","title":"Prefix"},"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"rate_limit_rpm":{"type":"integer","title":"Rate Limit Rpm"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","app_id","consumer_id","prefix","name","scopes","rate_limit_rpm","last_used_at","created_at"],"title":"AppConsumerApiKeyResponse","description":"Expose key metadata without its secret and render null scopes as wildcard access."},"AppCostBreakdownResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"period":{"$ref":"#/components/schemas/CostBreakdownPeriod"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"},"services":{"items":{"$ref":"#/components/schemas/ServiceCostBreakdown"},"type":"array","title":"Services"},"managed_resources":{"items":{"$ref":"#/components/schemas/ManagedResourceCostBreakdown"},"type":"array","title":"Managed Resources"},"unattributed_cost_usd":{"type":"number","title":"Unattributed Cost Usd","default":0.0}},"type":"object","required":["app_id","period","total_cost_usd","services"],"title":"AppCostBreakdownResponse","description":"Per-app cost breakdown response."},"AppCostSummary":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"name":{"type":"string","title":"Name"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"}},"type":"object","required":["app_id","name","total_cost_usd"],"title":"AppCostSummary","description":"Per-app cost summary for the org cost breakdown."},"AppEventsSummary":{"properties":{"mode":{"$ref":"#/components/schemas/ReparoMode"},"webhook_configured":{"type":"boolean","title":"Webhook Configured"},"error_threshold":{"type":"integer","title":"Error Threshold"},"cooldown_minutes":{"type":"integer","title":"Cooldown Minutes"}},"type":"object","required":["mode","webhook_configured","error_threshold","cooldown_minutes"],"title":"AppEventsSummary","description":"Content-free events routing summary embedded in AppResponse."},"AppInviteDeliveryStatus":{"type":"string","enum":["pending","sent","failed","unknown"],"title":"AppInviteDeliveryStatus","description":"Latest non-secret delivery outcome for an invitation."},"AppInviteListResponse":{"properties":{"invites":{"items":{"$ref":"#/components/schemas/AppInviteResponse"},"type":"array","title":"Invites"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["invites"],"title":"AppInviteListResponse","description":"Bounded operator invitation page."},"AppInvitePreviewResponse":{"properties":{"app_name":{"type":"string","title":"App Name"},"inviter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inviter Name"},"role":{"$ref":"#/components/schemas/AppMembershipRole"},"status":{"$ref":"#/components/schemas/AppInviteStatus"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["app_name","inviter_name","role","status","expires_at"],"title":"AppInvitePreviewResponse","description":"PII-minimized public context for a bearer invitation."},"AppInviteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/AppMembershipRole"},"status":{"$ref":"#/components/schemas/AppInviteStatus"},"invited_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Invited By User Id"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"delivery_status":{"$ref":"#/components/schemas/AppInviteDeliveryStatus"},"delivery_attempted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivery Attempted At"},"delivery_provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Provider Id"},"delivery_failure_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Failure Class"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","app_id","email","role","status","invited_by_user_id","expires_at","accepted_at","revoked_at","delivery_status","delivery_attempted_at","delivery_provider_id","delivery_failure_class","created_at"],"title":"AppInviteResponse","description":"Operator-visible durable invitation state."},"AppInviteStatus":{"type":"string","enum":["pending","accepted","revoked","expired"],"title":"AppInviteStatus","description":"Lifecycle state of an app invitation."},"AppInviteTokenRequest":{"properties":{"token":{"type":"string","maxLength":256,"minLength":32,"title":"Token"}},"type":"object","required":["token"],"title":"AppInviteTokenRequest","description":"Bearer invite token transported in a request body, never a URL path."},"AppListResponse":{"properties":{"apps":{"items":{"$ref":"#/components/schemas/AppResponse"},"type":"array","title":"Apps"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["apps","total","page","per_page"],"title":"AppListResponse","description":"Paginated response for listing apps."},"AppMembershipListResponse":{"properties":{"members":{"items":{"$ref":"#/components/schemas/AppMembershipResponse"},"type":"array","title":"Members"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["members"],"title":"AppMembershipListResponse","description":"Bounded operator membership page."},"AppMembershipResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"$ref":"#/components/schemas/AppMembershipRole"},"status":{"$ref":"#/components/schemas/AppMembershipStatus"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","user_id","email","name","role","status","created_at","updated_at"],"title":"AppMembershipResponse","description":"Operator-visible global user membership."},"AppMembershipRole":{"type":"string","enum":["member","admin"],"title":"AppMembershipRole","description":"Authorization role inside a tenant app, never the floo control plane."},"AppMembershipStatus":{"type":"string","enum":["active","revoked"],"title":"AppMembershipStatus","description":"Monotonic authorization decision for a global user and app."},"AppMetricsResponse":{"properties":{"window_hours":{"type":"integer","title":"Window Hours"},"request_count":{"type":"integer","title":"Request Count"},"error_rate":{"type":"number","title":"Error Rate"},"p50_latency_ms":{"type":"integer","title":"P50 Latency Ms"},"p95_latency_ms":{"type":"integer","title":"P95 Latency Ms"},"status_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Breakdown"}},"type":"object","required":["window_hours","request_count","error_rate","p50_latency_ms","p95_latency_ms","status_breakdown"],"title":"AppMetricsResponse","description":"Response for app metrics aggregated over a time window."},"AppResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"status":{"type":"string","title":"Status"},"effective_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Effective Status"},"runtime_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Runtime Status"},"deploy_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deploy Status"},"active_deploy_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Deploy Id"},"active_deploy_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Deploy Step"},"last_deploy_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Id"},"last_deploy_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Outcome"},"last_deploy_failure":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Failure"},"last_deploy_failure_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Failure Stage"},"inferred_health_flags":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Inferred Health Flags"},"access_mode":{"$ref":"#/components/schemas/AccessMode"},"access_policy":{"$ref":"#/components/schemas/AccessPolicy","default":"invite"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"runtime_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Runtime Url"},"health_status":{"$ref":"#/components/schemas/HealthStatus"},"last_health_check_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Health Check At"},"github_connected":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Github Connected"},"events":{"anyOf":[{"$ref":"#/components/schemas/AppEventsSummary"},{"type":"null"}]},"envs":{"items":{"$ref":"#/components/schemas/EnvironmentSummary"},"type":"array","title":"Envs","default":[]},"services":{"items":{"$ref":"#/components/schemas/ServiceSummary"},"type":"array","title":"Services","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","org_id","status","access_mode","url","health_status","last_health_check_at","created_at","updated_at"],"title":"AppResponse","description":"Response for a single app."},"AppTopologyResponse":{"properties":{"application_services":{"items":{"$ref":"#/components/schemas/TopologyComponentResponse"},"type":"array","title":"Application Services"},"managed_services":{"items":{"$ref":"#/components/schemas/TopologyComponentResponse"},"type":"array","title":"Managed Services"},"effective_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Effective Status"},"runtime_status":{"anyOf":[{"type":"string","enum":["running","starting","stopped","degraded"]},{"type":"null"}],"title":"Runtime Status"},"deploy_status":{"anyOf":[{"type":"string","enum":["idle","in_progress","succeeded","failed"]},{"type":"null"}],"title":"Deploy Status"},"active_deploy_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Deploy Id"},"active_deploy_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Deploy Step"},"last_deploy_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Id"},"last_deploy_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Outcome"},"last_deploy_failure":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Failure"},"last_deploy_failure_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Deploy Failure Stage"},"inferred_health_flags":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Inferred Health Flags"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["application_services","managed_services","total"],"title":"AppTopologyResponse","description":"Grouped topology response for a single app."},"ApprovalRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"deploy_id":{"type":"string","format":"uuid","title":"Deploy Id"},"status":{"$ref":"#/components/schemas/ApprovalStatus"},"gated_ops_snapshot":{"items":{},"type":"array","title":"Gated Ops Snapshot"},"requested_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Requested By User Id"},"requested_at":{"type":"string","format":"date-time","title":"Requested At"},"decided_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Decided By User Id"},"decided_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Decided At"},"decision_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Decision Note"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","deploy_id","status","gated_ops_snapshot","requested_by_user_id","requested_at","decided_by_user_id","decided_at","decision_note","expires_at"],"title":"ApprovalRequestResponse","description":"The pending/decided approval record, for the dashboard to render the gated plan."},"ApprovalStatus":{"type":"string","enum":["pending","approved","rejected","expired","superseded"],"title":"ApprovalStatus","description":"Lifecycle status of an approval request."},"AuditAction":{"type":"string","enum":["app.created","app.deleted","deploy.created","deploy.cancelled","deploy.promoted","deploy.rolled_back","deploy.restarted","deploy.approved","deploy.rejected","pr_infra.approved","pr_infra.rejected","pr_infra.carry_forward","edge_policy.set","edge_policy.deleted","preview.created","preview.deleted","preview.database_branch_reset","preview.managed_resource_reset","prod_orphan.torn_down","env.set","env.removed","env.legacy_secrets_reencrypted","login.failed","login.rate_limited","logs.read","error_groups.read","request_logs.read","env.read","dev_session.created","db.query","db_schema.read","db.migrated","managed_service_credentials.read","app_password.read","webhook_secret.revealed","access.broadened","storage_object.restored","storage_object.delete_requested","storage_object.deleted","managed_postgres_backup.created","managed_postgres.restored","managed_postgres.neon_migrated","managed_redis.recovered","managed_provisioning.resolved","api_key.created","api_key.revoked","app_api_key.created","app_api_key.revoked","app_api_key.scope_changed","app_consumer.created","app_consumer.deleted","reparo.config_updated","reparo.triggered","platform_admin.granted","platform_admin.revoked","control_plane_access.granted","provider_usage_exception.applied","provider_usage_exception.waived","cloud_run_usage.replayed","billing_plan_migration.scheduled","enterprise_contract_mrr.set","paygo_funding_session.read","paygo_auto_top_up.set","member.invited","member.removed","app_invite.created","app_invite.resent","app_invite.accepted","app_invite.revoked","app_membership.role_changed","app_membership.revoked","app_legacy_access.revoked","access_mode.changed","sso.configured","sso.portal_session_created","sso.state_changed","sso.disabled","sso.removed","sso.step_up_started","sso.step_up_completed","sso.step_up_denied","sso.step_up_failed","sso.recovery_code_generated","sso.recovery_code_confirm_attempted","sso.recovery_code_confirmed","sso.recovery_code_confirm_denied","sso.enforcement_enable_attempted","sso.enforcement_enabled","sso.enforcement_enable_denied","sso.enforcement_disable_attempted","sso.enforcement_disabled","sso.enforcement_disable_denied","sso.recovery_attempted","sso.recovered","sso.recovery_denied","sso.acquisition_cohort_enabled","sso.acquisition_cohort_disabled"],"title":"AuditAction","description":"Actions that are recorded in the audit log."},"AuditEventListResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/AuditEventResponse"},"type":"array","title":"Events"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["events","total","page","per_page"],"title":"AuditEventListResponse","description":"Paginated response for listing audit events."},"AuditEventResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"},"actor_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"},"actor_api_key_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Api Key Id"},"action":{"type":"string","title":"Action"},"resource_type":{"type":"string","title":"Resource Type"},"resource_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Resource Id"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","org_id","actor_user_id","action","resource_type","resource_id","metadata","ip_address","created_at"],"title":"AuditEventResponse","description":"Response for a single audit event."},"AuthResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"},"email":{"type":"string","title":"Email"},"user_id":{"type":"string","format":"uuid","title":"User Id"}},"type":"object","required":["api_key","email","user_id"],"title":"AuthResponse","description":"Response returned after successful auth."},"AutoTopUpOffReason":{"type":"string","enum":["customer","charge_failed"],"title":"AutoTopUpOffReason","description":"Why an organization has disabled prepaid auto top-up."},"AutoTopUpRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"AutoTopUpRequest","description":"Enable or disable auto top-up without granting saved-card consent."},"AutoTopUpResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"off_reason":{"anyOf":[{"$ref":"#/components/schemas/AutoTopUpOffReason"},{"type":"string","const":"needs_purchase"},{"type":"null"}],"title":"Off Reason"},"threshold_cents":{"type":"integer","title":"Threshold Cents"},"amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Cents"}},"type":"object","required":["enabled","off_reason","threshold_cents","amount_cents"],"title":"AutoTopUpResponse","description":"Current switch state and refill terms derived from settled consent evidence."},"AvailabilityMode":{"type":"string","enum":["on_demand","warm","fixed","paused"],"title":"AvailabilityMode","description":"Describe whether runtime capacity is demand-driven, warm, fixed, or paused."},"BillingMode":{"type":"string","enum":["subscription","prepaid"],"title":"BillingMode","description":"Durable mutually-exclusive customer billing authority."},"BulkInviteRequest":{"properties":{"emails":{"items":{"type":"string","format":"email"},"type":"array","maxItems":100,"minItems":1,"title":"Emails"},"role":{"$ref":"#/components/schemas/OrgRole","default":"member"}},"type":"object","required":["emails"],"title":"BulkInviteRequest","description":"Request body for bulk-inviting multiple users at once."},"BulkInviteResponse":{"properties":{"invited":{"type":"integer","title":"Invited"},"skipped":{"type":"integer","title":"Skipped"},"failed":{"type":"integer","title":"Failed"},"results":{"items":{"$ref":"#/components/schemas/BulkInviteResultEntry"},"type":"array","title":"Results"}},"type":"object","required":["invited","skipped","failed","results"],"title":"BulkInviteResponse","description":"Response after a bulk invite call."},"BulkInviteResultEntry":{"properties":{"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status"},"invite_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["email","status"],"title":"BulkInviteResultEntry","description":"One result from a bulk invite — successful or skipped/failed."},"CheckoutConfirmRequest":{"properties":{"session_id":{"type":"string","maxLength":255,"minLength":1,"pattern":"^cs_","title":"Session Id"}},"type":"object","required":["session_id"],"title":"CheckoutConfirmRequest","description":"Identify the Stripe Session whose purchase is being confirmed."},"CheckoutResponse":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"upgraded":{"type":"boolean","title":"Upgraded","default":false},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"}},"type":"object","title":"CheckoutResponse","description":"Response for plan upgrade — either a checkout URL or instant upgrade confirmation."},"CoalescedCommitResponse":{"properties":{"requested_commit_sha":{"type":"string","title":"Requested Commit Sha"},"source_repo_full_name":{"type":"string","title":"Source Repo Full Name"},"github_ref":{"type":"string","title":"Github Ref"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"}},"type":"object","required":["requested_commit_sha","source_repo_full_name","github_ref","created_at"],"title":"CoalescedCommitResponse","description":"A pushed commit whose effective outcome is this deploy."},"ColumnInfo":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"nullable":{"type":"boolean","title":"Nullable"}},"type":"object","required":["name","type","nullable"],"title":"ColumnInfo","description":"Describe a database column's name, type, and nullability."},"ConsumerKeyListResponse":{"properties":{"keys":{"items":{"$ref":"#/components/schemas/AppConsumerApiKeyResponse"},"type":"array","title":"Keys"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["keys","total"],"title":"ConsumerKeyListResponse","description":"Pair consumer key metadata with its total matching count."},"ConsumerListResponse":{"properties":{"consumers":{"items":{"$ref":"#/components/schemas/ConsumerResponse"},"type":"array","title":"Consumers"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["consumers","total"],"title":"ConsumerListResponse","description":"Pair consumer records with their total matching count."},"ConsumerResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"name":{"type":"string","title":"Name"},"metadata":{"anyOf":[{"$ref":"#/components/schemas/JsonObject-Output"},{"type":"null"}]},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","app_id","name","created_by","created_at"],"title":"ConsumerResponse","description":"Expose app consumer identity while serializing ORM metadata under its public name."},"CostBreakdownPeriod":{"properties":{"start":{"type":"string","format":"date-time","title":"Start"},"end":{"type":"string","format":"date-time","title":"End"},"label":{"type":"string","title":"Label"}},"type":"object","required":["start","end","label"],"title":"CostBreakdownPeriod","description":"Time period for a cost breakdown query."},"CostLine":{"properties":{"rate_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Key"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"quantity":{"type":"number","title":"Quantity"},"unit":{"type":"string","title":"Unit"},"display_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Unit"},"rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rate"},"display_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Display Rate"},"rate_card_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Card Version"},"effective_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Effective From"},"cost_usd":{"type":"number","title":"Cost Usd"},"resource_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Type"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},"type":"object","required":["rate_key","label","quantity","unit","display_unit","rate","display_rate","rate_card_version","effective_from","cost_usd"],"title":"CostLine","description":"Recorded quantity and price evidence; legacy rate metadata stays unknown."},"CpuAllocationMode":{"type":"string","enum":["request_based","always_allocated"],"title":"CpuAllocationMode","description":"Distinguish request-bound CPU from CPU allocated between requests."},"CreateAlertRuleRequest":{"properties":{"metric":{"$ref":"#/components/schemas/AlertMetric"},"operator":{"$ref":"#/components/schemas/AlertOperator"},"threshold":{"type":"number","title":"Threshold"},"window_minutes":{"type":"integer","maximum":1440.0,"minimum":1.0,"title":"Window Minutes","default":5},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"cooldown_minutes":{"type":"integer","maximum":1440.0,"minimum":1.0,"title":"Cooldown Minutes","default":15},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["metric","operator","threshold"],"title":"CreateAlertRuleRequest","description":"Request body for creating an alert rule."},"CreateApiKeyRequest":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"scope":{"anyOf":[{"$ref":"#/components/schemas/KeyScope"},{"type":"null"}]}},"type":"object","required":["name"],"title":"CreateApiKeyRequest","description":"Request body for creating an API key."},"CreateApiKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key":{"type":"string","title":"Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"key_suffix":{"type":"string","title":"Key Suffix"},"scope":{"$ref":"#/components/schemas/KeyScope"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","key","key_prefix","key_suffix","scope","created_at"],"title":"CreateApiKeyResponse","description":"Response after creating an API key. Includes the raw key (shown once)."},"CreateAppInviteRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"role":{"$ref":"#/components/schemas/AppMembershipRole","default":"member"}},"type":"object","required":["email"],"title":"CreateAppInviteRequest","description":"Invite one global floo identity to an app."},"CreateAppInviteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/AppMembershipRole"},"status":{"$ref":"#/components/schemas/AppInviteStatus"},"invited_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Invited By User Id"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"delivery_status":{"$ref":"#/components/schemas/AppInviteDeliveryStatus"},"delivery_attempted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivery Attempted At"},"delivery_provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Provider Id"},"delivery_failure_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Failure Class"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"invite_url":{"type":"string","title":"Invite Url"}},"type":"object","required":["id","app_id","email","role","status","invited_by_user_id","expires_at","accepted_at","revoked_at","delivery_status","delivery_attempted_at","delivery_provider_id","delivery_failure_class","created_at","invite_url"],"title":"CreateAppInviteResponse","description":"Create/resend result; the raw URL is returned exactly once."},"CreateAppRequest":{"properties":{"name":{"type":"string","maxLength":40,"minLength":2,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$","title":"Name"},"access_mode":{"type":"string","enum":["public","accounts"],"default":"public"}},"type":"object","required":["name"],"title":"CreateAppRequest","description":"Request body for creating an app."},"CreateConsumerRequest":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"metadata":{"anyOf":[{"$ref":"#/components/schemas/JsonObject-Input"},{"type":"null"}]}},"type":"object","required":["name"],"title":"CreateConsumerRequest","description":"Require a bounded consumer name and accept optional metadata."},"CreateDeployRequest":{"properties":{"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"},"framework":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Framework"},"services":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Services"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch"},"skip_migrations":{"type":"boolean","title":"Skip Migrations","default":false},"rebuild":{"type":"boolean","title":"Rebuild","default":false}},"type":"object","title":"CreateDeployRequest","description":"JSON request body for creating a deploy (replaces multipart tarball upload)."},"CreateDevSessionRequest":{"properties":{"services":{"items":{"$ref":"#/components/schemas/DevServiceInput"},"type":"array","title":"Services"}},"type":"object","required":["services"],"title":"CreateDevSessionRequest","description":"Supply the services that share a new development session."},"CreateDevSessionResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"services":{"additionalProperties":{"additionalProperties":{"type":"string"},"type":"object"},"type":"object","title":"Services"},"postgres_authorized":{"type":"boolean","title":"Postgres Authorized"},"withheld_secret_keys":{"items":{"type":"string"},"type":"array","title":"Withheld Secret Keys"}},"type":"object","required":["session_id","services","postgres_authorized"],"title":"CreateDevSessionResponse","description":"Return session credentials, the legacy authorization field, and withheld secret names."},"CreateEnvironmentRequest":{"properties":{"name":{"$ref":"#/components/schemas/EnvironmentName"}},"type":"object","required":["name"],"title":"CreateEnvironmentRequest","description":"Request body for creating an environment."},"CreateInviteRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"role":{"$ref":"#/components/schemas/OrgRole","default":"member"}},"type":"object","required":["email"],"title":"CreateInviteRequest","description":"Request body for creating an org invite."},"CreateInviteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/OrgRole"},"status":{"$ref":"#/components/schemas/InviteStatus"},"invited_by_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Invited By Id"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"invite_url":{"type":"string","title":"Invite Url"}},"type":"object","required":["id","org_id","email","role","status","invited_by_id","expires_at","created_at","invite_url"],"title":"CreateInviteResponse","description":"Response after creating an invite — includes the one-time invite URL."},"CreateManagedServiceRequest":{"properties":{"type":{"type":"string","enum":["postgres","redis","storage"],"title":"Type","description":"Service type: postgres, redis, or storage."},"name":{"type":"string","maxLength":63,"pattern":"^[a-z][a-z0-9_]*$","title":"Name","description":"Service name (lowercase, alphanumeric + underscores).","default":"default"},"tier":{"type":"string","enum":["basic","standard","performance"],"title":"Tier","description":"Service tier: basic, standard, or performance.","default":"basic"}},"type":"object","required":["type"],"title":"CreateManagedServiceRequest","description":"Request body for provisioning a managed service."},"CreatePreviewRequest":{"properties":{"branch":{"type":"string","minLength":1,"title":"Branch"},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"},"framework":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Framework"},"data":{"$ref":"#/components/schemas/PreviewDataRequest"}},"type":"object","required":["branch"],"title":"CreatePreviewRequest","description":"Create or redeploy a preview environment."},"CreateProjectRequest":{"properties":{"name":{"type":"string","maxLength":40,"minLength":2,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$","title":"Name"}},"type":"object","required":["name"],"title":"CreateProjectRequest","description":"Require a project name that satisfies the app naming contract."},"CreateServiceRequest":{"properties":{"name":{"type":"string","maxLength":63,"minLength":2,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$","title":"Name"},"type":{"$ref":"#/components/schemas/ServiceType"}},"type":"object","required":["name","type"],"title":"CreateServiceRequest","description":"Request body for creating a new service."},"CreateWebhookEndpointRequest":{"properties":{"channel":{"$ref":"#/components/schemas/WebhookChannelType"},"url":{"type":"string","maxLength":2048,"title":"Url"},"label":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Label"},"events":{"items":{"$ref":"#/components/schemas/WebhookEventType"},"type":"array","minItems":1,"title":"Events","default":["deploy.succeeded","deploy.failed"]}},"type":"object","required":["channel","url"],"title":"CreateWebhookEndpointRequest","description":"Request body for creating a webhook endpoint."},"CronJobListResponse":{"properties":{"cron_jobs":{"items":{"$ref":"#/components/schemas/CronJobResponse"},"type":"array","title":"Cron Jobs"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["cron_jobs","total"],"title":"CronJobListResponse","description":"Response for listing cron jobs."},"CronJobResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"env_id":{"type":"string","format":"uuid","title":"Env Id"},"name":{"type":"string","title":"Name"},"schedule":{"type":"string","title":"Schedule"},"command":{"type":"string","title":"Command"},"service_name":{"type":"string","title":"Service Name"},"timeout":{"type":"integer","title":"Timeout"},"enabled":{"type":"boolean","title":"Enabled"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"last_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","env_id","name","schedule","command","service_name","timeout","enabled","created_at","updated_at"],"title":"CronJobResponse","description":"Response for a single cron job."},"CronJobRunResponse":{"properties":{"name":{"type":"string","title":"Name"},"triggered":{"type":"boolean","title":"Triggered"},"message":{"type":"string","title":"Message"}},"type":"object","required":["name","triggered","message"],"title":"CronJobRunResponse","description":"Response for a manual cron job trigger."},"DashboardBootstrapResponse":{"properties":{"profile":{"$ref":"#/components/schemas/WhoamiResponse"},"org":{"anyOf":[{"$ref":"#/components/schemas/OrgResponse"},{"type":"null"}]},"apps":{"anyOf":[{"$ref":"#/components/schemas/AppListResponse"},{"type":"null"}]}},"type":"object","required":["profile"],"title":"DashboardBootstrapResponse","description":"Identity gate plus the bounded initial dashboard projection."},"DbQueryRequest":{"properties":{"sql":{"type":"string","title":"Sql"},"env":{"type":"string","title":"Env","default":"dev"},"limit":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Limit","default":1000}},"type":"object","required":["sql"],"title":"DbQueryRequest","description":"Accept SQL with a target environment and a bounded result limit."},"DbQueryResponse":{"properties":{"columns":{"items":{"type":"string"},"type":"array","title":"Columns"},"column_types":{"items":{"type":"string"},"type":"array","title":"Column Types"},"rows":{"items":{"items":{},"type":"array"},"type":"array","title":"Rows"},"row_count":{"type":"integer","title":"Row Count"},"duration_ms":{"type":"number","title":"Duration Ms"},"truncated":{"type":"boolean","title":"Truncated"}},"type":"object","required":["columns","column_types","rows","row_count","duration_ms","truncated"],"title":"DbQueryResponse","description":"Pair query rows with aligned column types, timing, and truncation metadata."},"DbSchemaResponse":{"properties":{"schema_name":{"type":"string","title":"Schema Name"},"tables":{"items":{"$ref":"#/components/schemas/TableInfo"},"type":"array","title":"Tables"},"schema_size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Schema Size Bytes"},"schema_size_human":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Size Human"}},"type":"object","required":["schema_name","tables"],"title":"DbSchemaResponse","description":"Expose the app-owned Postgres schema, tables, and optional size measurements."},"DeclaredManagedService":{"properties":{"type":{"$ref":"#/components/schemas/ManagedServiceType"},"name":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,62}$","title":"Name","default":"default"},"tier":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Tier"}},"additionalProperties":false,"type":"object","required":["type"],"title":"DeclaredManagedService","description":"Managed service as declared by the caller.\n\nSourced from either the legacy floo.app.toml sections (during the deprecation\nwindow) or from explicit managed-service add/migrate records (the canonical\nsurface going forward)."},"DeclaredRuntimeService":{"properties":{"name":{"type":"string","maxLength":63,"minLength":1,"title":"Name"},"type":{"type":"string","enum":["web","api","worker"],"title":"Type"},"cpu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpu"},"memory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory"},"min_instances":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Min Instances"},"max_instances":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Max Instances"},"instances":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Instances"},"env_managed":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Env Managed"}},"additionalProperties":false,"type":"object","required":["name","type"],"title":"DeclaredRuntimeService","description":"Runtime intent needed for authoritative server-side preflight resolution."},"DeclaredState":{"properties":{"managed_services":{"items":{"$ref":"#/components/schemas/DeclaredManagedService"},"type":"array","title":"Managed Services"},"env":{"$ref":"#/components/schemas/EnvironmentName","default":"dev"},"services":{"items":{"$ref":"#/components/schemas/DeclaredRuntimeService"},"type":"array","title":"Services"}},"additionalProperties":false,"type":"object","title":"DeclaredState","description":"Payload the CLI sends to POST /v1/apps/{app_id}/preflight.\n\nStrict field validation: a misspelled field from a CLI/API version skew\nmust fail loud (422) rather than silently route the user into a bad plan."},"DeployDiagnosticResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"step_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Step Name"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"code":{"type":"string","title":"Code"},"severity":{"type":"string","title":"Severity"},"source":{"type":"string","title":"Source"},"title":{"type":"string","title":"Title"},"message":{"type":"string","title":"Message"},"fix":{"type":"string","title":"Fix"},"knowledge_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Knowledge Ref"},"evidence_json":{"anyOf":[{"$ref":"#/components/schemas/JsonObject-Output"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","code","severity","source","title","message","fix","created_at"],"title":"DeployDiagnosticResponse","description":"Response for one structured deploy diagnostic."},"DeployListResponse":{"properties":{"deploys":{"items":{"$ref":"#/components/schemas/DeployResponse"},"type":"array","title":"Deploys"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"},"limit":{"type":"integer","title":"Limit"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More","default":false}},"type":"object","required":["deploys","total","page","per_page","limit"],"title":"DeployListResponse","description":"Paginated response for listing deploys."},"DeployResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"status":{"type":"string","title":"Status"},"framework":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Framework"},"source_deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Source Deploy Id"},"build_logs":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Logs"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"cloud_run_service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Run Service Name"},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha"},"coalesced_commits":{"items":{"$ref":"#/components/schemas/CoalescedCommitResponse"},"type":"array","title":"Coalesced Commits"},"github_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Github Ref"},"triggered_by":{"type":"string","title":"Triggered By"},"env_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Env Id"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"target_env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Env"},"target_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Branch"},"preview_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview Slug"},"source_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Branch"},"source_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Hash"},"build_args_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Args Hash"},"skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Reason"},"skip_migrations":{"type":"boolean","title":"Skip Migrations","default":false},"failure_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Category"},"failure_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Message"},"failure_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Step"},"failure_root_cause":{"anyOf":[{"$ref":"#/components/schemas/FailureRootCauseResponse"},{"type":"null"}]},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"failure_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Stage"},"failing_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failing Stage"},"root_cause_event_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Cause Event Excerpt"},"migrations":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Migrations"},"steps":{"items":{"$ref":"#/components/schemas/DeployStepResponse"},"type":"array","title":"Steps","default":[]},"diagnostics":{"items":{"$ref":"#/components/schemas/DeployDiagnosticResponse"},"type":"array","title":"Diagnostics","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"requested_app_access_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested App Access Mode"},"requested_env_access_modes":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Requested Env Access Modes"}},"type":"object","required":["id","app_id","status","framework","source_deploy_id","build_logs","url","triggered_by","created_at","updated_at"],"title":"DeployResponse","description":"Response for a single deploy."},"DeployStepDetailResponse":{"properties":{"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"order":{"type":"integer","title":"Order"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"error_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Category"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Reason"},"logs":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logs"}},"type":"object","required":["name","status","order"],"title":"DeployStepDetailResponse","description":"Step response with full logs — used for per-step detail endpoint."},"DeployStepResponse":{"properties":{"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"order":{"type":"integer","title":"Order"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"error_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Category"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Reason"}},"type":"object","required":["name","status","order"],"title":"DeployStepResponse","description":"Response for a single deploy pipeline step."},"DevServiceInput":{"properties":{"name":{"type":"string","title":"Name"},"port":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port"},"managed":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Managed"}},"type":"object","required":["name"],"title":"DevServiceInput","description":"Describe a local service with an optional listening port and managed attachments."},"DeviceAuthResponse":{"properties":{"device_code":{"type":"string","title":"Device Code"},"user_code":{"type":"string","title":"User Code"},"verification_uri":{"type":"string","title":"Verification Uri"},"verification_uri_complete":{"type":"string","title":"Verification Uri Complete"},"expires_in":{"type":"integer","title":"Expires In"},"interval":{"type":"integer","title":"Interval"}},"type":"object","required":["device_code","user_code","verification_uri","verification_uri_complete","expires_in","interval"],"title":"DeviceAuthResponse","description":"Response from initiating device code flow."},"DeviceTokenPendingResponse":{"properties":{"status":{"type":"string","enum":["pending","slow_down"],"title":"Status"}},"type":"object","required":["status"],"title":"DeviceTokenPendingResponse","description":"202 body while the user has not yet approved the device code; poll again."},"DeviceTokenRequest":{"properties":{"device_code":{"type":"string","title":"Device Code"}},"type":"object","required":["device_code"],"title":"DeviceTokenRequest","description":"Request body for polling device token."},"DnsRecord":{"properties":{"type":{"type":"string","enum":["CNAME","A"],"title":"Type"},"name":{"type":"string","title":"Name"},"value":{"type":"string","title":"Value"},"purpose":{"type":"string","enum":["traffic","traffic_apex","certificate"],"title":"Purpose","description":"`traffic_apex` records replace the `traffic` CNAME only at a zone apex, where a CNAME is not allowed."}},"type":"object","required":["type","name","value","purpose"],"title":"DnsRecord","description":"DNS record a domain owner should publish."},"DomainBlocker":{"type":"string","enum":["AWAITING_DNS","CERT_ISSUING","CERT_FAILED","HOSTNAME_HELD_BY_ANOTHER_APP","NOT_ROUTABLE","PROVIDER_ERROR"],"title":"DomainBlocker","description":"Actionable reason a declared domain is not active."},"DomainListResponse":{"properties":{"domains":{"items":{"$ref":"#/components/schemas/DomainResponse"},"type":"array","title":"Domains"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["domains","total"],"title":"DomainListResponse","description":"Response for listing domains."},"DomainResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"hostname":{"type":"string","title":"Hostname"},"status":{"type":"string","title":"Status"},"status_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Reason"},"blocker":{"anyOf":[{"$ref":"#/components/schemas/DomainBlocker"},{"type":"null"}]},"ssl_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ssl Status"},"verified":{"type":"boolean","title":"Verified","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"dns_records":{"items":{"$ref":"#/components/schemas/DnsRecord"},"type":"array","title":"Dns Records"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"env_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Env Id"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},"type":"object","required":["id","app_id","hostname","status","created_at","updated_at","dns_records"],"title":"DomainResponse","description":"Response for a single domain."},"EdgePolicyAction":{"type":"string","enum":["allow","deny"],"title":"EdgePolicyAction","description":"Restrict edge policy decisions to allowing or denying traffic."},"EdgePolicyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"env":{"type":"string","title":"Env"},"rules":{"items":{"$ref":"#/components/schemas/EdgePolicyRule"},"type":"array","title":"Rules"},"default_action":{"$ref":"#/components/schemas/EdgePolicyAction"},"enabled":{"type":"boolean","title":"Enabled"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","env","rules","default_action","enabled","created_at","updated_at"],"title":"EdgePolicyResponse","description":"Expose an environment's ordered edge rules, default decision, and enabled state."},"EdgePolicyRule":{"properties":{"action":{"$ref":"#/components/schemas/EdgePolicyAction"},"cidr":{"type":"string","title":"Cidr"}},"type":"object","required":["action","cidr"],"title":"EdgePolicyRule","description":"Pair an edge decision with a validated, normalized IP network."},"EdgeRouteItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"host":{"type":"string","title":"Host"},"path_prefix":{"type":"string","title":"Path Prefix"},"env_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Env Id"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"env_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env Slug"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"service_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Type"},"access_mode":{"type":"string","title":"Access Mode"},"api_key_enabled":{"type":"boolean","title":"Api Key Enabled"},"required_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Required Scope"},"source":{"type":"string","enum":["deploy","custom_domain","toml","system"],"title":"Source"},"source_of_truth":{"type":"string","title":"Source Of Truth"},"propagation_status":{"type":"string","const":"unknown","title":"Propagation Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","host","path_prefix","env_id","env","env_slug","service_id","service_name","service_type","access_mode","api_key_enabled","required_scope","source","source_of_truth","propagation_status","created_at","updated_at"],"title":"EdgeRouteItem","description":"One customer-safe projection of a gateway route.\n\nDeliberately omits ``gateway_routes.backend_url``. Raw Cloud Run URLs are\nimplementation details and must stay out of customer-facing output."},"EdgeRouteListResponse":{"properties":{"routes":{"items":{"$ref":"#/components/schemas/EdgeRouteItem"},"type":"array","title":"Routes"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["routes","total"],"title":"EdgeRouteListResponse","description":"App-scoped edge route table response."},"EnvVarListResponse":{"properties":{"env_vars":{"items":{"$ref":"#/components/schemas/EnvVarResponse"},"type":"array","title":"Env Vars"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["env_vars","total"],"title":"EnvVarListResponse","description":"Response for listing environment variables."},"EnvVarPlaintextResponse":{"properties":{"key":{"type":"string","title":"Key"},"value":{"type":"string","title":"Value"}},"type":"object","required":["key","value"],"title":"EnvVarPlaintextResponse","description":"Response for getting a single env var's plaintext value."},"EnvVarResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"env_id":{"type":"string","format":"uuid","title":"Env Id"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"key":{"type":"string","title":"Key"},"masked_value":{"type":"string","title":"Masked Value"},"is_secret":{"type":"boolean","title":"Is Secret"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","env_id","service_id","key","masked_value","is_secret","created_at","updated_at"],"title":"EnvVarResponse","description":"Response for a single environment variable."},"EnvironmentListResponse":{"properties":{"envs":{"items":{"$ref":"#/components/schemas/EnvironmentResponse"},"type":"array","title":"Envs"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["envs","total"],"title":"EnvironmentListResponse","description":"Response for listing environments."},"EnvironmentName":{"type":"string","enum":["dev","prod","preview"],"title":"EnvironmentName","description":"Enumerate the persisted development, production, and preview environment names."},"EnvironmentResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"access_mode":{"type":"string","title":"Access Mode"},"access_policy":{"$ref":"#/components/schemas/AccessPolicy"},"source_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Branch"},"pr_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pr Number"},"ttl_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttl Hours"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","app_id","name","slug","url","access_mode","access_policy","created_at"],"title":"EnvironmentResponse","description":"Response for a single environment."},"EnvironmentSummary":{"properties":{"name":{"type":"string","title":"Name"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"access_mode":{"$ref":"#/components/schemas/AccessMode"},"access_policy":{"$ref":"#/components/schemas/AccessPolicy"}},"type":"object","required":["name","url","access_mode","access_policy"],"title":"EnvironmentSummary","description":"Lightweight environment info embedded in AppResponse."},"ErrorDetail":{"properties":{"code":{"type":"string","title":"Code"},"message":{"type":"string","title":"Message"}},"additionalProperties":true,"type":"object","required":["code","message"],"title":"ErrorDetail","description":"Standard error envelope with operation-specific JSON context."},"ErrorGroup":{"properties":{"fingerprint":{"type":"string","title":"Fingerprint"},"count":{"type":"integer","title":"Count"},"first_seen":{"type":"string","title":"First Seen"},"last_seen":{"type":"string","title":"Last Seen"},"severity":{"type":"string","title":"Severity"},"sample_message":{"type":"string","title":"Sample Message"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"}},"type":"object","required":["fingerprint","count","first_seen","last_seen","severity","sample_message"],"title":"ErrorGroup","description":"A group of errors sharing the same fingerprint."},"ErrorGroupsResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/ErrorGroup"},"type":"array","title":"Errors"},"total":{"type":"integer","title":"Total"},"app_name":{"type":"string","title":"App Name"}},"type":"object","required":["errors","total","app_name"],"title":"ErrorGroupsResponse","description":"Response for the error groups endpoint."},"ErrorResponse":{"properties":{"detail":{"$ref":"#/components/schemas/ErrorDetail"}},"type":"object","required":["detail"],"title":"ErrorResponse","description":"Body of every error response except request validation (422)."},"FailureRootCauseResponse":{"properties":{"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"details":{"$ref":"#/components/schemas/JsonObject-Output"},"first_failure_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Failure At"},"root_cause_event_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Cause Event Excerpt"}},"type":"object","title":"FailureRootCauseResponse","description":"Normalized deploy failure summary for operator-facing surfaces."},"FeedbackCategory":{"type":"string","enum":["feature_request","friction","bug","general"],"title":"FeedbackCategory","description":"Type of feedback."},"FeedbackResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"category":{"$ref":"#/components/schemas/FeedbackCategory"},"source":{"$ref":"#/components/schemas/FeedbackSource"},"message":{"type":"string","title":"Message"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"app_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Name"},"user_email":{"type":"string","title":"User Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","category","source","message","context","app_name","user_email","created_at"],"title":"FeedbackResponse","description":"Response for a single feedback entry."},"FeedbackSource":{"type":"string","enum":["cli","dashboard","agent"],"title":"FeedbackSource","description":"Where the feedback came from."},"GitHubConnectRequest":{"properties":{"repo_full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Full Name"},"default_branch":{"type":"string","title":"Default Branch","default":"main"},"skip_env_var_check":{"type":"boolean","title":"Skip Env Var Check","default":false}},"type":"object","title":"GitHubConnectRequest","description":"Request to connect an app to a GitHub repository."},"GitHubConnectionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"connected":{"type":"boolean","title":"Connected"},"skip_env_var_check":{"type":"boolean","title":"Skip Env Var Check"},"preview_enabled":{"type":"boolean","title":"Preview Enabled"},"preview_ttl_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Preview Ttl Hours"},"repo_full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Full Name"},"default_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Branch"},"installation_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Installation Id"},"disconnected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Disconnected At"},"disconnected_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disconnected Reason"},"connected_at":{"type":"string","format":"date-time","title":"Connected At"},"services":{"items":{"$ref":"#/components/schemas/ServiceGitHubInfo"},"type":"array","title":"Services","default":[]}},"type":"object","required":["id","app_id","connected","skip_env_var_check","preview_enabled","connected_at"],"title":"GitHubConnectionResponse","description":"Response for a GitHub connection."},"GitHubInstallationCandidate":{"properties":{"installation_id":{"type":"integer","title":"Installation Id"},"owner_login":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Login"}},"type":"object","required":["installation_id"],"title":"GitHubInstallationCandidate","description":"One installation the authorizing GitHub user proved they can reach."},"GitHubInstallationResponse":{"properties":{"installation_id":{"type":"integer","title":"Installation Id"},"owner_login":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Login"},"bound_at":{"type":"string","format":"date-time","title":"Bound At"}},"type":"object","required":["installation_id","owner_login","bound_at"],"title":"GitHubInstallationResponse","description":"An active org binding recorded by floo, not live GitHub reachability."},"GitHubInstallationsResponse":{"properties":{"installations":{"items":{"$ref":"#/components/schemas/GitHubInstallationResponse"},"type":"array","title":"Installations"}},"type":"object","required":["installations"],"title":"GitHubInstallationsResponse","description":"Wrap GitHub installation records visible to the caller."},"GitHubRepoAccessReason":{"type":"string","enum":["ok","app_not_installed","repo_not_in_installation","repo_not_accessible"],"title":"GitHubRepoAccessReason","description":"Why floo can or cannot reach a repository, as one distinguishable cause.\n\n`accessible: false` on its own is what made first-time setup opaque: the\nthree causes below need three different actions, and collapsing them left\nthe operator re-running an install that had already succeeded (#2293)."},"GitHubRepoAccessResponse":{"properties":{"accessible":{"type":"boolean","title":"Accessible"},"default_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Branch"},"reason":{"$ref":"#/components/schemas/GitHubRepoAccessReason"},"install_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Install Url"},"settings_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Settings Url"},"installation_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Installation Id"}},"type":"object","required":["accessible","reason"],"title":"GitHubRepoAccessResponse","description":"Response from GET /v1/github/check-repo-access."},"GitHubRepoInfo":{"properties":{"full_name":{"type":"string","title":"Full Name"},"default_branch":{"type":"string","title":"Default Branch"},"private":{"type":"boolean","title":"Private"}},"type":"object","required":["full_name","default_branch","private"],"title":"GitHubRepoInfo","description":"A single repository accessible to a GitHub App installation."},"GitHubReposResponse":{"properties":{"repositories":{"items":{"$ref":"#/components/schemas/GitHubRepoInfo"},"type":"array","title":"Repositories"}},"type":"object","required":["repositories"],"title":"GitHubReposResponse","description":"Response from GET /v1/github/installations/{installation_id}/repos."},"GitHubSetupBeginResponse":{"properties":{"install_url":{"type":"string","title":"Install Url"}},"type":"object","required":["install_url"],"title":"GitHubSetupBeginResponse","description":"Response from POST /v1/github/setup/begin."},"GitHubSetupPollResponse":{"properties":{"status":{"$ref":"#/components/schemas/GitHubSetupStatus"},"installation_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Installation Id"},"candidates":{"items":{"$ref":"#/components/schemas/GitHubInstallationCandidate"},"type":"array","title":"Candidates","default":[]}},"type":"object","required":["status"],"title":"GitHubSetupPollResponse","description":"Response from GET /v1/github/setup/poll."},"GitHubSetupSelectRequest":{"properties":{"installation_id":{"type":"integer","title":"Installation Id"}},"type":"object","required":["installation_id"],"title":"GitHubSetupSelectRequest","description":"Request body for POST /v1/github/setup/select."},"GitHubSetupSelectResponse":{"properties":{"status":{"$ref":"#/components/schemas/GitHubSetupStatus"},"installation_id":{"type":"integer","title":"Installation Id"}},"type":"object","required":["status","installation_id"],"title":"GitHubSetupSelectResponse","description":"Response from POST /v1/github/setup/select."},"GitHubSetupStatus":{"type":"string","enum":["none","awaiting_installation","awaiting_org_approval","awaiting_selection","ready"],"title":"GitHubSetupStatus","description":"Setup-session states for GitHub App installation."},"GitTokenResponse":{"properties":{"token":{"type":"string","title":"Token"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"clone_url":{"type":"string","title":"Clone Url"}},"type":"object","required":["token","expires_at","clone_url"],"title":"GitTokenResponse","description":"Show-once, repository-scoped GitHub installation credential."},"HealthCheckResponse":{"properties":{"health_status":{"$ref":"#/components/schemas/HealthStatus"},"last_health_check_at":{"type":"string","format":"date-time","title":"Last Health Check At"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"checks":{"items":{"$ref":"#/components/schemas/HealthSubCheck"},"type":"array","title":"Checks","default":[]}},"type":"object","required":["health_status","last_health_check_at","url"],"title":"HealthCheckResponse","description":"Response for an on-demand health check.\n\n`health_status` is the composite rollup (worst-of all sub-checks) and\nstays compatible with pre-P2 clients that only read that field. The\n`checks` list gives deeper breakdown: HTTP probe, any managed-service\n(DB / Redis) state, and recent load (request rate / error rate / p95\nlatency). New clients should render the sub-checks; old clients\ncontinue to work on the rollup field alone."},"HealthCheckStatus":{"type":"string","enum":["ok","degraded","failed","unknown"],"title":"HealthCheckStatus","description":"Outcome of an individual health sub-check."},"HealthStatus":{"type":"string","enum":["healthy","unhealthy","unknown"],"title":"HealthStatus","description":"Health check status of an app."},"HealthSubCheck":{"properties":{"name":{"type":"string","title":"Name"},"status":{"$ref":"#/components/schemas/HealthCheckStatus"},"message":{"type":"string","title":"Message"},"metadata":{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"integer"},{"type":"string"},{"type":"null"}]},"type":"object","title":"Metadata","default":{}}},"type":"object","required":["name","status","message"],"title":"HealthSubCheck","description":"Result of a single sub-check inside a composite health probe.\n\nThe `name` is a stable identifier (e.g. 'http', 'postgres:main',\n'load:errors') that clients can key off. The `message` is a\nhuman-readable one-liner. `metadata` holds structured context — e.g.\nthe HTTP status code, request count, error count — so agents can\nprogrammatically understand what degraded means without parsing the\nmessage string."},"ImportEnvVarsRequest":{"properties":{"env_vars":{"items":{"$ref":"#/components/schemas/SetEnvVarRequest"},"type":"array","maxItems":100,"minItems":1,"title":"Env Vars"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"}},"type":"object","required":["env_vars"],"title":"ImportEnvVarsRequest","description":"Request body for bulk-importing environment variables."},"ImportEnvVarsResponse":{"properties":{"env_vars":{"items":{"$ref":"#/components/schemas/EnvVarResponse"},"type":"array","title":"Env Vars"},"created":{"type":"integer","title":"Created"},"updated":{"type":"integer","title":"Updated"},"skipped":{"items":{"type":"string"},"type":"array","title":"Skipped"}},"type":"object","required":["env_vars","created","updated"],"title":"ImportEnvVarsResponse","description":"Response for bulk-importing environment variables."},"IngestResponse":{"properties":{"accepted":{"type":"integer","title":"Accepted"}},"type":"object","required":["accepted"],"title":"IngestResponse","description":"Acknowledgement for a successful ingest."},"IngestTokenResponse":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"IngestTokenResponse","description":"Short-lived signed proof the browser loaded from an allowed app host."},"IngressMode":{"type":"string","enum":["public","internal"],"title":"IngressMode","description":"Whether the service accepts public traffic."},"InviteListResponse":{"properties":{"invites":{"items":{"$ref":"#/components/schemas/InviteResponse"},"type":"array","title":"Invites"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["invites","total"],"title":"InviteListResponse","description":"Response listing pending invites for an org."},"InvitePreviewResponse":{"properties":{"org_name":{"type":"string","title":"Org Name"},"role":{"$ref":"#/components/schemas/OrgRole"},"email":{"type":"string","title":"Email"},"status":{"$ref":"#/components/schemas/InviteStatus"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["org_name","role","email","status","expires_at"],"title":"InvitePreviewResponse","description":"Public preview of an invite — shown before accepting."},"InviteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/OrgRole"},"status":{"$ref":"#/components/schemas/InviteStatus"},"invited_by_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Invited By Id"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","org_id","email","role","status","invited_by_id","expires_at","created_at"],"title":"InviteResponse","description":"Response for a single org invite."},"InviteStatus":{"type":"string","enum":["pending","accepted","revoked"],"title":"InviteStatus","description":"Lifecycle status of an org invite."},"JsonObject-Input":{"additionalProperties":{"$ref":"#/components/schemas/JsonValue-Input"},"type":"object"},"JsonObject-Output":{"additionalProperties":{"$ref":"#/components/schemas/JsonValue-Output"},"type":"object"},"JsonValue-Input":{"anyOf":[{"type":"boolean"},{"type":"integer"},{"type":"number"},{"type":"string"},{"items":{"$ref":"#/components/schemas/JsonValue-Input"},"type":"array"},{"additionalProperties":{"$ref":"#/components/schemas/JsonValue-Input"},"type":"object"},{"type":"null"}]},"JsonValue-Output":{"anyOf":[{"type":"boolean"},{"type":"integer"},{"type":"number"},{"type":"string"},{"items":{"$ref":"#/components/schemas/JsonValue-Output"},"type":"array"},{"additionalProperties":{"$ref":"#/components/schemas/JsonValue-Output"},"type":"object"},{"type":"null"}]},"KeyScope":{"type":"string","enum":["read","write","admin"],"title":"KeyScope","description":"Permission scope for an API key.\n\nPrivilege hierarchy: read < write < admin (enforced via scope_level(),\nnot native comparison — StrEnum compares lexicographically)."},"LogEntry":{"properties":{"timestamp":{"type":"string","title":"Timestamp"},"severity":{"type":"string","title":"Severity"},"message":{"type":"string","title":"Message"},"deployment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deployment Id"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"labels":{"anyOf":[{"$ref":"#/components/schemas/JsonObject-Output"},{"type":"null"}]},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"cron_job_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cron Job Name"},"deploy_context":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Deploy Context"},"severity_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity Class"},"lifecycle_noise":{"type":"boolean","title":"Lifecycle Noise","default":false}},"type":"object","required":["timestamp","severity","message"],"title":"LogEntry","description":"A single log entry from Cloud Logging."},"LogsResponse":{"properties":{"logs":{"items":{"$ref":"#/components/schemas/LogEntry"},"type":"array","title":"Logs"},"total":{"type":"integer","title":"Total"},"app_name":{"type":"string","title":"App Name"},"limit":{"type":"integer","title":"Limit"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More","default":false}},"type":"object","required":["logs","total","app_name","limit"],"title":"LogsResponse","description":"Response for the logs endpoint."},"ManagedResourceCostBreakdown":{"properties":{"managed_service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Managed Service Id"},"env_managed_resource_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Env Managed Resource Id"},"name":{"type":"string","title":"Name"},"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"costs":{"additionalProperties":{"$ref":"#/components/schemas/ResourceCost"},"type":"object","title":"Costs"},"lines":{"items":{"$ref":"#/components/schemas/CostLine"},"type":"array","title":"Lines"},"total_usd":{"type":"number","title":"Total Usd"}},"type":"object","required":["managed_service_id","env_managed_resource_id","name","env","costs","total_usd"],"title":"ManagedResourceCostBreakdown","description":"Per-managed-resource cost breakdown."},"ManagedServiceDetailResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"type":{"type":"string","enum":["postgres","redis","storage"],"title":"Type"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"env_var_keys":{"items":{"type":"string"},"type":"array","title":"Env Var Keys"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"dev_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Dev Deprovision After"},"prod_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Prod Deprovision After"},"credentials":{"additionalProperties":{"type":"string"},"type":"object","title":"Credentials"}},"type":"object","required":["id","app_id","type","name","status","env_var_keys","created_at","updated_at","credentials"],"title":"ManagedServiceDetailResponse","description":"Response for a managed service with credentials."},"ManagedServiceDoctorIssue":{"properties":{"resource_id":{"type":"string","format":"uuid","title":"Resource Id"},"resource_kind":{"type":"string","enum":["managed_service","preview_resource"],"title":"Resource Kind"},"type":{"$ref":"#/components/schemas/ManagedServiceType"},"name":{"type":"string","title":"Name"},"env":{"type":"string","title":"Env"},"status":{"type":"string","const":"failed","title":"Status"},"reason":{"type":"string","title":"Reason"},"remediation":{"type":"string","title":"Remediation"}},"type":"object","required":["resource_id","resource_kind","type","name","env","status","reason","remediation"],"title":"ManagedServiceDoctorIssue","description":"A managed resource whose provision or teardown failed."},"ManagedServiceListResponse":{"properties":{"managed_services":{"items":{"$ref":"#/components/schemas/ManagedServiceResponse"},"type":"array","title":"Managed Services"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["managed_services","total"],"title":"ManagedServiceListResponse","description":"Response for listing managed services."},"ManagedServicePlanItem":{"properties":{"type":{"$ref":"#/components/schemas/ManagedServiceType"},"name":{"type":"string","maxLength":63,"title":"Name"},"tier":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Tier"},"managed_service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Managed Service Id"},"risk":{"$ref":"#/components/schemas/OpRisk","description":"Machine-readable risk of the action this plan item represents."},"data_impact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Impact","description":"Human-readable description of what would be destroyed if this item were deprovisioned. Populated for to_orphan items only."}},"additionalProperties":false,"type":"object","required":["type","name","risk"],"title":"ManagedServicePlanItem","description":"One managed-service row in a preflight plan."},"ManagedServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"type":{"type":"string","enum":["postgres","redis","storage"],"title":"Type"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"env_var_keys":{"items":{"type":"string"},"type":"array","title":"Env Var Keys"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"dev_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Dev Deprovision After"},"prod_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Prod Deprovision After"}},"type":"object","required":["id","app_id","type","name","status","env_var_keys","created_at","updated_at"],"title":"ManagedServiceResponse","description":"Response for a managed service."},"ManagedServiceType":{"type":"string","enum":["postgres","redis","storage"],"title":"ManagedServiceType","description":"Type of managed infrastructure service."},"ManagedServicesDoctorResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"app_name":{"type":"string","title":"App Name"},"checked_resources":{"type":"integer","title":"Checked Resources"},"checked_envs":{"type":"integer","title":"Checked Envs","default":0},"degraded_detected":{"type":"boolean","title":"Degraded Detected"},"issues":{"items":{"$ref":"#/components/schemas/ManagedServiceDoctorIssue"},"type":"array","title":"Issues"}},"type":"object","required":["app_id","app_name","checked_resources","degraded_detected","issues"],"title":"ManagedServicesDoctorResponse","description":"Canonical and preview managed resources checked for failed lifecycle operations."},"ManagedServicesPlan":{"properties":{"to_provision":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"To Provision"},"to_retry":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"To Retry"},"to_retain":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"To Retain"},"to_orphan":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"To Orphan"},"to_deprovision":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"To Deprovision"},"in_flight_deprovisioning":{"items":{"$ref":"#/components/schemas/ManagedServicePlanItem"},"type":"array","title":"In Flight Deprovisioning"}},"additionalProperties":false,"type":"object","title":"ManagedServicesPlan","description":"Reconciliation plan for managed services (postgres, redis, storage).\n\nManaged services are stateful and CLI-canonical. Deploy creates to_provision,\nretries to_retry (FAILED rows that the user has redeclared), retains\nto_retain, and NEVER acts on to_orphan — orphans require explicit\nremoval. Rows currently being deprovisioned surface in\nin_flight_deprovisioning so they remain visible to operators instead of\nsilently disappearing from the plan."},"MemberListResponse":{"properties":{"members":{"items":{"$ref":"#/components/schemas/MemberResponse"},"type":"array","title":"Members"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["members","total"],"title":"MemberListResponse","description":"Response listing members of an org."},"MemberResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/OrgRole"},"joined_at":{"type":"string","format":"date-time","title":"Joined At"}},"type":"object","required":["user_id","email","role","joined_at"],"title":"MemberResponse","description":"Response for a single org member."},"MintConsumerKeyRequest":{"properties":{"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"},"rate_limit_rpm":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Rpm"}},"type":"object","required":["name"],"title":"MintConsumerKeyRequest","description":"Require a key name with optional scopes and a bounded per-minute rate limit."},"MintedAppConsumerApiKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"consumer_id":{"type":"string","format":"uuid","title":"Consumer Id"},"prefix":{"type":"string","title":"Prefix"},"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"rate_limit_rpm":{"type":"integer","title":"Rate Limit Rpm"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"raw_key":{"type":"string","title":"Raw Key"}},"type":"object","required":["id","app_id","consumer_id","prefix","name","scopes","rate_limit_rpm","last_used_at","created_at","raw_key"],"title":"MintedAppConsumerApiKeyResponse","description":"Include the raw bearer secret in the response to key creation."},"NotificationCategory":{"type":"string","enum":["deploy_success","deploy_failure","domains","managed_services","billing"],"title":"NotificationCategory","description":"A user-muteable class of transactional email.\n\nMembership in this enum *is* the muteable contract: an email type mapped to\none of these consults the recipient's preference before sending; any email\ntype not mapped here is always-send (transactional / security / destructive)\nand can never be muted. The muteable set is pinned by\ntests/test_notification_preferences.py so a security or destructive email can\nnever be made silenceable by accident."},"NotificationPreference":{"properties":{"category":{"$ref":"#/components/schemas/NotificationCategory"},"label":{"type":"string","title":"Label"},"description":{"type":"string","title":"Description"},"enabled":{"type":"boolean","title":"Enabled"},"is_default":{"type":"boolean","title":"Is Default"}},"type":"object","required":["category","label","description","enabled","is_default"],"title":"NotificationPreference","description":"One category's effective state for the authenticated user."},"NotificationPreferencesResponse":{"properties":{"preferences":{"items":{"$ref":"#/components/schemas/NotificationPreference"},"type":"array","title":"Preferences"}},"type":"object","required":["preferences"],"title":"NotificationPreferencesResponse","description":"Wrap the caller's notification preferences by category."},"OpRisk":{"properties":{"tier":{"$ref":"#/components/schemas/RiskTier"},"destructive":{"type":"boolean","title":"Destructive","description":"Report whether the risk tier is at least recoverably destructive.","readOnly":true},"data_loss":{"type":"boolean","title":"Data Loss","description":"Report whether the risk tier reaches the data-loss threshold.","readOnly":true}},"type":"object","required":["tier","destructive","data_loss"],"title":"OpRisk","description":"Machine-readable risk of one plan operation.\n\nOnly ``tier`` is stored; ``destructive`` and ``data_loss`` are computed from\nit, so the three can never drift. The computed fields still serialize, so\nconsumers — the guardrail policy and the approval gates — read one source of\ntruth on the wire.\n\n``extra=\"ignore\"`` (not \"forbid\"): the emitted JSON carries the computed\ndestructive/data_loss keys, so the model must accept its own output on input\n— those keys are ignored and recomputed from ``tier``, never stored, so an\ninconsistent risk still cannot survive a round-trip."},"OrgAnalyticsResponse":{"properties":{"org_id":{"type":"string","format":"uuid","title":"Org Id"},"period":{"type":"string","title":"Period"},"summary":{"$ref":"#/components/schemas/OrgAnalyticsSummary"},"apps":{"items":{"$ref":"#/components/schemas/AppComparisonEntry"},"type":"array","title":"Apps"},"time_series":{"items":{"$ref":"#/components/schemas/TimeSeriesPoint"},"type":"array","title":"Time Series"}},"type":"object","required":["org_id","period","summary","apps","time_series"],"title":"OrgAnalyticsResponse","description":"Response for org-level analytics."},"OrgAnalyticsSummary":{"properties":{"total_requests":{"type":"integer","title":"Total Requests"},"total_errors":{"type":"integer","title":"Total Errors"},"error_rate":{"type":"number","title":"Error Rate"},"total_apps_with_traffic":{"type":"integer","title":"Total Apps With Traffic"},"avg_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Latency Ms"},"p95_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"P95 Latency Ms"},"authenticated_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Authenticated Requests"},"unauthenticated_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unauthenticated Requests"},"gateway_handled_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gateway Handled Requests"},"status_code_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Code Breakdown"},"rejection_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Rejection Breakdown","default":{}}},"type":"object","required":["total_requests","total_errors","error_rate","total_apps_with_traffic","avg_latency_ms","p95_latency_ms","authenticated_requests","unauthenticated_requests","gateway_handled_requests","status_code_breakdown"],"title":"OrgAnalyticsSummary","description":"Summary statistics across all apps in an org.\n\nMirrors the latency / status-code surface of `AppAnalyticsSummary` so an\nagent processing analytics output does not have to null-check differently\ndepending on scope. Tier-gated fields (`avg_latency_ms`, `p95_latency_ms`)\nstay `None` when analytics is restricted where per-app analytics also returns `None`,\nkeeping the gating contract identical at both scopes."},"OrgAppMemberListResponse":{"properties":{"users":{"items":{"$ref":"#/components/schemas/OrgAppMemberResponse"},"type":"array","title":"Users"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["users","total"],"title":"OrgAppMemberListResponse","description":"Organization-wide active app membership summary."},"OrgAppMemberResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"access_granted_at":{"type":"string","format":"date-time","title":"Access Granted At"},"apps":{"items":{"type":"string"},"type":"array","title":"Apps"}},"type":"object","required":["id","email","name","access_granted_at","apps"],"title":"OrgAppMemberResponse","description":"One global user with active app memberships in an organization."},"OrgCostBreakdownResponse":{"properties":{"period":{"$ref":"#/components/schemas/CostBreakdownPeriod"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"},"included_cost_usd":{"type":"number","title":"Included Cost Usd"},"apps":{"items":{"$ref":"#/components/schemas/AppCostSummary"},"type":"array","title":"Apps"},"lines":{"items":{"$ref":"#/components/schemas/CostLine"},"type":"array","title":"Lines"}},"type":"object","required":["period","total_cost_usd","included_cost_usd","apps"],"title":"OrgCostBreakdownResponse","description":"Org-level cost breakdown — per-app totals for a billing period."},"OrgListResponse":{"properties":{"orgs":{"items":{"$ref":"#/components/schemas/OrgResponse"},"type":"array","title":"Orgs"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["orgs","total"],"title":"OrgListResponse","description":"Response listing the caller's organizations."},"OrgPlan":{"type":"string","enum":["paygo","team","enterprise"],"title":"OrgPlan","description":"Billing plan tier for an organization."},"OrgResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"plan":{"anyOf":[{"$ref":"#/components/schemas/OrgPlan"},{"type":"null"}]},"spend_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spend Cap"},"spend_cap_policy":{"$ref":"#/components/schemas/SpendCapPolicy"},"current_period_spend_cents":{"type":"integer","title":"Current Period Spend Cents","default":0},"spend_cap_exceeded":{"type":"boolean","title":"Spend Cap Exceeded","default":false},"billing_period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Billing Period Start"},"billing_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Billing Period End"},"member_count":{"type":"integer","title":"Member Count"},"member_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Member Limit"},"has_payment_method":{"type":"boolean","title":"Has Payment Method","default":false},"is_internal":{"type":"boolean","title":"Is Internal","default":false},"my_role":{"$ref":"#/components/schemas/OrgRole"},"onboarding_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Onboarding Completed At"},"logo_data_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Data Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","slug","plan","spend_cap","spend_cap_policy","member_count","my_role","created_at","updated_at"],"title":"OrgResponse","description":"Response for a single organization."},"OrgRole":{"type":"string","enum":["admin","member","viewer"],"title":"OrgRole","description":"Role of a user within an organization."},"OrganizationSsoCredentialReason":{"type":"string","enum":["NO_BINDING","SESSION_CREDENTIAL","EXACT_CURRENT_BINDING","POLICY_ENFORCED_CREDENTIAL_INCOMPATIBLE","CREDENTIAL_NOT_EXACT_CURRENT_SSO"],"title":"OrganizationSsoCredentialReason","description":"Stable explanation for the credential classification."},"OrganizationSsoCredentialStatus":{"type":"string","enum":["exact_current_sso","not_exact_current_sso","not_applicable"],"title":"OrganizationSsoCredentialStatus","description":"Whether the presented credential proves the current SSO binding."},"OrganizationSsoDoctorResponse":{"properties":{"credential_status":{"$ref":"#/components/schemas/OrganizationSsoCredentialStatus"},"credential_reason":{"$ref":"#/components/schemas/OrganizationSsoCredentialReason"},"enforcement_access":{"$ref":"#/components/schemas/OrganizationSsoEnforcementAccess"},"provider_reachability":{"$ref":"#/components/schemas/OrganizationSsoProviderReachability"},"next_action":{"anyOf":[{"$ref":"#/components/schemas/OrganizationSsoNextAction"},{"type":"null"}]},"status":{"anyOf":[{"$ref":"#/components/schemas/OrganizationSsoStatusResponse"},{"type":"null"}]}},"type":"object","required":["credential_status","credential_reason","enforcement_access","provider_reachability","next_action","status"],"title":"OrganizationSsoDoctorResponse","description":"Atomic SSO health and current-credential diagnostic snapshot."},"OrganizationSsoDomainResponse":{"properties":{"domain":{"type":"string","title":"Domain"},"state":{"type":"string","title":"State"}},"type":"object","required":["domain","state"],"title":"OrganizationSsoDomainResponse","description":"Redacted organization-domain presentation state."},"OrganizationSsoEnforcementAccess":{"type":"string","enum":["not_required","allowed","step_up_required","binding_unavailable"],"title":"OrganizationSsoEnforcementAccess","description":"The caller's current access outcome for this organization."},"OrganizationSsoEnforcementPolicy":{"type":"string","enum":["optional","enforced"],"title":"OrganizationSsoEnforcementPolicy","description":"Whether the binding is optional or required for owned resources."},"OrganizationSsoLifecycle":{"type":"string","enum":["enabled","disabled","removed"],"title":"OrganizationSsoLifecycle","description":"floo-owned lifecycle for an organization SSO binding."},"OrganizationSsoNextAction":{"type":"string","enum":["OPEN_SSO_SETUP","USE_ORGANIZATION_SSO_RECOVERY","CLI_REAUTHENTICATE_WITH_ORG_SSO"],"title":"OrganizationSsoNextAction","description":"Stable machine action emitted by the SSO diagnostic."},"OrganizationSsoPortalSessionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"url":{"type":"string","title":"Url"},"expires_in_seconds":{"type":"integer","title":"Expires In Seconds"}},"type":"object","required":["id","url","expires_in_seconds"],"title":"OrganizationSsoPortalSessionResponse","description":"Short-lived WorkOS Admin Portal URL, returned once and never persisted."},"OrganizationSsoProviderReachability":{"type":"string","enum":["reachable","unavailable","not_configured"],"title":"OrganizationSsoProviderReachability","description":"Coarse live provider reachability safe for diagnostic output."},"OrganizationSsoProviderState":{"type":"string","enum":["pending","active","inactive","deleted","invalid","provider_unavailable"],"title":"OrganizationSsoProviderState","description":"Fail-closed projection of the authoritative WorkOS connection state."},"OrganizationSsoProviderType":{"type":"string","enum":["saml","oidc"],"title":"OrganizationSsoProviderType","description":"Provider protocols floo supports for enterprise SSO."},"OrganizationSsoRecoveryCodeConfirmRequest":{"properties":{"recovery_token":{"type":"string","title":"Recovery Token"}},"type":"object","required":["recovery_token"],"title":"OrganizationSsoRecoveryCodeConfirmRequest","description":"Confirm receipt of a rotated token before retiring the prior token."},"OrganizationSsoRecoveryRequest":{"properties":{"recovery_token":{"type":"string","title":"Recovery Token"}},"type":"object","required":["recovery_token"],"title":"OrganizationSsoRecoveryRequest","description":"Consume recovery material to disable enforcement, never to read data."},"OrganizationSsoStatusResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"lifecycle":{"$ref":"#/components/schemas/OrganizationSsoLifecycle"},"status":{"$ref":"#/components/schemas/OrganizationSsoProviderState"},"provider_type":{"anyOf":[{"$ref":"#/components/schemas/OrganizationSsoProviderType"},{"type":"null"}]},"domains":{"items":{"$ref":"#/components/schemas/OrganizationSsoDomainResponse"},"type":"array","title":"Domains"},"acquisition_available":{"type":"boolean","title":"Acquisition Available"},"enforcement_ready":{"type":"boolean","title":"Enforcement Ready"},"enforcement_policy":{"$ref":"#/components/schemas/OrganizationSsoEnforcementPolicy"},"recovery_ready":{"type":"boolean","title":"Recovery Ready"},"observed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Observed At"}},"type":"object","required":["id","lifecycle","status","provider_type","domains","acquisition_available","enforcement_ready","enforcement_policy","recovery_ready","observed_at"],"title":"OrganizationSsoStatusResponse","description":"Tenant-safe SSO status with no WorkOS identifiers."},"PaygoAuthorityResponse":{"properties":{"state":{"$ref":"#/components/schemas/PaygoSpendState"},"stop_reason":{"anyOf":[{"$ref":"#/components/schemas/PaygoStopReason"},{"type":"null"}]},"binding_authority":{"$ref":"#/components/schemas/PaygoBindingAuthority"},"balance_sequence":{"type":"integer","title":"Balance Sequence"},"funds_remaining_nanodollars":{"type":"string","title":"Funds Remaining Nanodollars"},"period_usage_nanodollars":{"type":"string","title":"Period Usage Nanodollars"},"hard_limit_nanodollars":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hard Limit Nanodollars"},"remaining_nanodollars":{"type":"string","title":"Remaining Nanodollars"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"}},"type":"object","required":["state","stop_reason","binding_authority","balance_sequence","funds_remaining_nanodollars","period_usage_nanodollars","hard_limit_nanodollars","remaining_nanodollars","observed_at"],"title":"PaygoAuthorityResponse","description":"Current admission inputs; a read never authorizes a later operation."},"PaygoBalanceEventKind":{"type":"string","enum":["funding_pending","account_activated","funding_settled","funding_canceled","refund_settled","refund_reinstated","dispute_debited","dispute_reinstated","operator_adjustment","migration_opening","usage_debit"],"title":"PaygoBalanceEventKind","description":"Closed accounting effects; allowances and promotional grants are excluded."},"PaygoBalanceResponse":{"properties":{"billing_mode":{"anyOf":[{"$ref":"#/components/schemas/BillingMode"},{"type":"null"}]},"funding_eligible":{"type":"boolean","title":"Funding Eligible"},"activation":{"type":"string","enum":["dormant","scheduled","active"],"title":"Activation"},"usage_started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Usage Started At"},"pending_nanodollars":{"type":"string","title":"Pending Nanodollars"},"balance_nanodollars":{"type":"string","title":"Balance Nanodollars"},"recorded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Recorded At"},"authority":{"anyOf":[{"$ref":"#/components/schemas/PaygoAuthorityResponse"},{"type":"null"}]},"enforcement":{"anyOf":[{"$ref":"#/components/schemas/PaygoEnforcementResponse"},{"type":"null"}]}},"type":"object","required":["billing_mode","funding_eligible","activation","usage_started_at","pending_nanodollars","balance_nanodollars","recorded_at"],"title":"PaygoBalanceResponse","description":"Current committed money snapshot; positive credit balance does not authorize spending."},"PaygoBindingAuthority":{"type":"string","enum":["funds","hard_limit","activation","meter_freshness","unknown"],"title":"PaygoBindingAuthority","description":"The authority currently limiting additional spend."},"PaygoEnforcementResponse":{"properties":{"desired_blocked":{"type":"boolean","title":"Desired Blocked"},"generation":{"type":"integer","title":"Generation"},"applied_generation":{"type":"integer","title":"Applied Generation"}},"type":"object","required":["desired_blocked","generation","applied_generation"],"title":"PaygoEnforcementResponse","description":"Recorded provider convergence, not a live workload health assessment."},"PaygoFundingAttemptResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"amount_cents":{"type":"integer","title":"Amount Cents"},"currency":{"type":"string","const":"usd","title":"Currency"},"status":{"type":"string","title":"Status"},"save_for_future":{"type":"boolean","title":"Save For Future"},"card_saved":{"type":"boolean","title":"Card Saved"}},"type":"object","required":["id","amount_cents","currency","status","save_for_future","card_saved"],"title":"PaygoFundingAttemptResponse","description":"Resumable funding state; settled is the only credited terminal state."},"PaygoFundingSessionRequest":{"properties":{"client_request_id":{"type":"string","format":"uuid","title":"Client Request Id"},"amount_cents":{"type":"integer","maximum":100000.0,"minimum":1000.0,"title":"Amount Cents"},"currency":{"type":"string","const":"usd","title":"Currency","default":"usd"},"return_to":{"type":"string","enum":["onboarding","billing"],"title":"Return To"},"save_for_future":{"type":"boolean","const":true,"title":"Save For Future"},"consent_version":{"type":"string","enum":["paygo-card-backstop-v1","paygo-card-top-up-v1"],"title":"Consent Version"}},"type":"object","required":["client_request_id","amount_cents","return_to","save_for_future","consent_version"],"title":"PaygoFundingSessionRequest","description":"A credit purchase requires explicit consent to save a card and collect usage overages."},"PaygoFundingSessionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"amount_cents":{"type":"integer","title":"Amount Cents"},"currency":{"type":"string","const":"usd","title":"Currency"},"status":{"type":"string","title":"Status"},"save_for_future":{"type":"boolean","title":"Save For Future"},"card_saved":{"type":"boolean","title":"Card Saved"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret","description":"Stripe Checkout Session client secret for the browser's payment form."}},"type":"object","required":["id","amount_cents","currency","status","save_for_future","card_saved"],"title":"PaygoFundingSessionResponse","description":"POST-only funding session entry point for the creator org admin."},"PaygoHistoryResponse":{"properties":{"currency":{"type":"string","const":"usd","title":"Currency","default":"usd"},"events":{"items":{"$ref":"#/components/schemas/PaygoTransaction"},"type":"array","title":"Events"},"next_before_sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Before Sequence"}},"type":"object","required":["events","next_before_sequence"],"title":"PaygoHistoryResponse","description":"A descending page of USD money events; this is not spend authorization."},"PaygoNotification":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"state":{"$ref":"#/components/schemas/PaygoSpendState"},"subject":{"type":"string","title":"Subject"},"body":{"type":"string","title":"Body"},"first_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Attempt At"},"last_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Attempt At"},"provider_accepted":{"type":"boolean","title":"Provider Accepted"},"closed_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Closed Reason"}},"type":"object","required":["id","state","subject","body","first_attempt_at","last_attempt_at","provider_accepted","closed_reason"],"title":"PaygoNotification","description":"One retained email submission; acceptance does not establish inbox delivery."},"PaygoNotificationsResponse":{"properties":{"records":{"items":{"$ref":"#/components/schemas/PaygoNotification"},"type":"array","title":"Records"},"next_before_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Next Before Id"}},"type":"object","required":["records","next_before_id"],"title":"PaygoNotificationsResponse","description":"Customer notice evidence, ordered by descending epoch and stable record ID."},"PaygoSavedCard":{"properties":{"brand":{"type":"string","title":"Brand"},"last4":{"type":"string","title":"Last4"},"exp_month":{"type":"integer","title":"Exp Month"},"exp_year":{"type":"integer","title":"Exp Year"}},"type":"object","required":["brand","last4","exp_month","exp_year"],"title":"PaygoSavedCard","description":"Display details of the card authorized for prepaid overage charges."},"PaygoSavedCardResponse":{"properties":{"card":{"anyOf":[{"$ref":"#/components/schemas/PaygoSavedCard"},{"type":"null"}]}},"type":"object","required":["card"],"title":"PaygoSavedCardResponse","description":"Current consented overage card, or null when no saved card is available."},"PaygoSpendState":{"type":"string","enum":["pending_activation","available","low","imminent","exhausted","recovered","unknown"],"title":"PaygoSpendState","description":"Customer-visible prepaid authority states."},"PaygoStopReason":{"type":"string","enum":["pending_activation","unknown","payment_failed","unpaid_ceiling","refund_pending","hard_limit"],"title":"PaygoStopReason","description":"Ordered reasons running prepaid services must stop."},"PaygoTransaction":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_sequence":{"type":"integer","title":"Account Sequence"},"kind":{"$ref":"#/components/schemas/PaygoBalanceEventKind"},"source_occurred_at":{"type":"string","format":"date-time","title":"Source Occurred At"},"recorded_at":{"type":"string","format":"date-time","title":"Recorded At"},"pending_delta_nanodollars":{"type":"string","title":"Pending Delta Nanodollars"},"funds_delta_nanodollars":{"type":"string","title":"Funds Delta Nanodollars"},"usage_delta_nanodollars":{"type":"string","title":"Usage Delta Nanodollars"},"pending_after_nanodollars":{"type":"string","title":"Pending After Nanodollars"},"funds_after_nanodollars":{"type":"string","title":"Funds After Nanodollars"},"usage_after_nanodollars":{"type":"string","title":"Usage After Nanodollars"},"raw_balance_after_nanodollars":{"type":"string","title":"Raw Balance After Nanodollars"}},"type":"object","required":["id","account_sequence","kind","source_occurred_at","recorded_at","pending_delta_nanodollars","funds_delta_nanodollars","usage_delta_nanodollars","pending_after_nanodollars","funds_after_nanodollars","usage_after_nanodollars","raw_balance_after_nanodollars"],"title":"PaygoTransaction","description":"Exact immutable money effects without processor or operator-only evidence."},"PlanFeaturesResponse":{"properties":{"custom_domains":{"type":"boolean","title":"Custom Domains"},"accounts_access":{"type":"boolean","title":"Accounts Access"},"edge_policy":{"type":"boolean","title":"Edge Policy"},"audit_logs":{"type":"boolean","title":"Audit Logs"},"audit_export":{"type":"boolean","title":"Audit Export"},"support_level":{"type":"string","enum":["community","standard","priority","dedicated"],"title":"Support Level"},"sso":{"type":"boolean","title":"Sso"},"scim":{"type":"boolean","title":"Scim"}},"type":"object","required":["custom_domains","accounts_access","edge_policy","audit_logs","audit_export","support_level","sso","scim"],"title":"PlanFeaturesResponse","description":"Feature ownership for the current plan."},"PlanLimitsResponse":{"properties":{"plan":{"anyOf":[{"$ref":"#/components/schemas/OrgPlan"},{"type":"null"}]},"max_spend_cap_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Spend Cap Cents"},"limits":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"null"}]},"type":"object","title":"Limits"},"features":{"$ref":"#/components/schemas/PlanFeaturesResponse"}},"type":"object","required":["plan","max_spend_cap_cents","limits","features"],"title":"PlanLimitsResponse","description":"Response containing plan limits for the org."},"PlanSummary":{"properties":{"action_count":{"type":"integer","title":"Action Count","default":0},"destructive_count":{"type":"integer","title":"Destructive Count","default":0},"estimated_duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Duration Seconds"}},"additionalProperties":false,"type":"object","title":"PlanSummary","description":"Aggregate counts and risk flags for a preflight plan."},"PortalRequest":{"properties":{"return_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Return Url"}},"type":"object","required":["return_url"],"title":"PortalRequest","description":"Request to create a Stripe Customer Portal Session."},"PortalResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"PortalResponse","description":"Response containing the Stripe Portal URL."},"PrApprovalRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"pr_number":{"type":"integer","title":"Pr Number"},"repo_full_name":{"type":"string","title":"Repo Full Name"},"head_sha":{"type":"string","title":"Head Sha"},"status":{"$ref":"#/components/schemas/PrApprovalStatus"},"gated_ops_snapshot":{"items":{},"type":"array","title":"Gated Ops Snapshot"},"gated_set_hash":{"type":"string","title":"Gated Set Hash"},"requested_at":{"type":"string","format":"date-time","title":"Requested At"},"decided_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Decided By User Id"},"decided_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Decided At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","app_id","pr_number","repo_full_name","head_sha","status","gated_ops_snapshot","gated_set_hash","requested_at","decided_by_user_id","decided_at","expires_at"],"title":"PrApprovalRequestResponse","description":"A PR-time infra-gate approval record, for the dashboard approval page.\n\nMirrors ApprovalRequestResponse but is keyed by its own id (a PR's identity is\n(app, repo, pr_number); the row id is the unambiguous handle the comment/email\nlink to). Governance L6 / #824."},"PrApprovalStatus":{"type":"string","enum":["pending","approved","rejected","superseded","expired","consumed"],"title":"PrApprovalStatus","description":"Lifecycle status of a PR-time approval request."},"PreflightPlan":{"properties":{"managed_services":{"$ref":"#/components/schemas/ManagedServicesPlan"},"runtime_services":{"items":{"$ref":"#/components/schemas/PreflightRuntimeService"},"type":"array","title":"Runtime Services"},"scheduled_deprovisions":{"items":{"$ref":"#/components/schemas/ScheduledDeprovisionItem"},"type":"array","title":"Scheduled Deprovisions"},"summary":{"$ref":"#/components/schemas/PlanSummary"},"destructive":{"type":"boolean","title":"Destructive","default":false},"data_loss":{"type":"boolean","title":"Data Loss","default":false}},"additionalProperties":false,"type":"object","title":"PreflightPlan","description":"Top-level preflight plan.\n\nAdditional domain plans (services, env vars, routes, crons, domains) are\nadded as the planner grows. The shape is deliberately additive, with new\nfields defaulting to empty plans so existing consumers keep working.\n\n`destructive` is true iff acting on this plan would modify or destroy\nexisting state. Pure provisioning is additive and not destructive.\n`scheduled_deprovisions` is a sibling status readout, not an action bin."},"PreflightRuntimeComponent":{"properties":{"name":{"type":"string","title":"Name"},"cpu":{"type":"string","title":"Cpu"},"memory":{"type":"string","title":"Memory"},"source":{"type":"string","title":"Source"}},"type":"object","required":["name","cpu","memory","source"],"title":"PreflightRuntimeComponent","description":"Describe one preflight runtime component's resource allocation and origin."},"PreflightRuntimeInstanceTotal":{"properties":{"cpu":{"type":"string","title":"Cpu"},"memory":{"type":"string","title":"Memory"}},"type":"object","required":["cpu","memory"],"title":"PreflightRuntimeInstanceTotal","description":"Expose aggregate CPU and memory for one preflight instance."},"PreflightRuntimePlan":{"properties":{"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"service_type":{"type":"string","title":"Service Type"},"availability":{"type":"string","title":"Availability"},"declared":{"$ref":"#/components/schemas/PreflightRuntimeValues"},"effective":{"$ref":"#/components/schemas/PreflightRuntimeValues"},"sources":{"$ref":"#/components/schemas/PreflightRuntimeSources"},"components":{"items":{"$ref":"#/components/schemas/PreflightRuntimeComponent"},"type":"array","title":"Components"},"instance_total":{"$ref":"#/components/schemas/PreflightRuntimeInstanceTotal"},"cpu_allocation":{"type":"string","title":"Cpu Allocation"},"cpu_allocation_reason":{"type":"string","title":"Cpu Allocation Reason"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings"}},"type":"object","required":["env","service_type","availability","declared","effective","sources","components","instance_total","cpu_allocation","cpu_allocation_reason","warnings"],"title":"PreflightRuntimePlan","description":"Server-resolved runtime posture for a declared service."},"PreflightRuntimeService":{"properties":{"name":{"type":"string","title":"Name"},"runtime_plan":{"$ref":"#/components/schemas/PreflightRuntimePlan"},"generated_env_keys":{"items":{"type":"string"},"type":"array","title":"Generated Env Keys"}},"additionalProperties":false,"type":"object","required":["name","runtime_plan"],"title":"PreflightRuntimeService","description":"Pair a strictly shaped service runtime plan with generated environment key names."},"PreflightRuntimeSources":{"properties":{"cpu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpu"},"memory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory"},"min_instances":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Instances"},"max_instances":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Max Instances"},"instances":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instances"}},"type":"object","required":["cpu","memory","min_instances","max_instances","instances"],"title":"PreflightRuntimeSources","description":"Record the origin of each nullable preflight runtime setting."},"PreflightRuntimeValues":{"properties":{"cpu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpu"},"memory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory"},"min_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Instances"},"max_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Instances"},"instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instances"}},"type":"object","required":["cpu","memory","min_instances","max_instances","instances"],"title":"PreflightRuntimeValues","description":"Expose nullable requested or resolved runtime resource values during preflight."},"PreviewDataRequest":{"properties":{"mode":{"$ref":"#/components/schemas/PreviewHydrationMode","default":"empty"},"seed_command":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seed Command"},"sanitize_command":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sanitize Command"}},"type":"object","title":"PreviewDataRequest","description":"Data hydration settings for an explicitly-created preview."},"PreviewDatabaseBranchListResponse":{"properties":{"database_branches":{"items":{"$ref":"#/components/schemas/PreviewDatabaseBranchResponse"},"type":"array","title":"Database Branches"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["database_branches","total"],"title":"PreviewDatabaseBranchListResponse","description":"List preview database branches."},"PreviewDatabaseBranchResponse":{"properties":{"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id"},"managed_service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Managed Service Id"},"name":{"type":"string","title":"Name"},"source_env":{"type":"string","title":"Source Env"},"preview_slug":{"type":"string","title":"Preview Slug"},"resource_status":{"type":"string","title":"Resource Status"},"hydration_mode":{"type":"string","title":"Hydration Mode"},"schema_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Name"},"role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Name"},"base_schema_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Schema Name"},"base_role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Role Name"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"reset_eligible":{"type":"boolean","title":"Reset Eligible"},"reset_blocked_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reset Blocked Reason"}},"type":"object","required":["name","source_env","preview_slug","resource_status","hydration_mode","reset_eligible"],"title":"PreviewDatabaseBranchResponse","description":"A managed Postgres branch backing one preview environment."},"PreviewHydrationMode":{"type":"string","enum":["empty","seed","clone-dev","clone-prod-sanitized"],"title":"PreviewHydrationMode","description":"Wire-safe data hydration mode."},"PreviewListResponse":{"properties":{"previews":{"items":{"$ref":"#/components/schemas/PreviewResponse"},"type":"array","title":"Previews"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["previews","total"],"title":"PreviewListResponse","description":"List active previews for an app."},"PreviewManagedResourceBranchListResponse":{"properties":{"resources":{"items":{"$ref":"#/components/schemas/PreviewManagedResourceBranchResponse"},"type":"array","title":"Resources"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["resources","total"],"title":"PreviewManagedResourceBranchListResponse","description":"List preview managed resource branches."},"PreviewManagedResourceBranchResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"managed_service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Managed Service Id"},"resource_type":{"type":"string","title":"Resource Type"},"name":{"type":"string","title":"Name"},"resource_key":{"type":"string","title":"Resource Key"},"source_env":{"type":"string","title":"Source Env"},"preview_slug":{"type":"string","title":"Preview Slug"},"resource_status":{"type":"string","title":"Resource Status"},"hydration_mode":{"type":"string","title":"Hydration Mode"},"schema_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Name"},"role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Name"},"base_schema_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Schema Name"},"base_role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Role Name"},"database_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Database Id"},"bucket_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bucket Name"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"reset_eligible":{"type":"boolean","title":"Reset Eligible"},"reset_blocked_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reset Blocked Reason"},"dev_prod_untouched":{"type":"boolean","title":"Dev Prod Untouched","default":true}},"type":"object","required":["id","resource_type","name","resource_key","source_env","preview_slug","resource_status","hydration_mode","reset_eligible"],"title":"PreviewManagedResourceBranchResponse","description":"A preview-owned managed resource branch."},"PreviewResourceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"type":{"type":"string","title":"Type"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"external_resource_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Resource Id"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","type","name","status"],"title":"PreviewResourceResponse","description":"A managed resource backing one preview environment."},"PreviewResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"slug":{"type":"string","title":"Slug"},"source_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Branch"},"pr_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pr Number"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"latest_deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Latest Deploy Id"},"latest_deploy_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Deploy Status"},"latest_commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Commit Sha"},"latest_cloud_run_service_names":{"items":{"type":"string"},"type":"array","title":"Latest Cloud Run Service Names"},"ttl_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttl Hours"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"resources":{"items":{"$ref":"#/components/schemas/PreviewResourceResponse"},"type":"array","title":"Resources"},"database_branches":{"items":{"$ref":"#/components/schemas/PreviewDatabaseBranchResponse"},"type":"array","title":"Database Branches"},"managed_resource_branches":{"items":{"$ref":"#/components/schemas/PreviewManagedResourceBranchResponse"},"type":"array","title":"Managed Resource Branches"}},"type":"object","required":["id","app_id","slug","source_branch"],"title":"PreviewResponse","description":"Preview environment detail."},"Project":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"name":{"type":"string","title":"Name"},"app_url":{"type":"string","title":"App Url"},"repo_full_name":{"type":"string","title":"Repo Full Name"},"clone_url":{"type":"string","title":"Clone Url"},"default_branch":{"type":"string","title":"Default Branch"},"first_deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"First Deploy Id"}},"type":"object","required":["app_id","name","app_url","repo_full_name","clone_url","default_branch"],"title":"Project","description":"Expose a managed app's repository, development URL, and optional first deploy."},"ProjectsResponse":{"properties":{"projects":{"items":{"$ref":"#/components/schemas/Project"},"type":"array","title":"Projects"}},"type":"object","required":["projects"],"title":"ProjectsResponse","description":"Wrap the managed projects visible to the caller."},"PromoteRequest":{"properties":{"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"},"services":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Services"}},"type":"object","title":"PromoteRequest","description":"Request to promote an app to prod."},"PromoteResponse":{"properties":{"deploy_id":{"type":"string","format":"uuid","title":"Deploy Id"},"tag":{"type":"string","title":"Tag"},"release_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Url"},"services":{"items":{"$ref":"#/components/schemas/ServicePromoteResult"},"type":"array","title":"Services"},"message":{"type":"string","title":"Message"}},"type":"object","required":["deploy_id","tag","services","message"],"title":"PromoteResponse","description":"Response from the promote endpoint."},"RealtimeMetricsResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"period":{"type":"string","enum":["5m","1h","24h","7d"],"title":"Period"},"services":{"items":{"$ref":"#/components/schemas/ServiceMetrics"},"type":"array","title":"Services"}},"type":"object","required":["app_id","period","services"],"title":"RealtimeMetricsResponse","description":"Response for realtime per-app metrics."},"RedisKeyDetailResponse":{"properties":{"env":{"type":"string","enum":["dev","prod"],"title":"Env"},"key":{"type":"string","minLength":1,"title":"Key"},"type":{"type":"string","minLength":1,"title":"Type"},"ttl_seconds":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Ttl Seconds"},"size":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Size"},"size_display":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Size Display"},"string_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"String Value"},"entries":{"items":{"$ref":"#/components/schemas/RedisPreviewEntry"},"type":"array","title":"Entries"},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","required":["env","key","type"],"title":"RedisKeyDetailResponse","description":"Detailed preview for a single Redis key."},"RedisKeySummaryResponse":{"properties":{"key":{"type":"string","minLength":1,"title":"Key"},"type":{"type":"string","minLength":1,"title":"Type"},"ttl_seconds":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Ttl Seconds"},"size":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Size"},"size_display":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Size Display"}},"type":"object","required":["key","type"],"title":"RedisKeySummaryResponse","description":"Directory row for a Redis key."},"RedisKeysResponse":{"properties":{"env":{"type":"string","enum":["dev","prod"],"title":"Env"},"keys":{"items":{"$ref":"#/components/schemas/RedisKeySummaryResponse"},"type":"array","title":"Keys"},"total_returned":{"type":"integer","minimum":0.0,"title":"Total Returned"},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","required":["env","keys","total_returned"],"title":"RedisKeysResponse","description":"Response for listing Redis keys."},"RedisPreviewEntry":{"properties":{"label":{"type":"string","minLength":1,"title":"Label"},"value":{"type":"string","title":"Value"}},"type":"object","required":["label","value"],"title":"RedisPreviewEntry","description":"One row in a Redis value preview."},"RedisStatsResponse":{"properties":{"env":{"type":"string","enum":["dev","prod"],"title":"Env"},"key_count":{"type":"integer","minimum":0.0,"title":"Key Count"},"memory_used_bytes":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Memory Used Bytes"},"memory_human":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Memory Human"},"connected_clients":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Connected Clients"},"hit_rate":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Hit Rate"},"uptime_seconds":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Uptime Seconds"}},"type":"object","required":["env","key_count"],"title":"RedisStatsResponse","description":"High-level Redis metrics for the managed instance."},"ReleaseListResponse":{"properties":{"releases":{"items":{"$ref":"#/components/schemas/ReleaseResponse"},"type":"array","title":"Releases"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["releases","total","page","per_page"],"title":"ReleaseListResponse","description":"Paginated response for listing releases."},"ReleaseResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"env_id":{"type":"string","format":"uuid","title":"Env Id"},"deploy_id":{"type":"string","format":"uuid","title":"Deploy Id"},"source_deploy_id":{"type":"string","format":"uuid","title":"Source Deploy Id"},"image_digest":{"type":"string","title":"Image Digest"},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha"},"tag":{"type":"string","title":"Tag"},"promoted_by":{"type":"string","title":"Promoted By"},"release_number":{"type":"integer","title":"Release Number"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","env_id","deploy_id","source_deploy_id","image_digest","commit_sha","tag","promoted_by","release_number","created_at","updated_at"],"title":"ReleaseResponse","description":"Response for a single release."},"ReparoConfigResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"mode":{"$ref":"#/components/schemas/ReparoMode"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"error_threshold":{"type":"integer","title":"Error Threshold"},"cooldown_minutes":{"type":"integer","title":"Cooldown Minutes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","mode","webhook_url","error_threshold","cooldown_minutes","created_at","updated_at"],"title":"ReparoConfigResponse","description":"Response for Reparo configuration."},"ReparoEventListResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/ReparoEventResponse"},"type":"array","title":"Events"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["events","total","page","per_page"],"title":"ReparoEventListResponse","description":"Paginated response for Reparo events."},"ReparoEventResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Deploy Id"},"error_fingerprint":{"type":"string","title":"Error Fingerprint"},"error_message":{"type":"string","title":"Error Message"},"stack_trace":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stack Trace"},"status":{"$ref":"#/components/schemas/ReparoEventStatus"},"webhook_response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Webhook Response Status"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","deploy_id","error_fingerprint","error_message","stack_trace","status","webhook_response_status","resolved_at","created_at","updated_at"],"title":"ReparoEventResponse","description":"Response for a single Reparo event."},"ReparoEventStatus":{"type":"string","enum":["triggered","in_progress","succeeded","failed","skipped"],"title":"ReparoEventStatus","description":"Lifecycle status of a Reparo event.\n\n`triggered`   — the event was created and is queued for delivery\n`in_progress` — webhook delivery is in flight (or being retried)\n`succeeded`   — webhook responded 2xx; downstream agent has acked\n`failed`      — permanent delivery failure (after retries)\n`skipped`     — matched a rule but suppressed (cooldown, rate limit)"},"ReparoMode":{"type":"string","enum":["webhook","off"],"title":"ReparoMode","description":"Operating mode for Reparo.\n\n`webhook` — detected errors fire an enriched outbound webhook\n`off`     — detection disabled for the app\n\nHistorical note: a `native` mode used to exist that promised floo\nwould generate fixes via a GitHub PR. That scope was dropped on\n2026-04-13 because it competes with specialized agent platforms."},"RequestLogEntry":{"properties":{"timestamp":{"type":"string","title":"Timestamp"},"method":{"type":"string","title":"Method"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path"},"host":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host"},"status_code":{"type":"integer","title":"Status Code"},"latency_ms":{"type":"integer","title":"Latency Ms"},"access_mode":{"type":"string","title":"Access Mode"},"user_identity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Identity"},"app_consumer_api_key_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"App Consumer Api Key Id"}},"type":"object","required":["timestamp","method","status_code","latency_ms","access_mode"],"title":"RequestLogEntry","description":"A single HTTP request handled by floo's gateway."},"RequestLogsResponse":{"properties":{"requests":{"items":{"$ref":"#/components/schemas/RequestLogEntry"},"type":"array","title":"Requests"},"total":{"type":"integer","title":"Total"},"app_name":{"type":"string","title":"App Name"},"next_cursor":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["requests","total","app_name"],"title":"RequestLogsResponse","description":"Response for the gateway request logs endpoint."},"ResolutionSource":{"type":"string","enum":["configured","platform_default","plan_limit","platform_limit","resource_compatibility","max_instances_limit"],"title":"ResolutionSource","description":"Identify the configuration, policy, or compatibility constraint that resolved a value."},"ResourceCost":{"properties":{"cost_usd":{"type":"number","title":"Cost Usd"}},"type":"object","required":["cost_usd"],"title":"ResourceCost","description":"Cost for a single resource type — customer-facing amount only."},"ResourceDoctorDrift":{"properties":{"declared":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Declared","default":"unknown"},"applied":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Applied","default":"unknown"},"kind":{"type":"string","enum":["not_declared","not_applied"],"title":"Kind"},"summary":{"type":"string","title":"Summary"},"likely_fix":{"type":"string","title":"Likely Fix"},"resource_id":{"type":"string","format":"uuid","title":"Resource Id"},"resource_kind":{"type":"string","enum":["service","managed_service","cron_job"],"title":"Resource Kind"},"name":{"type":"string","title":"Name"}},"type":"object","required":["kind","summary","likely_fix","resource_id","resource_kind","name"],"title":"ResourceDoctorDrift","description":"A row with false membership in the environment's LIVE deploy."},"ResourceDoctorResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id"},"app_name":{"type":"string","title":"App Name"},"env":{"type":"string","title":"Env"},"live_deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Live Deploy Id"},"checked_resources":{"type":"integer","title":"Checked Resources"},"unknown_resources":{"type":"integer","title":"Unknown Resources"},"drift_detected":{"type":"boolean","title":"Drift Detected"},"drift":{"items":{"$ref":"#/components/schemas/ResourceDoctorDrift"},"type":"array","title":"Drift"}},"type":"object","required":["app_id","app_name","env","live_deploy_id","checked_resources","unknown_resources","drift_detected","drift"],"title":"ResourceDoctorResponse","description":"Membership coverage; unknown rows can also have a proven false dimension."},"RestartRequest":{"properties":{"services":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Services"}},"type":"object","title":"RestartRequest","description":"Request body for restarting an app."},"RiskTier":{"type":"integer","enum":[1,2,3],"title":"RiskTier","description":"Risk tier of a single plan operation.\n\nMirrors the CLI destructive-command tier contract (floo-cli/src/confirm.rs)\nand the State and Audit Doctrine confirmation tiers. The tier is the single\nsource of truth — destructive/data_loss are computed from it\n(see OpRisk.destructive / OpRisk.data_loss)."},"RollbackRequest":{"properties":{"deploy_id":{"type":"string","format":"uuid","title":"Deploy Id"}},"type":"object","required":["deploy_id"],"title":"RollbackRequest","description":"Request body for rolling back to a previous deploy."},"RuntimeComponentResponse":{"properties":{"name":{"type":"string","title":"Name"},"cpu":{"type":"string","title":"Cpu"},"memory":{"type":"string","title":"Memory"},"source":{"type":"string","title":"Source"}},"type":"object","required":["name","cpu","memory","source"],"title":"RuntimeComponentResponse","description":"Describe one runtime component's resource allocation and origin."},"RuntimeInstanceTotal":{"properties":{"cpu":{"type":"string","title":"Cpu"},"memory":{"type":"string","title":"Memory"}},"type":"object","required":["cpu","memory"],"title":"RuntimeInstanceTotal","description":"Expose total CPU and memory allocated to one runtime instance."},"RuntimePlanResponse":{"properties":{"env":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"},"service_type":{"$ref":"#/components/schemas/ServiceType"},"availability":{"$ref":"#/components/schemas/AvailabilityMode"},"declared":{"$ref":"#/components/schemas/RuntimeValuesResponse"},"effective":{"$ref":"#/components/schemas/RuntimeValuesResponse"},"sources":{"$ref":"#/components/schemas/RuntimeSourcesResponse"},"components":{"items":{"$ref":"#/components/schemas/RuntimeComponentResponse"},"type":"array","title":"Components"},"instance_total":{"$ref":"#/components/schemas/RuntimeInstanceTotal"},"cpu_allocation":{"$ref":"#/components/schemas/CpuAllocationMode"},"cpu_allocation_reason":{"type":"string","title":"Cpu Allocation Reason"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings"}},"type":"object","required":["env","service_type","availability","declared","effective","sources","components","instance_total","cpu_allocation","cpu_allocation_reason","warnings"],"title":"RuntimePlanResponse","description":"Server-resolved scaling and CPU contract for one environment."},"RuntimeSourcesResponse":{"properties":{"cpu":{"anyOf":[{"$ref":"#/components/schemas/ResolutionSource"},{"type":"null"}]},"memory":{"anyOf":[{"$ref":"#/components/schemas/ResolutionSource"},{"type":"null"}]},"min_instances":{"anyOf":[{"$ref":"#/components/schemas/ResolutionSource"},{"type":"null"}]},"max_instances":{"anyOf":[{"$ref":"#/components/schemas/ResolutionSource"},{"type":"null"}]},"instances":{"anyOf":[{"$ref":"#/components/schemas/ResolutionSource"},{"type":"null"}]}},"type":"object","required":["cpu","memory","min_instances","max_instances","instances"],"title":"RuntimeSourcesResponse","description":"Identify the resolution source of each service runtime setting."},"RuntimeValuesResponse":{"properties":{"cpu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpu"},"memory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory"},"min_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Instances"},"max_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Instances"},"instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instances"}},"type":"object","required":["cpu","memory","min_instances","max_instances","instances"],"title":"RuntimeValuesResponse","description":"Expose nullable CPU, memory, and instance scaling values for a service."},"SalesLeadIntent":{"type":"string","enum":["enterprise_internal_tools","billing_enterprise","seat_limit","general"],"title":"SalesLeadIntent","description":"Reason the user asked to talk to sales."},"SalesLeadResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"source":{"$ref":"#/components/schemas/SalesLeadSource"},"intent":{"$ref":"#/components/schemas/SalesLeadIntent"},"email":{"type":"string","title":"Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","source","intent","email","created_at"],"title":"SalesLeadResponse","description":"Response for a submitted sales lead."},"SalesLeadSource":{"type":"string","enum":["landing","dashboard"],"title":"SalesLeadSource","description":"Where the sales lead came from."},"ScheduledDeprovisionItem":{"properties":{"type":{"$ref":"#/components/schemas/ManagedServiceType"},"name":{"type":"string","maxLength":63,"title":"Name"},"managed_service_id":{"type":"string","format":"uuid","title":"Managed Service Id"},"dev_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Dev Deprovision After"},"prod_deprovision_after":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Prod Deprovision After"}},"additionalProperties":false,"type":"object","required":["type","name","managed_service_id"],"title":"ScheduledDeprovisionItem","description":"A managed service with a live teardown clock (epic #817/#824).\n\nA status readout, not a reconciliation action: it surfaces every pending\nauto-teardown and its per-env deadline so operators and agents can see a\ncountdown that is already running — independent of whether the service is\nre-declared in this deploy. The gating decision already happened when the\nremoval was first declared (an undeclared row also appears in\n``managed_services.to_deprovision``); this view adds only the *when*. A\nteardown is rescinded by re-declaring the service in floo.app.toml before\nthe clock elapses."},"ServiceCostBreakdown":{"properties":{"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"name":{"type":"string","title":"Name"},"costs":{"additionalProperties":{"$ref":"#/components/schemas/ResourceCost"},"type":"object","title":"Costs"},"lines":{"items":{"$ref":"#/components/schemas/CostLine"},"type":"array","title":"Lines"},"total_usd":{"type":"number","title":"Total Usd"}},"type":"object","required":["service_id","name","costs","total_usd"],"title":"ServiceCostBreakdown","description":"Per-service cost breakdown."},"ServiceGitHubInfo":{"properties":{"name":{"type":"string","title":"Name"},"repo_full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Full Name"},"default_branch":{"type":"string","title":"Default Branch","default":"main"},"installation_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Installation Id"}},"type":"object","required":["name"],"title":"ServiceGitHubInfo","description":"Per-service GitHub repo info in connection response."},"ServiceGitHubRequest":{"properties":{"repo_full_name":{"type":"string","title":"Repo Full Name"},"default_branch":{"type":"string","title":"Default Branch","default":"main"}},"type":"object","required":["repo_full_name"],"title":"ServiceGitHubRequest","description":"Request to set GitHub repo on a specific service."},"ServiceListResponse":{"properties":{"services":{"items":{"$ref":"#/components/schemas/ServiceResponse"},"type":"array","title":"Services"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["services","total","page","per_page"],"title":"ServiceListResponse","description":"Response for listing services."},"ServiceMetrics":{"properties":{"name":{"type":"string","title":"Name"},"request_count":{"type":"integer","title":"Request Count"},"error_count":{"type":"integer","title":"Error Count"},"error_rate":{"type":"number","title":"Error Rate"},"avg_latency_ms":{"type":"number","title":"Avg Latency Ms"},"p95_latency_ms":{"type":"number","title":"P95 Latency Ms"},"cpu_utilization":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cpu Utilization"},"memory_utilization":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Memory Utilization"},"instance_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instance Count"}},"type":"object","required":["name","request_count","error_count","error_rate","avg_latency_ms","p95_latency_ms","cpu_utilization","memory_utilization","instance_count"],"title":"ServiceMetrics","description":"Realtime metrics for a single service within an app.\n\ncpu_utilization, memory_utilization, and instance_count require Cloud\nMonitoring API integration and are always null in the current implementation."},"ServicePromoteResult":{"properties":{"name":{"type":"string","title":"Name"},"success":{"type":"boolean","title":"Success"},"image_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Uri"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["name","success"],"title":"ServicePromoteResult","description":"Per-service outcome from a promote operation."},"ServiceResponse":{"properties":{"declared":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Declared","default":"unknown"},"applied":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Applied","default":"unknown"},"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/ServiceType"},"port":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port"},"ingress":{"$ref":"#/components/schemas/IngressMode"},"cloud_run_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Run Url"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"cloud_run_service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Run Service Name"},"image_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Uri"},"status":{"$ref":"#/components/schemas/ServiceStatus"},"cpu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpu"},"memory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory"},"max_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Instances"},"min_instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Instances"},"instances":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instances"},"max_request_body_mb":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Request Body Mb"},"runtime_plan":{"anyOf":[{"$ref":"#/components/schemas/RuntimePlanResponse"},{"type":"null"}]},"cache_hit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cache Hit"},"base_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Image"},"base_image_floo":{"type":"boolean","title":"Base Image Floo","default":false},"repo_full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Full Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_id","name","type","port","ingress","cloud_run_url","image_uri","status","created_at","updated_at"],"title":"ServiceResponse","description":"Response for a single service."},"ServiceStatus":{"type":"string","enum":["pending","deploying","running","failed","stopped"],"title":"ServiceStatus","description":"Lifecycle status of a service."},"ServiceSummary":{"properties":{"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/ServiceType"},"ingress":{"$ref":"#/components/schemas/IngressMode"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"cloud_run_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Run Url"}},"type":"object","required":["name","type","ingress","url"],"title":"ServiceSummary","description":"Lightweight service info embedded in AppResponse so the dashboard\nknows which services are public-facing and what each one's URL is.\n\n`url` is the customer-facing URL routed through floo's gateway (or a\ncustom domain). `cloud_run_url` is the direct Cloud Run runtime URL —\nexposed so agents can debug deploy issues without scraping deploy logs;\nclients should always hit `url`, not `cloud_run_url`."},"ServiceType":{"type":"string","enum":["web","api","worker","cron","database","cache","storage"],"title":"ServiceType","description":"Type of service within an app."},"SessionListItem":{"properties":{"public_id":{"type":"string","format":"uuid","title":"Public Id"},"session_type":{"type":"string","title":"Session Type"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["public_id","session_type","email","created_at","last_seen_at","expires_at"],"title":"SessionListItem","description":"A single session in the list response."},"SessionListResponse":{"properties":{"sessions":{"items":{"$ref":"#/components/schemas/SessionListItem"},"type":"array","title":"Sessions"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["sessions","total"],"title":"SessionListResponse","description":"Response for GET /v1/auth/sessions."},"SetEnvVarRequest":{"properties":{"key":{"type":"string","maxLength":255,"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","title":"Key"},"value":{"type":"string","maxLength":10000,"title":"Value"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"is_secret":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Secret"}},"type":"object","required":["key","value"],"title":"SetEnvVarRequest","description":"Request body for setting an environment variable, alone or in an import.\n\n``value`` being required is load-bearing for the write-only contract\n(#1018): there is no metadata-only mutation, so ``is_secret`` can never be\nflipped without supplying a brand-new value — the old secret value stays\nunreachable by construction. Pinned by\n``tests/test_env_var_wire_boundary.py``."},"SignedUrlRequest":{"properties":{"object_path":{"type":"string","maxLength":1024,"minLength":1,"title":"Object Path","description":"Object path within the bucket (1-1024 characters; no leading slash, backslash, control characters, or empty, '.' or '..' segments). PUT/POST paths must start with 'uploads/'."},"method":{"type":"string","enum":["GET","PUT","POST"],"title":"Method","description":"Access method. GET returns a signed URL; PUT/POST returns a signed POST upload policy.","default":"GET"},"expiration_seconds":{"type":"integer","maximum":3600.0,"minimum":60.0,"title":"Expiration Seconds","description":"Expiration in seconds (60-3600 for GET; 60-900 for PUT/POST). Default: 900.","default":900},"content_type":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Content Type","description":"Required for PUT/POST; at most 255 characters and no control characters."},"max_bytes":{"anyOf":[{"type":"integer","maximum":104857600.0,"minimum":1.0},{"type":"null"}],"title":"Max Bytes","description":"Only valid for PUT/POST upload policies; 1-104857600 bytes (100 MiB). Defaults to 10485760 bytes (10 MiB)."}},"type":"object","required":["object_path"],"title":"SignedUrlRequest","description":"Request body for generating a signed URL."},"SignedUrlResponse":{"properties":{"url":{"type":"string","minLength":1,"title":"Url"},"method":{"type":"string","enum":["GET","POST"],"title":"Method"},"expires_in_seconds":{"type":"integer","minimum":0.0,"title":"Expires In Seconds"},"object_path":{"type":"string","minLength":1,"title":"Object Path"},"bucket":{"type":"string","minLength":1,"title":"Bucket"},"fields":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Fields"},"max_bytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Bytes"}},"type":"object","required":["url","method","expires_in_seconds","object_path","bucket"],"title":"SignedUrlResponse","description":"Response for a generated signed URL."},"SigningSecretResponse":{"properties":{"signing_secret":{"type":"string","title":"Signing Secret"}},"type":"object","required":["signing_secret"],"title":"SigningSecretResponse","description":"Response for revealing or rotating a signing secret."},"SpendCapPolicy":{"type":"string","enum":["off","alerts_only","freeze_new_spend","hard_stop"],"title":"SpendCapPolicy","description":"How floo should react when an org reaches its spend cap."},"SpendCapRequest":{"properties":{"spend_cap":{"type":"integer","maximum":2147483647.0,"minimum":0.0,"title":"Spend Cap","description":"Monthly spend cap in cents. 0 = no cap."},"policy":{"anyOf":[{"$ref":"#/components/schemas/SpendCapPolicy"},{"type":"null"}]}},"type":"object","required":["spend_cap"],"title":"SpendCapRequest","description":"Request to set the org spend cap."},"SpendCapResponse":{"properties":{"spend_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spend Cap"},"policy":{"$ref":"#/components/schemas/SpendCapPolicy"}},"type":"object","required":["spend_cap","policy"],"title":"SpendCapResponse","description":"Response for spend cap. None means no cap has been configured."},"StorageObjectResponse":{"properties":{"name":{"type":"string","minLength":1,"title":"Name"},"size_bytes":{"type":"integer","minimum":0.0,"title":"Size Bytes"},"size_human":{"type":"string","minLength":1,"title":"Size Human"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"}},"type":"object","required":["name","size_bytes","size_human"],"title":"StorageObjectResponse","description":"Summary for one object in a managed storage bucket."},"StorageObjectRestoreRequest":{"properties":{"object_path":{"type":"string","maxLength":1024,"minLength":1,"title":"Object Path","description":"Object path within bucket (no leading slash, no '..' traversal)."},"generation":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[0-9]+$","title":"Generation","description":"GCS generation id to restore."}},"type":"object","required":["object_path","generation"],"title":"StorageObjectRestoreRequest","description":"Request body for restoring one storage object generation."},"StorageObjectRestoreResponse":{"properties":{"bucket_name":{"type":"string","minLength":1,"title":"Bucket Name"},"object_path":{"type":"string","minLength":1,"title":"Object Path"},"restored_generation":{"type":"string","minLength":1,"title":"Restored Generation"},"live_generation":{"type":"string","minLength":1,"title":"Live Generation"},"size_bytes":{"type":"integer","minimum":0.0,"title":"Size Bytes"},"size_human":{"type":"string","minLength":1,"title":"Size Human"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"}},"type":"object","required":["bucket_name","object_path","restored_generation","live_generation","size_bytes","size_human"],"title":"StorageObjectRestoreResponse","description":"Response after restoring a storage object generation."},"StorageObjectVersionResponse":{"properties":{"object_path":{"type":"string","minLength":1,"title":"Object Path"},"generation":{"type":"string","minLength":1,"title":"Generation"},"is_live":{"type":"boolean","title":"Is Live"},"size_bytes":{"type":"integer","minimum":0.0,"title":"Size Bytes"},"size_human":{"type":"string","minLength":1,"title":"Size Human"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"etag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Etag"}},"type":"object","required":["object_path","generation","is_live","size_bytes","size_human"],"title":"StorageObjectVersionResponse","description":"One restorable GCS object generation."},"StorageObjectVersionsResponse":{"properties":{"bucket_name":{"type":"string","minLength":1,"title":"Bucket Name"},"object_path":{"type":"string","minLength":1,"title":"Object Path"},"versions":{"items":{"$ref":"#/components/schemas/StorageObjectVersionResponse"},"type":"array","title":"Versions"},"total_returned":{"type":"integer","minimum":0.0,"title":"Total Returned"},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","required":["bucket_name","object_path","versions","total_returned"],"title":"StorageObjectVersionsResponse","description":"Response for listing restorable generations for one object."},"StorageObjectsResponse":{"properties":{"env":{"type":"string","enum":["dev","prod"],"title":"Env"},"bucket_name":{"type":"string","minLength":1,"title":"Bucket Name"},"prefix":{"type":"string","title":"Prefix","default":""},"objects":{"items":{"$ref":"#/components/schemas/StorageObjectResponse"},"type":"array","title":"Objects"},"total_returned":{"type":"integer","minimum":0.0,"title":"Total Returned"},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","required":["env","bucket_name","objects","total_returned"],"title":"StorageObjectsResponse","description":"Response for listing bucket contents."},"StorageUsageResponse":{"properties":{"env":{"type":"string","enum":["dev","prod"],"title":"Env"},"bucket_name":{"type":"string","minLength":1,"title":"Bucket Name"},"object_count":{"type":"integer","minimum":0.0,"title":"Object Count"},"total_size_bytes":{"type":"integer","minimum":0.0,"title":"Total Size Bytes"},"total_size_human":{"type":"string","minLength":1,"title":"Total Size Human"}},"type":"object","required":["env","bucket_name","object_count","total_size_bytes","total_size_human"],"title":"StorageUsageResponse","description":"Response for storage usage metrics."},"SubmitFeedbackRequest":{"properties":{"category":{"$ref":"#/components/schemas/FeedbackCategory"},"message":{"type":"string","maxLength":5000,"minLength":1,"title":"Message"},"source":{"$ref":"#/components/schemas/FeedbackSource","default":"dashboard"},"context":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Context"},"app_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Name"}},"type":"object","required":["category","message"],"title":"SubmitFeedbackRequest","description":"Request body for submitting feedback."},"SubmitSalesLeadRequest":{"properties":{"source":{"$ref":"#/components/schemas/SalesLeadSource","default":"landing"},"intent":{"$ref":"#/components/schemas/SalesLeadIntent","default":"enterprise_internal_tools"},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"company":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Company"},"phone":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Phone"},"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"team_size":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Team Size"},"use_case":{"anyOf":[{"type":"string","maxLength":3000},{"type":"null"}],"title":"Use Case"},"page_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Page Url"}},"type":"object","required":["email"],"title":"SubmitSalesLeadRequest","description":"Request body for submitting a sales lead."},"TableInfo":{"properties":{"name":{"type":"string","title":"Name"},"columns":{"items":{"$ref":"#/components/schemas/ColumnInfo"},"type":"array","title":"Columns"},"row_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Row Count"}},"type":"object","required":["name","columns"],"title":"TableInfo","description":"Describe table columns with an optional observed row count."},"TestWebhookResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success"],"title":"TestWebhookResponse","description":"Response from testing a webhook endpoint."},"TimeSeriesPoint":{"properties":{"period_start":{"type":"string","format":"date-time","title":"Period Start"},"request_count":{"type":"integer","title":"Request Count"},"error_count":{"type":"integer","title":"Error Count"},"error_rate":{"type":"number","title":"Error Rate"}},"type":"object","required":["period_start","request_count","error_count","error_rate"],"title":"TimeSeriesPoint","description":"A single data point in a time series."},"TopUser":{"properties":{"identity":{"type":"string","title":"Identity"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["identity","count"],"title":"TopUser","description":"A top user entry with identity and request count."},"TopologyComponentResponse":{"properties":{"declared":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Declared","default":"unknown"},"applied":{"anyOf":[{"type":"boolean"},{"type":"string","const":"unknown"}],"title":"Applied","default":"unknown"},"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"family":{"type":"string","enum":["application","managed"],"title":"Family"},"type":{"type":"string","enum":["web","api","worker","cron","database","cache","postgres","redis","storage"],"title":"Type"},"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["pending","deploying","running","failed","stopped","provisioning","ready","backing_up","restoring","deprovisioning","deprovision_failed"],"title":"Status"},"runtime_status":{"anyOf":[{"type":"string","enum":["running","starting","stopped","degraded"]},{"type":"null"}],"title":"Runtime Status"},"deploy_status":{"anyOf":[{"type":"string","enum":["idle","in_progress","succeeded","failed"]},{"type":"null"}],"title":"Deploy Status"},"active_deploy_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Deploy Step"},"ingress":{"anyOf":[{"type":"string","enum":["public","internal"]},{"type":"null"}],"title":"Ingress"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"cloud_run_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Run Url"},"image_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Uri"},"repo_full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Full Name"},"port":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"schedule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schedule"},"command":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Command"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout"},"linked_service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Linked Service Id"},"linked_service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Service Name"},"env_var_keys":{"items":{"type":"string"},"type":"array","title":"Env Var Keys"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"last_run_status":{"anyOf":[{"type":"string","enum":["success","failed","interrupted"]},{"type":"null"}],"title":"Last Run Status"}},"type":"object","required":["id","app_id","family","type","name","status","created_at","updated_at"],"title":"TopologyComponentResponse","description":"Normalized runtime component for the dashboard topology view."},"TriggerReparoRequest":{"properties":{"error_fingerprint":{"type":"string","maxLength":64,"minLength":1,"title":"Error Fingerprint"},"error_message":{"type":"string","maxLength":10000,"minLength":1,"title":"Error Message"},"stack_trace":{"anyOf":[{"type":"string","maxLength":100000},{"type":"null"}],"title":"Stack Trace"},"deploy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Deploy Id"}},"additionalProperties":false,"type":"object","required":["error_fingerprint","error_message"],"title":"TriggerReparoRequest","description":"Request body for manually triggering a Reparo event."},"UpdateAlertRuleRequest":{"properties":{"metric":{"anyOf":[{"$ref":"#/components/schemas/AlertMetric"},{"type":"null"}]},"operator":{"anyOf":[{"$ref":"#/components/schemas/AlertOperator"},{"type":"null"}]},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold"},"window_minutes":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":1.0},{"type":"null"}],"title":"Window Minutes"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"cooldown_minutes":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":1.0},{"type":"null"}],"title":"Cooldown Minutes"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"UpdateAlertRuleRequest","description":"Request body for updating an alert rule (all fields optional)."},"UpdateAppMembershipRequest":{"properties":{"role":{"$ref":"#/components/schemas/AppMembershipRole"}},"type":"object","required":["role"],"title":"UpdateAppMembershipRequest","description":"Change a tenant-app role without changing control-plane authority."},"UpdateAppRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":40,"minLength":2,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},{"type":"null"}],"title":"Name"},"access_mode":{"type":"string","enum":["public","accounts"],"default":"public"},"access_policy":{"anyOf":[{"$ref":"#/components/schemas/AccessPolicy"},{"type":"null"}]}},"type":"object","title":"UpdateAppRequest","description":"Request body for updating an app."},"UpdateEnvironmentRequest":{"properties":{"access_mode":{"anyOf":[{"type":"string","enum":["public","accounts"]},{"type":"null"}]}},"type":"object","title":"UpdateEnvironmentRequest","description":"Request body for updating an environment."},"UpdateEventRequest":{"properties":{"status":{"$ref":"#/components/schemas/ReparoEventStatus"}},"additionalProperties":false,"type":"object","required":["status"],"title":"UpdateEventRequest","description":"Request body for updating a Reparo event status.\n\n`extra='forbid'` rejects unknown fields — after the 2026-04-13 scope\ntightening, any client still sending `pr_url` now gets a 422 instead\nof a silent drop."},"UpdateMemberRoleRequest":{"properties":{"role":{"$ref":"#/components/schemas/OrgRole"}},"type":"object","required":["role"],"title":"UpdateMemberRoleRequest","description":"Request body for updating a member's role."},"UpdateNotificationPreferenceRequest":{"properties":{"category":{"$ref":"#/components/schemas/NotificationCategory"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["category","enabled"],"title":"UpdateNotificationPreferenceRequest","description":"Select a notification category and its desired enabled state."},"UpdateOrgRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string","maxLength":63,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},{"type":"null"}],"title":"Slug"},"logo_data_url":{"anyOf":[{"type":"string","maxLength":1500000},{"type":"null"}],"title":"Logo Data Url"}},"type":"object","title":"UpdateOrgRequest","description":"Request body for updating an organization."},"UpdateProfileRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"}},"type":"object","title":"UpdateProfileRequest","description":"Request body for updating user profile."},"UpdateReparoConfigRequest":{"properties":{"mode":{"$ref":"#/components/schemas/ReparoMode"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2048,"minLength":1},{"type":"null"}],"title":"Webhook Url"},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret"},"error_threshold":{"type":"integer","minimum":1.0,"title":"Error Threshold","default":5},"cooldown_minutes":{"type":"integer","minimum":1.0,"title":"Cooldown Minutes","default":15}},"additionalProperties":false,"type":"object","required":["mode"],"title":"UpdateReparoConfigRequest","description":"Request body for creating/updating Reparo configuration.\n\n`extra='forbid'` rejects unknown fields outright. This matters for the\n2026-04-13 scope tightening: old clients sending `auto_deploy=true` now\nget a 422 validation error instead of silently dropping the field and\nreturning 200 OK on a request the server cannot honor."},"UpdateWebhookEndpointRequest":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"events":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookEventType"},"type":"array","minItems":1},{"type":"null"}],"title":"Events"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UpdateWebhookEndpointRequest","description":"Request body for updating a webhook endpoint."},"UpgradeRequest":{"properties":{"plan":{"anyOf":[{"type":"string","enum":["paygo","team"]},{"type":"null"}],"title":"Plan"}},"type":"object","title":"UpgradeRequest","description":"Request to upgrade a plan or open billing portal.\n\nIf plan is None, opens the Stripe Customer Portal (must have existing customer).\nIf plan is set, creates a Checkout Session for new customers or Portal for existing."},"VisitorInsightsResponse":{"properties":{"period":{"type":"string","enum":["24h","7d","30d"],"title":"Period"},"unique_visitors":{"type":"integer","title":"Unique Visitors"},"total_pageviews":{"type":"integer","title":"Total Pageviews"},"total_custom_events":{"type":"integer","title":"Total Custom Events"},"time_series":{"items":{"$ref":"#/components/schemas/VisitorTimeSeriesPoint"},"type":"array","title":"Time Series"},"top_paths":{"items":{"$ref":"#/components/schemas/VisitorPathCount"},"type":"array","title":"Top Paths"},"top_referrers":{"items":{"$ref":"#/components/schemas/VisitorReferrerCount"},"type":"array","title":"Top Referrers"}},"type":"object","required":["period","unique_visitors","total_pageviews","total_custom_events","time_series","top_paths","top_referrers"],"title":"VisitorInsightsResponse","description":"Aggregated visitor insights for an app over a time window."},"VisitorPathCount":{"properties":{"path":{"type":"string","title":"Path"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["path","count"],"title":"VisitorPathCount","description":"Aggregated count of events for a single path."},"VisitorReferrerCount":{"properties":{"referrer":{"type":"string","title":"Referrer"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["referrer","count"],"title":"VisitorReferrerCount","description":"Aggregated count of visits from a single referrer."},"VisitorTimeSeriesPoint":{"properties":{"bucket_start":{"type":"string","format":"date-time","title":"Bucket Start"},"unique_visitors":{"type":"integer","title":"Unique Visitors"},"pageviews":{"type":"integer","title":"Pageviews"}},"type":"object","required":["bucket_start","unique_visitors","pageviews"],"title":"VisitorTimeSeriesPoint","description":"One bucket of the visitor time series chart."},"WaitlistRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"company":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Company"},"heard_from":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Heard From"}},"type":"object","required":["email"],"title":"WaitlistRequest","description":"Request body for joining the waitlist."},"WaitlistResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","email","created_at"],"title":"WaitlistResponse","description":"Response after joining the waitlist."},"WebhookChannelType":{"type":"string","enum":["slack","discord","google_chat"],"title":"WebhookChannelType","description":"Supported webhook channel types."},"WebhookDeliveryDetailResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"endpoint_id":{"type":"string","format":"uuid","title":"Endpoint Id"},"event":{"$ref":"#/components/schemas/WebhookEventType"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatus"},"attempt_count":{"type":"integer","minimum":0.0,"title":"Attempt Count"},"last_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status Code"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"next_retry_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Retry At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"}},"type":"object","required":["id","endpoint_id","event","status","attempt_count","last_status_code","last_error","next_retry_at","completed_at","created_at","payload"],"title":"WebhookDeliveryDetailResponse","description":"Response for a single webhook delivery with full payload."},"WebhookDeliveryListResponse":{"properties":{"deliveries":{"items":{"$ref":"#/components/schemas/WebhookDeliveryResponse"},"type":"array","title":"Deliveries"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["deliveries","total"],"title":"WebhookDeliveryListResponse","description":"Response for listing webhook deliveries."},"WebhookDeliveryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"endpoint_id":{"type":"string","format":"uuid","title":"Endpoint Id"},"event":{"$ref":"#/components/schemas/WebhookEventType"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatus"},"attempt_count":{"type":"integer","minimum":0.0,"title":"Attempt Count"},"last_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status Code"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"next_retry_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Retry At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","endpoint_id","event","status","attempt_count","last_status_code","last_error","next_retry_at","completed_at","created_at"],"title":"WebhookDeliveryResponse","description":"Response for a single webhook delivery."},"WebhookDeliveryStatus":{"type":"string","enum":["pending","succeeded","failed","retrying"],"title":"WebhookDeliveryStatus","description":"Status of a webhook delivery attempt."},"WebhookEndpointCreateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"channel":{"type":"string","title":"Channel"},"url":{"type":"string","title":"Url"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"signing_secret":{"type":"string","title":"Signing Secret"}},"type":"object","required":["id","org_id","channel","url","label","events","is_active","created_at","updated_at","signing_secret"],"title":"WebhookEndpointCreateResponse","description":"Response for creating a webhook endpoint — includes the signing secret (one-time)."},"WebhookEndpointListResponse":{"properties":{"webhooks":{"items":{"$ref":"#/components/schemas/WebhookEndpointResponse"},"type":"array","title":"Webhooks"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["webhooks","total"],"title":"WebhookEndpointListResponse","description":"Response for listing webhook endpoints."},"WebhookEndpointResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"channel":{"type":"string","title":"Channel"},"url":{"type":"string","title":"Url"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","org_id","channel","url","label","events","is_active","created_at","updated_at"],"title":"WebhookEndpointResponse","description":"Response for a single webhook endpoint."},"WebhookEventType":{"type":"string","enum":["deploy.succeeded","deploy.failed"],"title":"WebhookEventType","description":"Events that can trigger webhook notifications."},"WhoamiResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"waitlisted":{"type":"boolean","title":"Waitlisted"},"control_plane_access":{"type":"boolean","title":"Control Plane Access"},"effective_scope":{"anyOf":[{"$ref":"#/components/schemas/KeyScope"},{"type":"null"}]}},"type":"object","required":["user_id","email","name","waitlisted","control_plane_access"],"title":"WhoamiResponse","description":"Response from the whoami endpoint."}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A `floo_` API key."}},"parameters":{"X-Floo-Org-Id":{"name":"X-Floo-Org-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Organization to act in; defaults to the one joined most recently."}}}}