{"openapi":"3.0.3","info":{"title":"Rock8Cloud API","description":"REST API for the Rock8Cloud deployment platform.\n\n## Authentication\nTwo methods are accepted, both as `Authorization: Bearer <token>`:\n- **API key** - a `vhk_...` token created in Settings -> API Keys. Scoped to a single organization. Send it as-is.\n- **OAuth 2.0** - authorization-code (with PKCE), via the `oauth2` security scheme below. Clients can self-register (RFC 7591) and discover endpoints from `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server` (RFC 9728 / RFC 8414). An OAuth token is not bound to one organization, so requests must also send `X-Organization-Id: <organizationId>` to select which organization the call acts on.\n\n## Scopes\nResource reads require `read:<resource>`. Mutations require both `read:<resource>` and `write:<resource>`, including previews served over POST. Nested resources may require additional parent-resource scopes. Session-cookie callers are checked against organization role capabilities instead. An endpoint's description lists its resource scopes and notable role restrictions.\n\n## Versioning\nSend `Rock8cloud-Version: 2026-10-01` to pin a version. Without the header a request is served by the latest version. An unsupported value returns 400 with code `UNSUPPORTED_API_VERSION`. Every response carries the `Rock8cloud-Version` it was served with. Breaking changes ship only as a new dated version, and a version stays supported for at least 6 months after its successor is released. Deprecated operations send `Deprecation` and `Sunset` headers before removal. Adding operations, optional parameters, response fields, enum values or error codes is not breaking, so ignore unknown fields.\n\n## Errors\nApplication errors use the `Error` schema: JSON `{ \"error\": string, \"code\": string, \"hint\"?: string, \"details\"?: array }`. Branch on `code`, not on the message. Some legacy handlers omit `code` or add fields, and authentication-provider endpoints use other shapes, so inspect the HTTP status and the operation's documented payload. Status codes include 400 (bad input), 401 (missing/invalid credential), 402 (usage limit exceeded), 403 (insufficient scope/role), 404 (not found), 409 (conflict), 422 (validation failed), 429 (rate limited), 500 (internal error), 502 (upstream integration error), and 503 (integration unavailable).\n\n## MCP\nAgents can also drive this API over the Model Context Protocol at `/mcp` (Streamable HTTP, OAuth-only). Its server card is at `/mcp/server-card`.","version":"2026-10-01"},"servers":[{"url":"https://app.rock8.cloud"}],"tags":[{"name":"Organizations","description":"Organizations, members, roles, billing and usage."},{"name":"Users","description":"The authenticated user, preferences and sessions."},{"name":"Projects","description":"Projects group services, environments and databases."},{"name":"Services","description":"Deployable services: repos, images, env vars, scaling, URLs."},{"name":"Custom domains","description":"Custom hostnames on services and their verification."},{"name":"Deployments","description":"Builds, deployments, rollbacks, logs and metrics."},{"name":"Jobs","description":"Background jobs and their progress."},{"name":"Databases","description":"Managed PostgreSQL, Dragonfly (Redis) and their credentials."},{"name":"Object storage","description":"S3 buckets, credentials and objects."},{"name":"Pages","description":"Published pages (artifacts) on name.rock8cloud.page."},{"name":"Applications","description":"One-click applications deployed from a pre-built image."},{"name":"Uptime monitors","description":"HTTP uptime checks and their status history."},{"name":"Branches","description":"Git branches and preview environments."},{"name":"GitHub","description":"GitHub App installations and repositories."},{"name":"Workflows","description":"Deploy-on-push, preview and other platform workflows."},{"name":"Agent workflows","description":"Triggers that run agents on repository events."},{"name":"Agents","description":"Cloud agent sessions and runs in isolated sandboxes."},{"name":"Custom agents","description":"User-defined agents and their runs."},{"name":"Code review","description":"AI code reviews on pull requests."},{"name":"Blueprints","description":"Ready-made stacks deployable in one call."},{"name":"API keys","description":"Scoped API keys and OAuth client consents."},{"name":"Notification channels","description":"Slack, Discord, email and webhook notifications."},{"name":"Audit log","description":"Who did what, when, in an organization."},{"name":"Build metrics","description":"Build duration and cache statistics."},{"name":"Chat platforms","description":"Slack and Discord bot connections."},{"name":"Jira","description":"Jira Forge app integration and the A2A agent endpoint."},{"name":"Service status","description":"Live runtime status of services, deployments and projects."},{"name":"Organization events","description":"Server-sent event streams for an organization."},{"name":"Health","description":"Liveness and readiness probes."},{"name":"Discovery","description":"Machine-readable metadata: OAuth, MCP server card, API catalog."},{"name":"MCP","description":"The Model Context Protocol endpoint."},{"name":"Auth","description":"Sign-in, OAuth provider and session endpoints."},{"name":"Access","description":"Instance access requests and invitations."},{"name":"Signup","description":"Signup intents captured before an account exists."},{"name":"Bug reports","description":"In-app bug reports and the bug bounty leaderboard."}],"externalDocs":{"url":"https://docs.rock8.cloud/docs/guides/api-keys","description":"API keys and scopes"},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable message."},"code":{"type":"string","description":"Stable machine-readable code, e.g. NOT_FOUND, INSUFFICIENT_SCOPE, VALIDATION_ERROR, UNSUPPORTED_API_VERSION."},"hint":{"type":"string","description":"How to fix the request, when known."},"details":{"type":"array","items":{"type":"object"},"description":"Failing fields of a 422 validation error."}}}},"responses":{"BadRequest":{"description":"Malformed request, or an unsupported API version header (code UNSUPPORTED_API_VERSION).","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing or invalid credential.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The credential lacks the required scope or role.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"The resource or route does not exist.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationFailed":{"description":"The request failed validation. `details` lists the failing fields.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Unexpected server error.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":{"ApiVersion":{"name":"Rock8cloud-Version","in":"header","required":false,"description":"API version to serve the request with. Omit it for the latest version.","schema":{"type":"string","enum":["2026-10-01"],"default":"2026-10-01"}}},"headers":{"ApiVersion":{"description":"API version that served the request.","schema":{"type":"string"}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key (`vhk_...`) bound to one organization, or user OAuth 2.0 access token with X-Organization-Id selecting the organization."},"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://app.rock8.cloud/auth/api/oauth2/authorize","tokenUrl":"https://app.rock8.cloud/auth/api/oauth2/token","refreshUrl":"https://app.rock8.cloud/auth/api/oauth2/token","scopes":{"openid":"OpenID","profile":"Profile","email":"Email","offline_access":"Offline access (refresh tokens)","read:organization":"Read organization","write:organization":"Write organization","read:projects":"Read projects","write:projects":"Write projects","read:deployments":"Read deployments","write:deployments":"Write deployments","read:services":"Read services","write:services":"Write services","read:uptime-monitors":"Read uptime monitors","write:uptime-monitors":"Write uptime monitors","read:databases":"Read databases","write:databases":"Write databases","read:workflows":"Read workflows","write:workflows":"Write workflows","read:code-reviews":"Read code reviews","write:code-reviews":"Write code reviews","read:ai-coder":"Read AI coder","write:ai-coder":"Write AI coder","read:ai-sandbox-coder":"Read AI sandbox coder","write:ai-sandbox-coder":"Write AI sandbox coder","read:blueprints":"View blueprints","write:blueprints":"Deploy blueprints","read:agents":"Read agent sessions","write:agents":"Run agent sessions","agent:spawn":"Spawn sub-agent sessions","read:s3-objects":"Read S3 bucket objects","write:s3-objects":"Write S3 bucket objects","read:artifacts":"Read published artifacts","write:artifacts":"Publish artifacts","read:ai-gateway":"Read AI Gateway organizations and balances","write:ai-gateway":"Manage AI Gateway organizations, keys and top-ups"}}}}}},"security":[{"bearerAuth":[]},{"oauth2":[]}],"paths":{"/.well-known/openid-configuration":{"get":{"operationId":"getOpenIdConfiguration","security":[],"summary":"OpenID Connect discovery document","description":"OpenID Connect discovery metadata for this instance's authorization server.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OpenIdConfiguration","additionalProperties":true,"type":"object","required":["issuer","authorization_endpoint","token_endpoint","response_types_supported","response_modes_supported","grant_types_supported","code_challenge_methods_supported","userinfo_endpoint","end_session_endpoint","subject_types_supported","id_token_signing_alg_values_supported","claims_supported","prompt_values_supported"],"properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"jwks_uri":{"type":"string"},"registration_endpoint":{"description":"Dynamic client registration endpoint (RFC 7591).","type":"string"},"introspection_endpoint":{"type":"string"},"revocation_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string"}},"response_types_supported":{"type":"array","items":{"type":"string"}},"response_modes_supported":{"type":"array","items":{"type":"string"}},"grant_types_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"introspection_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"revocation_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}},"authorization_response_iss_parameter_supported":{"type":"boolean"},"dpop_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"backchannel_logout_supported":{"type":"boolean"},"backchannel_logout_session_supported":{"type":"boolean"},"userinfo_endpoint":{"type":"string"},"end_session_endpoint":{"type":"string"},"subject_types_supported":{"type":"array","items":{"type":"string"}},"id_token_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"claims_supported":{"type":"array","items":{"type":"string"}},"claims_parameter_supported":{"type":"boolean"},"prompt_values_supported":{"type":"array","items":{"type":"string"}},"acr_values_supported":{"type":"array","items":{"type":"string"}},"request_parameter_supported":{"type":"boolean"},"request_uri_parameter_supported":{"type":"boolean"}}}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"operationId":"getOAuthAuthorizationServerMetadata","security":[],"summary":"OAuth authorization server metadata","description":"RFC 8414 authorization server metadata: authorize/token/registration endpoints and supported scopes.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OAuthAuthorizationServerMetadata","additionalProperties":true,"type":"object","required":["issuer","authorization_endpoint","token_endpoint","response_types_supported","response_modes_supported","grant_types_supported","code_challenge_methods_supported"],"properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"jwks_uri":{"type":"string"},"registration_endpoint":{"description":"Dynamic client registration endpoint (RFC 7591).","type":"string"},"introspection_endpoint":{"type":"string"},"revocation_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string"}},"response_types_supported":{"type":"array","items":{"type":"string"}},"response_modes_supported":{"type":"array","items":{"type":"string"}},"grant_types_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"introspection_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"revocation_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}},"authorization_response_iss_parameter_supported":{"type":"boolean"},"dpop_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"backchannel_logout_supported":{"type":"boolean"},"backchannel_logout_session_supported":{"type":"boolean"}}}}}}}}},"/.well-known/oauth-authorization-server/auth/api":{"get":{"operationId":"getOAuthAuthorizationServerMetadataAuthApi","security":[],"summary":"OAuth authorization server metadata (/auth/api issuer path)","description":"Same RFC 8414 metadata as GET /.well-known/oauth-authorization-server, at the path RFC 8414 discovery expects when the issuer URL includes /auth/api.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OAuthAuthorizationServerMetadata","additionalProperties":true,"type":"object","required":["issuer","authorization_endpoint","token_endpoint","response_types_supported","response_modes_supported","grant_types_supported","code_challenge_methods_supported"],"properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"jwks_uri":{"type":"string"},"registration_endpoint":{"description":"Dynamic client registration endpoint (RFC 7591).","type":"string"},"introspection_endpoint":{"type":"string"},"revocation_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string"}},"response_types_supported":{"type":"array","items":{"type":"string"}},"response_modes_supported":{"type":"array","items":{"type":"string"}},"grant_types_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"introspection_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"revocation_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}},"authorization_response_iss_parameter_supported":{"type":"boolean"},"dpop_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"backchannel_logout_supported":{"type":"boolean"},"backchannel_logout_session_supported":{"type":"boolean"}}}}}}}}},"/.well-known/openid-configuration/auth/api":{"get":{"operationId":"getOpenIdConfigurationAuthApi","security":[],"summary":"OpenID Connect discovery document (/auth/api issuer path)","description":"Same OpenID Connect metadata as GET /.well-known/openid-configuration, at the path expected when the issuer URL includes /auth/api.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OpenIdConfiguration","additionalProperties":true,"type":"object","required":["issuer","authorization_endpoint","token_endpoint","response_types_supported","response_modes_supported","grant_types_supported","code_challenge_methods_supported","userinfo_endpoint","end_session_endpoint","subject_types_supported","id_token_signing_alg_values_supported","claims_supported","prompt_values_supported"],"properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"jwks_uri":{"type":"string"},"registration_endpoint":{"description":"Dynamic client registration endpoint (RFC 7591).","type":"string"},"introspection_endpoint":{"type":"string"},"revocation_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string"}},"response_types_supported":{"type":"array","items":{"type":"string"}},"response_modes_supported":{"type":"array","items":{"type":"string"}},"grant_types_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"introspection_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"revocation_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}},"authorization_response_iss_parameter_supported":{"type":"boolean"},"dpop_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"backchannel_logout_supported":{"type":"boolean"},"backchannel_logout_session_supported":{"type":"boolean"},"userinfo_endpoint":{"type":"string"},"end_session_endpoint":{"type":"string"},"subject_types_supported":{"type":"array","items":{"type":"string"}},"id_token_signing_alg_values_supported":{"type":"array","items":{"type":"string"}},"claims_supported":{"type":"array","items":{"type":"string"}},"claims_parameter_supported":{"type":"boolean"},"prompt_values_supported":{"type":"array","items":{"type":"string"}},"acr_values_supported":{"type":"array","items":{"type":"string"}},"request_parameter_supported":{"type":"boolean"},"request_uri_parameter_supported":{"type":"boolean"}}}}}}}}},"/auth/api/oauth2/register":{"post":{"operationId":"registerOAuthClient","security":[],"summary":"Register an OAuth client","description":"RFC 7591 dynamic client registration for the OAuth provider. Used by MCP clients to self-register before the authorization-code flow.","tags":["Auth"],"responses":{"201":{"description":"OAuth client registered.","content":{"application/json":{"schema":{"title":"OAuthClientRegistration","additionalProperties":true,"type":"object","required":["client_id","redirect_uris"],"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"client_id_issued_at":{"description":"Unix time in seconds.","type":"number"},"client_secret_expires_at":{"description":"Unix time in seconds. 0 means the secret never expires.","type":"number"},"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string"},"scope":{"description":"Space-separated scopes allowed for the client.","type":"string"},"application_type":{"nullable":true,"anyOf":[{"anyOf":[{"const":"web","type":"string"},{"const":"native","type":"string"}]},{"type":"null"}]}}}}}}}}},"/api/health":{"get":{"operationId":"getHealth","security":[],"summary":"Liveness and readiness probe","description":"Checks the database connection. Returns 200 `{ status: \"ok\" }` or 503 `{ status: \"unhealthy\" }`.","tags":["Health"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"HealthOk","type":"object","required":["status"],"properties":{"status":{"enum":["ok"],"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"The database check failed.","content":{"application/json":{"schema":{"title":"HealthUnhealthy","type":"object","required":["status"],"properties":{"status":{"enum":["unhealthy"],"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/.well-known/oauth-protected-resource":{"get":{"operationId":"getOAuthProtectedResourceMetadata","security":[],"summary":"OAuth protected resource metadata","description":"RFC 9728 protected resource metadata for the REST API: lists the authorization server(s) and scopes.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OAuthProtectedResourceMetadata","type":"object","required":["resource","authorization_servers","bearer_methods_supported","scopes_supported"],"properties":{"resource":{"description":"Protected resource identifier: the API origin, or the MCP endpoint URL on the /mcp variant.","type":"string"},"authorization_servers":{"type":"array","items":{"type":"string"}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}}}}}}}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"operationId":"getOAuthProtectedResourceMetadataMcp","security":[],"summary":"OAuth protected resource metadata (MCP endpoint)","description":"RFC 9728 protected resource metadata for the MCP endpoint, the URL its WWW-Authenticate challenge points to. `resource` is the MCP endpoint URL, as RFC 9728 requires for a path-suffixed metadata URL.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OAuthProtectedResourceMetadata","type":"object","required":["resource","authorization_servers","bearer_methods_supported","scopes_supported"],"properties":{"resource":{"description":"Protected resource identifier: the API origin, or the MCP endpoint URL on the /mcp variant.","type":"string"},"authorization_servers":{"type":"array","items":{"type":"string"}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}}}}}}}}}},"/.well-known/integrations.json":{"get":{"operationId":"getIntegrationsManifest","security":[],"summary":"integrations.sh manifest","description":"Machine-readable integrations.sh v3 declaration: credentials and surfaces (REST API, MCP) an agent uses to connect to Rock8Cloud.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"IntegrationsManifest","type":"object","required":["version","summary","credentials","surfaces"],"properties":{"version":{"type":"number"},"summary":{"type":"string"},"credentials":{"type":"object","patternProperties":{"^(.*)$":{"type":"object","required":["type","label","setup"],"properties":{"type":{"type":"string"},"label":{"type":"string"},"generateUrl":{"type":"string"},"setup":{"type":"string"}}}}},"surfaces":{"type":"array","items":{"type":"object","required":["type","slug","name","url","docs","basis","auth"],"properties":{"type":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"spec":{"type":"string"},"transports":{"type":"array","items":{"type":"string"}},"docs":{"type":"string"},"basis":{"type":"object","required":["via","source"],"properties":{"via":{"type":"string"},"source":{"type":"string"}}},"auth":{"type":"object","required":["status","entries"],"properties":{"status":{"type":"string"},"entries":{"type":"array","items":{"type":"object","required":["use","basis"],"properties":{"use":{"type":"array","items":{"type":"object","required":["id","mechanics"],"properties":{"id":{"type":"string"},"mechanics":{"type":"object","patternProperties":{"^(.*)$":{"type":"string"}}}}}},"basis":{"type":"object","required":["via","source"],"properties":{"via":{"type":"string"},"source":{"type":"string"}}}}}}}}}}}}}}}}}}},"/mcp/server-card":{"get":{"operationId":"getMcpServerCard","security":[],"summary":"MCP server card","description":"Machine-readable MCP server card per the SEP-2127 server-card schema, served at the reserved <streamable-http-url>/server-card location.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/mcp-server-card+json":{"schema":{"title":"McpServerCard","type":"object","required":["$schema","name","version","title","description","websiteUrl","url","serverUrl","transport","remotes","_meta"],"properties":{"$schema":{"type":"string"},"name":{"type":"string"},"version":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"websiteUrl":{"type":"string"},"url":{"type":"string"},"serverUrl":{"type":"string"},"transport":{"type":"string"},"remotes":{"type":"array","items":{"type":"object","required":["type","url","supportedProtocolVersions"],"properties":{"type":{"type":"string"},"url":{"type":"string"},"supportedProtocolVersions":{"type":"array","items":{"type":"string"}}}}},"_meta":{"type":"object","patternProperties":{"^(.*)$":{"type":"object","patternProperties":{"^(.*)$":{"type":"string"}}}}}}}}}}}}},"/.well-known/mcp/server-card.json":{"get":{"operationId":"getMcpServerCardLegacy","security":[],"summary":"MCP server card (legacy well-known path)","description":"Same MCP server card as GET /mcp/server-card, kept at the legacy .well-known/mcp/server-card.json location so the two cannot drift.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"McpServerCard","type":"object","required":["$schema","name","version","title","description","websiteUrl","url","serverUrl","transport","remotes","_meta"],"properties":{"$schema":{"type":"string"},"name":{"type":"string"},"version":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"websiteUrl":{"type":"string"},"url":{"type":"string"},"serverUrl":{"type":"string"},"transport":{"type":"string"},"remotes":{"type":"array","items":{"type":"object","required":["type","url","supportedProtocolVersions"],"properties":{"type":{"type":"string"},"url":{"type":"string"},"supportedProtocolVersions":{"type":"array","items":{"type":"string"}}}}},"_meta":{"type":"object","patternProperties":{"^(.*)$":{"type":"object","patternProperties":{"^(.*)$":{"type":"string"}}}}}}}}}}}}},"/.well-known/mcp":{"get":{"operationId":"getMcpManifest","security":[],"summary":"MCP discovery manifest","description":"SEP-1960 manifest: the streamable HTTP MCP endpoint, its OAuth 2.0 endpoints and dynamic client registration, and a link to the server card.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"McpManifest","type":"object","required":["mcp_version","server_name","server_version","url","serverUrl","transport","endpoints","capabilities","authentication","registration","server_card","documentation","terms_of_service","privacy_policy"],"properties":{"mcp_version":{"type":"string"},"server_name":{"type":"string"},"server_version":{"type":"string"},"url":{"type":"string"},"serverUrl":{"type":"string"},"transport":{"type":"string"},"endpoints":{"type":"object","required":["streamable_http"],"properties":{"streamable_http":{"type":"string"}}},"capabilities":{"type":"object","required":["tools","prompts","resources","sampling","roots"],"properties":{"tools":{"type":"boolean"},"prompts":{"type":"boolean"},"resources":{"type":"boolean"},"sampling":{"type":"boolean"},"roots":{"type":"boolean"}}},"authentication":{"type":"object","required":["required","methods","oauth2"],"properties":{"required":{"type":"boolean"},"methods":{"type":"array","items":{"type":"string"}},"oauth2":{"type":"object","required":["authorization_endpoint","token_endpoint","scopes_supported"],"properties":{"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string"}}}}}},"registration":{"type":"object","required":["dynamic_registration","registration_endpoint"],"properties":{"dynamic_registration":{"type":"boolean"},"registration_endpoint":{"type":"string"}}},"server_card":{"type":"string"},"documentation":{"type":"string"},"terms_of_service":{"type":"string"},"privacy_policy":{"type":"string"}}}}}}}}},"/.well-known/api-catalog":{"get":{"operationId":"getApiCatalog","security":[],"summary":"RFC 9727 API catalog","description":"RFC 9264 linkset whose first entry lists the REST API and MCP surfaces as items, followed by each surface with its spec and documentation links. HEAD returns the api-catalog Link header.","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/linkset+json":{"schema":{"title":"ApiCatalog","type":"object","required":["linkset"],"properties":{"linkset":{"type":"array","items":{"type":"object","required":["anchor"],"properties":{"anchor":{"type":"string"},"item":{"type":"array","items":{"type":"object","required":["href"],"properties":{"href":{"type":"string"},"type":{"type":"string"}}}},"profile":{"type":"array","items":{"type":"object","required":["href"],"properties":{"href":{"type":"string"},"type":{"type":"string"}}}},"service-desc":{"type":"array","items":{"type":"object","required":["href"],"properties":{"href":{"type":"string"},"type":{"type":"string"}}}},"service-doc":{"type":"array","items":{"type":"object","required":["href"],"properties":{"href":{"type":"string"},"type":{"type":"string"}}}}}}}}}}}}}}},"/api/user":{"get":{"operationId":"getCurrentUser","summary":"Get the current user","description":"Returns the authenticated user id, name and image. Requires a session or bearer token.","tags":["Users"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CurrentUser","type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]},"delete":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteCurrentUser","summary":"Delete the current user","description":"Soft-deletes the authenticated user profile and their sessions, memberships and accounts, after the caller types the exact confirmation phrase \"delete my profile\". Emits a user:delete audit log in every organization the user belonged to. Requires a session or bearer token. Responds 400 when the confirmation phrase does not match.","tags":["Users"],"responses":{"204":{"description":"User deleted. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirmation"],"properties":{"confirmation":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["confirmation"],"properties":{"confirmation":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["confirmation"],"properties":{"confirmation":{"type":"string"}}}}}}}},"/api/user/marketing-trial-eligible":{"get":{"operationId":"getCurrentUserMarketingTrialEligibility","summary":"Check the current user marketing trial eligibility","description":"Returns whether the authenticated user is still eligible for the marketing trial, read fresh from the database to avoid the session cache. Requires a session or bearer token.","tags":["Users"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"MarketingTrialEligibility","type":"object","required":["eligible"],"properties":{"eligible":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/organization/list":{"get":{"operationId":"listOrganizations","summary":"List the current user organizations","description":"Lists every organization the authenticated user belongs to, excluding soft-deleted ones. Registered ahead of the membership guard so org discovery stays reachable even when the active organization is stale. Requires the read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationList","type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"title":"Organization","type":"object","required":["id","name","slug","role","tier","subscriptionStatus"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"role":{"type":"string","enum":["owner","member","reader"]},"tier":{"nullable":true,"type":"string","enum":["pluto","mercury","earth","neptune","enterprise"]},"subscriptionStatus":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/organization/{orgId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteOrganization","summary":"Delete an organization","description":"Soft-deletes an organization identified by its id: cancels queued custom-agent runs, revokes their keys, cancels Stripe subscriptions, retires the AI Gateway keys issued for its projects and hard-deletes them. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers.","tags":["Organizations"],"responses":{"204":{"description":"Organization deleted. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/ai-config":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationAiConfig","summary":"Get an organization AI config","description":"Returns whether AI features are enabled for the organization and the resolved availability of each AI agent feature. The id must be the caller active organization. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAiConfigSummary","type":"object","required":["aiFeaturesEnabled","resolvedAgents"],"properties":{"aiFeaturesEnabled":{"type":"boolean"},"resolvedAgents":{"type":"array","items":{"type":"object","required":["agent","enabled"],"properties":{"agent":{"type":"string","enum":["code-review","sandbox-coder","changelog","dockerfile-init"]},"enabled":{"type":"boolean"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateOrganizationAiConfig","summary":"Update an organization AI config","description":"Sets the organization-wide AI features master toggle. The id must be the caller active organization. Requires read:organization and write:organization scopes for bearer callers, canManageOrganization for session callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAiConfig","type":"object","required":["id","organizationId","aiFeaturesEnabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"aiFeaturesEnabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["aiFeaturesEnabled"],"properties":{"aiFeaturesEnabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["aiFeaturesEnabled"],"properties":{"aiFeaturesEnabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["aiFeaturesEnabled"],"properties":{"aiFeaturesEnabled":{"type":"boolean"}}}}}}}},"/api/organization/{orgId}/ai-spend":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"anyOf":[{"enum":["24h"],"type":"string"},{"enum":["7d"],"type":"string"},{"enum":["30d"],"type":"string"}]},"in":"query","name":"window","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationAiSpend","summary":"Get an organization AI spend rollup","description":"Returns bucketed EUR AI spend rollups for the organization over a time window (24h, 7d or 30d, default 7d). The id must be the caller active organization. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAiSpend","type":"object","required":["totals","byFeature","byModel","byFeatureModel","byProject","seriesByModel"],"properties":{"totals":{"type":"object","required":["runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}},"byFeature":{"type":"array","items":{"type":"object","required":["usageFeature","runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"usageFeature":{"type":"string","enum":["code-review","sandbox-coder","agent-session","custom-agent","changelog","dockerfile-init"]},"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}}},"byModel":{"type":"array","items":{"type":"object","required":["requestedProvider","requestedModel","runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"requestedProvider":{"nullable":true,"type":"string"},"requestedModel":{"nullable":true,"type":"string"},"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}}},"byFeatureModel":{"type":"array","items":{"type":"object","required":["usageFeature","requestedProvider","requestedModel","runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"usageFeature":{"type":"string","enum":["code-review","sandbox-coder","agent-session","custom-agent","changelog","dockerfile-init"]},"requestedProvider":{"nullable":true,"type":"string"},"requestedModel":{"nullable":true,"type":"string"},"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}}},"byProject":{"type":"array","items":{"type":"object","required":["projectId","projectName","runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"projectId":{"nullable":true,"type":"string"},"projectName":{"nullable":true,"description":"Null when the project was deleted.","type":"string"},"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}}},"seriesByModel":{"type":"array","items":{"type":"object","required":["bucket","requestedProvider","requestedModel","runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur"],"properties":{"bucket":{"description":"UTC bucket key: YYYY-MM-DD for day buckets, YYYY-MM-DDTHH for hour buckets.","type":"string"},"requestedProvider":{"nullable":true,"type":"string"},"requestedModel":{"nullable":true,"type":"string"},"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"description":"EUR charged to the organization, in micro-EUR.","type":"number"},"vendorCostMicroUsd":{"description":"Diagnostic vendor cost, in micro-USD.","type":"number"},"markupMicroEur":{"description":"Part of the charge attributable to the token margin, in micro-EUR.","type":"number"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/projects-with-services":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listOrganizationProjectsWithServices","summary":"List an organization projects with their services","description":"Returns every project in the organization with its services in one request, including deployment state and preview environments, batched to avoid per-project fan-out. The id must be the caller active organization. Requires read:organization scope plus read:projects for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"ProjectWithServices","type":"object","required":["id","name","generatedNamespace","organizationId","isSystem","sourceBlueprintId","sourceBlueprintVersion","services"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"generatedNamespace":{"type":"string"},"organizationId":{"type":"string"},"isSystem":{"type":"boolean"},"sourceBlueprintId":{"nullable":true,"type":"string"},"sourceBlueprintVersion":{"nullable":true,"type":"number"},"services":{"type":"array","items":{"title":"ServiceWithState","anyOf":[{"title":"RepoServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"DatabaseServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"S3ServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"ApplicationServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"ArtifactsServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}}]}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/service-policies":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationServicePolicies","summary":"Get an organization available service policies","description":"Returns the service policies the organization admin has made available for services to opt into. The id must be the caller active organization. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationServicePolicies","type":"object","required":["available"],"properties":{"available":{"description":"Service policy name to whether the organization admin made it available.","type":"object","additionalProperties":{"type":"boolean"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/audit-config":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationAuditConfig","summary":"Get an organization audit log config","description":"Returns the audit log retention configuration for the caller active organization, creating a default row if none exists. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAuditConfig","type":"object","required":["id","organizationId","enabled","retentionDays","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"enabled":{"type":"boolean"},"retentionDays":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateOrganizationAuditConfig","summary":"Update an organization audit log config","description":"Updates whether audit logging is enabled and its retention period (1 to 365 days) for the caller active organization. Requires read:organization and write:organization scopes for bearer callers, canManageOrganization for session callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAuditConfig","type":"object","required":["id","organizationId","enabled","retentionDays","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"enabled":{"type":"boolean"},"retentionDays":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"retentionDays":{"type":"number"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"retentionDays":{"type":"number"}}}},"text/plain":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"retentionDays":{"type":"number"}}}}}}}},"/api/organization/{orgId}/subscription":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationSubscription","summary":"Get an organization subscription and resource usage","description":"Returns the organization subscription status, tier, resource budgets and used amounts, and AI budget balance, projected from live Stripe data. Read-only. The id must be the caller active organization. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationSubscription","type":"object","required":["subscription","usage","plans"],"properties":{"subscription":{"type":"object","required":["tier","tierLabel","status","statusLabel","isActive","isTrialing","isInactive","canSwitchPlan","trial","trialExtended","withCardExtensionMinutes","billingInterval","periodEnd","cancelAtPeriodEnd"],"properties":{"tier":{"type":"string","enum":["pluto","mercury","earth","neptune","enterprise"]},"tierLabel":{"type":"string"},"status":{"type":"string"},"statusLabel":{"type":"string"},"isActive":{"type":"boolean"},"isTrialing":{"type":"boolean"},"isInactive":{"type":"boolean"},"canSwitchPlan":{"type":"boolean"},"trial":{"nullable":true,"type":"object","required":["endsAt","daysLeft","hoursLeft","minutesLeft","isExpiringSoon","isLastDay"],"properties":{"endsAt":{"format":"date-time","type":"string"},"daysLeft":{"type":"number"},"hoursLeft":{"type":"number"},"minutesLeft":{"type":"number"},"isExpiringSoon":{"type":"boolean"},"isLastDay":{"type":"boolean"}}},"trialExtended":{"type":"boolean"},"withCardExtensionMinutes":{"type":"number"},"billingInterval":{"nullable":true,"type":"string","enum":["monthly","annual"]},"periodEnd":{"nullable":true,"format":"date-time","type":"string"},"cancelAtPeriodEnd":{"type":"boolean"}}},"usage":{"type":"object","required":["period","metrics","aiPurchasedMicroEur","aiPurchasedNetGrantedMicroEur","addonCpuUnits","addonMemUnits"],"properties":{"period":{"type":"object","required":["startedAt","resetsAt"],"properties":{"startedAt":{"format":"date-time","type":"string"},"resetsAt":{"format":"date-time","type":"string"}}},"metrics":{"type":"object","required":["cpu","memory","buildMinutes","aiBudget","storage"],"properties":{"cpu":{"type":"object","required":["current","limit","percentage","isNearLimit","isAtLimit"],"properties":{"current":{"type":"number"},"limit":{"nullable":true,"description":"Null means unlimited.","type":"number"},"percentage":{"type":"number"},"isNearLimit":{"type":"boolean"},"isAtLimit":{"type":"boolean"}}},"memory":{"type":"object","required":["current","limit","percentage","isNearLimit","isAtLimit"],"properties":{"current":{"type":"number"},"limit":{"nullable":true,"description":"Null means unlimited.","type":"number"},"percentage":{"type":"number"},"isNearLimit":{"type":"boolean"},"isAtLimit":{"type":"boolean"}}},"buildMinutes":{"type":"object","required":["current","limit","percentage","isNearLimit","isAtLimit"],"properties":{"current":{"type":"number"},"limit":{"nullable":true,"description":"Null means unlimited.","type":"number"},"percentage":{"type":"number"},"isNearLimit":{"type":"boolean"},"isAtLimit":{"type":"boolean"}}},"aiBudget":{"type":"object","required":["current","limit","percentage","isNearLimit","isAtLimit"],"properties":{"current":{"type":"number"},"limit":{"nullable":true,"description":"Null means unlimited.","type":"number"},"percentage":{"type":"number"},"isNearLimit":{"type":"boolean"},"isAtLimit":{"type":"boolean"}}},"storage":{"type":"object","required":["current","limit","percentage","isNearLimit","isAtLimit"],"properties":{"current":{"type":"number"},"limit":{"nullable":true,"description":"Null means unlimited.","type":"number"},"percentage":{"type":"number"},"isNearLimit":{"type":"boolean"},"isAtLimit":{"type":"boolean"}}}}},"aiPurchasedMicroEur":{"type":"number"},"aiPurchasedNetGrantedMicroEur":{"type":"number"},"addonCpuUnits":{"type":"number"},"addonMemUnits":{"type":"number"}}},"plans":{"type":"array","items":{"type":"object","required":["tier","label","description","isCurrent","isPopular","pricing","limits","addons","features"],"properties":{"tier":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"isCurrent":{"type":"boolean"},"isPopular":{"type":"boolean"},"pricing":{"type":"object","required":["monthly","annual"],"properties":{"monthly":{"type":"object","required":["cents","display"],"properties":{"cents":{"type":"number"},"display":{"type":"string"}}},"annual":{"type":"object","required":["cents","monthlyEquivalentCents","display","monthlyDisplay","savingsPercent"],"properties":{"cents":{"type":"number"},"monthlyEquivalentCents":{"type":"number"},"display":{"type":"string"},"monthlyDisplay":{"type":"string"},"savingsPercent":{"type":"number"}}}}},"limits":{"type":"object","required":["cpuPoolMillis","memPoolMib","defaultServiceCpuMillis","defaultServiceMemMib","buildMinutesPerPeriod","aiBudgetEurPerPeriod","storageGb"],"properties":{"cpuPoolMillis":{"nullable":true,"type":"number"},"memPoolMib":{"nullable":true,"type":"number"},"defaultServiceCpuMillis":{"type":"number"},"defaultServiceMemMib":{"type":"number"},"buildMinutesPerPeriod":{"nullable":true,"type":"number"},"aiBudgetEurPerPeriod":{"nullable":true,"type":"number"},"storageGb":{"nullable":true,"type":"number"}}},"addons":{"type":"object","required":["stepCpuMillis","stepMemMib","cpuUnit","memUnit"],"properties":{"stepCpuMillis":{"type":"number"},"stepMemMib":{"type":"number"},"cpuUnit":{"type":"object","required":["monthlyCents","annualCents"],"properties":{"monthlyCents":{"type":"number"},"annualCents":{"type":"number"}}},"memUnit":{"type":"object","required":["monthlyCents","annualCents"],"properties":{"monthlyCents":{"type":"number"},"annualCents":{"type":"number"}}}}},"features":{"type":"array","items":{"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/subscription/can-switch":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"checkOrganizationSubscriptionCanSwitch","summary":"Check if an organization can switch tier","description":"Read-only pre-flight capacity check for a tier switch: reports whether current resource usage would violate the target tier pool. The id must be the caller active organization. As a POST, requires read:organization and write:organization scopes for bearer callers and canManageOrganization for session callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationSubscriptionCanSwitch","type":"object","required":["canSwitch","violations"],"properties":{"canSwitch":{"type":"boolean"},"violations":{"type":"array","items":{"type":"object","required":["resource","current","limit"],"properties":{"resource":{"type":"string","enum":["cpu","memory"]},"current":{"type":"number"},"limit":{"type":"number"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"}}}}}}}},"/api/organization/{orgId}/subscription/switch":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"switchOrganizationSubscription","summary":"Switch an organization subscription tier","description":"Switches the organization to a target paid tier and billing interval, prorating and charging immediately, ending a trial when needed, or returning a Checkout/Portal recovery URL when a payment method is missing or the subscription needs recovery. The id must be the caller active organization and the caller must be an owner, checked before the org capacity lock is taken. Requires read:organization and write:organization scopes for bearer callers. Responds 409 when current CPU or memory usage would violate the target tier resource pool. Same-tier billing interval changes skip the capacity check.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationSubscriptionSwitch","type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"tier":{"type":"string","enum":["pluto","mercury","earth","neptune","enterprise"]},"isDowngrade":{"type":"boolean"},"alreadyApplied":{"type":"boolean"},"interval":{"type":"string","enum":["monthly","annual"]},"checkoutUrl":{"nullable":true,"description":"Stripe Checkout URL to add a payment method before the switch applies.","type":"string"},"recoveryUrl":{"description":"Checkout or Portal URL to restore a broken subscription first.","type":"string"},"recoveryKind":{"type":"string","enum":["portal","checkout"]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"},"annual":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"},"annual":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["targetTier"],"properties":{"targetTier":{"type":"string"},"annual":{"type":"boolean"}}}}}}}},"/api/organization/{orgId}/billing/apply-promo-code":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"applyOrganizationPromoCode","summary":"Apply a Stripe promotion code to an organization","description":"Applies a Stripe promotion code to the organization subscription, stacking on any already-attached discounts. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers. Responds 400 for an invalid or inactive code or when the subscription needs recovery first.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationPromoCodeApplied","type":"object","required":["success","code"],"properties":{"success":{"type":"boolean"},"code":{"type":"string"},"alreadyApplied":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"minLength":1,"maxLength":64,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["code"],"properties":{"code":{"minLength":1,"maxLength":64,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["code"],"properties":{"code":{"minLength":1,"maxLength":64,"type":"string"}}}}}}}},"/api/organization/{orgId}/billing/ai-budget/topup":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createOrganizationAiBudgetTopup","summary":"Create an AI budget top-up Checkout session","description":"Creates a payment-mode Stripe Checkout session for a one-time EUR AI budget top-up (5 to 10000 EUR). The budget is granted once the checkout.session.completed webhook fires. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers. Responds 400 when billing is not set up for the organization.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAiBudgetTopup","type":"object","required":["checkoutUrl"],"properties":{"checkoutUrl":{"nullable":true,"description":"Stripe Checkout URL for the top-up payment.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amountEur"],"properties":{"amountEur":{"minimum":5,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":5,"maximum":10000,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["amountEur"],"properties":{"amountEur":{"minimum":5,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":5,"maximum":10000,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["amountEur"],"properties":{"amountEur":{"minimum":5,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":5,"maximum":10000,"type":"integer"}]}}}}}}}},"/api/organization/{orgId}/billing/resource-addons":{"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateOrganizationResourceAddons","summary":"Set an organization purchased resource add-on units","description":"Sets the absolute CPU and memory add-on unit quantities on the organization Stripe subscription, prorating and charging immediately (idempotent under retries). Runs under the org capacity lock. Not available on the enterprise tier. The id must be the caller active organization and the caller must be an owner, checked before the lock. Requires read:organization and write:organization scopes for bearer callers. Responds 409 when reducing add-ons would violate the resource pool, or when the subscription changed mid-request and was rolled back.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationResourceAddonsUpdate","type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"cpuUnits":{"type":"number"},"memUnits":{"type":"number"},"recoveryUrl":{"description":"Checkout or Portal URL to restore a broken subscription first.","type":"string"},"recoveryKind":{"type":"string","enum":["portal","checkout"]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"prorationDate":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"prorationDate":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"prorationDate":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}}}}}},"/api/organization/{orgId}/billing/resource-addons/preview":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"previewOrganizationResourceAddons","summary":"Preview an organization resource add-on price change","description":"Read-only preview of what changing CPU/memory add-on units would cost: the amount settled now (0 while trialing), the recurring delta per interval, and whether a payment method is on file. The id must be the caller active organization and the caller must be an owner. As a POST, requires read:organization and write:organization scopes for bearer callers. Not available on the enterprise tier.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationResourceAddonsPreview","type":"object","required":["dueNowCents","recurringDeltaCents","remainingFraction","currency","interval","trialing","trialEndsAt","periodEnd","hasPaymentMethod","prorationDate"],"properties":{"dueNowCents":{"description":"Prorated charge (positive) or credit (negative) settled now, in cents.","type":"number"},"recurringDeltaCents":{"description":"Change of the recurring add-on total per billing interval, in cents.","type":"number"},"remainingFraction":{"description":"Fraction of the current period left, 0 to 1.","type":"number"},"currency":{"type":"string"},"interval":{"type":"string","enum":["monthly","annual"]},"trialing":{"type":"boolean"},"trialEndsAt":{"nullable":true,"format":"date-time","type":"string"},"periodEnd":{"format":"date-time","type":"string"},"hasPaymentMethod":{"type":"boolean"},"prorationDate":{"description":"Unix seconds to pass back as `prorationDate` when confirming.","type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["cpuUnits","memUnits"],"properties":{"cpuUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]},"memUnits":{"minimum":0,"maximum":1000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"maximum":1000,"type":"integer"}]}}}}}}}},"/api/organization/{orgId}/billing/promo-code":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"removeOrganizationPromoCode","summary":"Remove every promotion code from an organization","description":"Removes every discount attached to the organization Stripe subscription. Idempotent: a no-op returns success when nothing is attached. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationPromoCodeRemoved","type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"alreadyRemoved":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/billing/promo-code/{discountId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string"},"in":"path","name":"discountId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"removeOrganizationPromoCodeDiscount","summary":"Remove one promotion code from an organization","description":"Removes one discount, identified by its id, from the organization Stripe subscription, keeping any others attached. Idempotent. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationPromoCodeRemoved","type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"alreadyRemoved":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/subscription/preview":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"previewOrganizationSubscription","summary":"Preview an organization subscription discount and next invoice","description":"Read-only preview of attached discounts and the projected next-invoice total from live Stripe data, so the UI can show what a promo code actually charges. The id must be the caller active organization and the caller must be an owner. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationSubscriptionPreview","type":"object","required":["discounts","nextInvoice"],"properties":{"discounts":{"type":"array","items":{"type":"object","required":["id","code","label","duration","durationInMonths","recurrenceLabel","savingsLabel","eligible","eligibleTierLabels","scope","percentOff","amountOffCents","currency"],"properties":{"id":{"type":"string"},"code":{"type":"string"},"label":{"type":"string"},"duration":{"type":"string","enum":["once","repeating","forever"]},"durationInMonths":{"nullable":true,"type":"number"},"recurrenceLabel":{"type":"string"},"savingsLabel":{"type":"string"},"eligible":{"type":"boolean"},"eligibleTierLabels":{"type":"array","items":{"type":"string"}},"scope":{"type":"string","enum":["all","plans","addons"]},"percentOff":{"nullable":true,"type":"number"},"amountOffCents":{"nullable":true,"type":"number"},"currency":{"nullable":true,"type":"string"}}}},"nextInvoice":{"nullable":true,"type":"object","required":["subtotalCents","discountCents","totalCents","currency","interval","display"],"properties":{"subtotalCents":{"type":"number"},"discountCents":{"type":"number"},"totalCents":{"type":"number"},"currency":{"type":"string"},"interval":{"type":"string","enum":["month","year"]},"display":{"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/billing-portal/add-card":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createOrganizationBillingPortalAddCardSession","summary":"Create a Stripe billing portal session to add a card","description":"Creates a Stripe billing portal session deep-linked into the payment-method-update flow, redirecting back to the given return URL. The id must be the caller active organization and the caller must be an owner. Requires read:organization and write:organization scopes for bearer callers. Responds 400 when the organization has no Stripe customer.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationBillingPortalSession","type":"object","required":["url"],"properties":{"url":{"description":"Stripe billing portal URL.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["returnUrl"],"properties":{"returnUrl":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["returnUrl"],"properties":{"returnUrl":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["returnUrl"],"properties":{"returnUrl":{"type":"string"}}}}}}}},"/api/organization/{orgId}/members/{userId}/scopes":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string"},"in":"path","name":"userId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getOrganizationMemberScopes","summary":"Get an organization member OAuth scopes","description":"Returns a member custom scopes (or the role default set when uncustomized) and the scopes available to their role. Callable by an organization owner or by the member themselves. Requires read:organization scope for bearer callers.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationMemberScopes","type":"object","required":["scopes","available","customized"],"properties":{"scopes":{"type":"array","items":{"type":"string"}},"available":{"type":"array","items":{"type":"string"}},"customized":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string"},"in":"path","name":"userId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateOrganizationMemberScopes","summary":"Update an organization member OAuth scopes","description":"Sets a member custom OAuth scopes after validating every requested scope against the scopes their role allows. Requires the caller to be an organization owner and read:organization and write:organization scopes for bearer callers. Responds 400 when a requested scope is not available to the member role.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationMemberScopesUpdated","type":"object","required":["scopes"],"properties":{"scopes":{"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scopes"],"properties":{"scopes":{"type":"array","items":{"type":"string"}}}}},"multipart/form-data":{"schema":{"type":"object","required":["scopes"],"properties":{"scopes":{"type":"array","items":{"type":"string"}}}}},"text/plain":{"schema":{"type":"object","required":["scopes"],"properties":{"scopes":{"type":"array","items":{"type":"string"}}}}}}}}},"/api/organization/{orgId}/rock8router/organizations":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAiGatewayOrganizations","summary":"List AI Gateway organizations","description":"Lists the Rock8Router AI Gateway organizations the caller verified e-mail is a member of, with `publicBaseUrl`, the gateway URL apps call with an issued key. The id must be the caller active organization. Requires read:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayOrganizationList","type":"object","required":["available","organizations","publicBaseUrl"],"properties":{"available":{"type":"boolean"},"organizations":{"type":"array","items":{"title":"AiGatewayOrganization","type":"object","required":["id","name","slug","role","currentBalanceEurCents"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"role":{"type":"string"},"currentBalanceEurCents":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]}}}},"publicBaseUrl":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAiGatewayOrganization","summary":"Create an AI Gateway organization","description":"Creates a Rock8Router AI Gateway organization under the caller verified e-mail. The id must be the caller active organization and the caller must be an owner. Requires write:ai-gateway scope for bearer callers. Responds 403 for non-owners, 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayOrganization","type":"object","required":["id","name","slug","role","currentBalanceEurCents"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"role":{"type":"string"},"currentBalanceEurCents":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"minLength":1,"maxLength":100,"pattern":"\\S","type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name"],"properties":{"name":{"minLength":1,"maxLength":100,"pattern":"\\S","type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["name"],"properties":{"name":{"minLength":1,"maxLength":100,"pattern":"\\S","type":"string"}}}}}}}},"/api/organization/{orgId}/rock8router/organizations/{rock8routerOrganizationId}/balance":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","minLength":1},"in":"path","name":"rock8routerOrganizationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAiGatewayBalance","summary":"Get an AI Gateway organization balance","description":"Returns the balance of a Rock8Router AI Gateway organization the caller verified e-mail is a member of. The id must be the caller active organization. Requires read:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayBalance","type":"object","required":["organizationId","currentBalanceEurCents"],"properties":{"organizationId":{"type":"string"},"currentBalanceEurCents":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/rock8router/organizations/{rock8routerOrganizationId}/topup":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","minLength":1},"in":"path","name":"rock8routerOrganizationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAiGatewayTopup","summary":"Create an AI Gateway top-up Checkout session","description":"Creates a payment-mode Stripe Checkout session that tops up a Rock8Router AI Gateway organization balance in EUR. The balance is credited once the checkout.session.completed webhook fires. The id must be the caller active organization and the caller must be an owner. Requires write:ai-gateway scope for bearer callers. Responds 403 for non-owners or a gateway organization funded by another organization, 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayTopup","type":"object","required":["checkoutUrl"],"properties":{"checkoutUrl":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amountEur","returnPath"],"properties":{"amountEur":{"minimum":10,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":10,"maximum":10000,"type":"integer"}]},"returnPath":{"minLength":1,"maxLength":2048,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["amountEur","returnPath"],"properties":{"amountEur":{"minimum":10,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":10,"maximum":10000,"type":"integer"}]},"returnPath":{"minLength":1,"maxLength":2048,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["amountEur","returnPath"],"properties":{"amountEur":{"minimum":10,"maximum":10000,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":10,"maximum":10000,"type":"integer"}]},"returnPath":{"minLength":1,"maxLength":2048,"type":"string"}}}}}}}},"/api/organization/{orgId}/rock8router/api-keys":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAiGatewayApiKey","summary":"Create an AI Gateway API key","description":"Issues a Rock8Router AI Gateway API key restricted to the given models and an optional EUR cent spending cap. Returns the token once. The id must be the caller active organization. Requires write:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayCreatedApiKey","type":"object","required":["apiKey","token"],"properties":{"apiKey":{"title":"AiGatewayApiKey","type":"object","required":["id","keyPrefix","name","organizationId","limitEurCents","isActive","hasBillingHistory","allowedModelIds"],"properties":{"id":{"type":"string"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"organizationId":{"type":"string"},"limitEurCents":{"nullable":true,"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"isActive":{"type":"boolean"},"hasBillingHistory":{"type":"boolean"},"allowedModelIds":{"nullable":true,"type":"array","items":{"type":"string"}}}},"token":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rock8routerOrganizationId","models","name"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"name":{"minLength":1,"maxLength":100,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["rock8routerOrganizationId","models","name"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"name":{"minLength":1,"maxLength":100,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["rock8routerOrganizationId","models","name"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"name":{"minLength":1,"maxLength":100,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}}}}}},"/api/organization/{orgId}/rock8router/models":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","minLength":1},"in":"query","name":"rock8routerOrganizationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAiGatewayModels","summary":"List AI Gateway models","description":"Lists the models a Rock8Router AI Gateway organization offers to its API keys. The id must be the caller active organization. Requires read:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"AiGatewayModel","type":"object","required":["id","model","modelId","name","isActive"],"properties":{"id":{"type":"string"},"model":{"type":"string"},"modelId":{"type":"string"},"name":{"type":"string"},"isActive":{"type":"boolean"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organization/{orgId}/rock8router/api-keys/{keyId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"keyId","required":true},{"schema":{"type":"string","minLength":1},"in":"query","name":"rock8routerOrganizationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAiGatewayApiKey","summary":"Get an AI Gateway API key","description":"Returns an AI Gateway API key as Rock8Router currently holds it: models, spending cap and active flag. Never returns the token. The id must be the caller active organization. Requires read:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayApiKey","type":"object","required":["id","keyPrefix","name","organizationId","limitEurCents","isActive","hasBillingHistory","allowedModelIds"],"properties":{"id":{"type":"string"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"organizationId":{"type":"string"},"limitEurCents":{"nullable":true,"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"isActive":{"type":"boolean"},"hasBillingHistory":{"type":"boolean"},"allowedModelIds":{"nullable":true,"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"keyId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateAiGatewayApiKey","summary":"Update an AI Gateway API key","description":"Enables or disables an AI Gateway API key, or changes its models or EUR cent spending cap. Applied upstream immediately. The id must be the caller active organization. Requires write:ai-gateway scope for bearer callers. Responds 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayApiKey","type":"object","required":["id","keyPrefix","name","organizationId","limitEurCents","isActive","hasBillingHistory","allowedModelIds"],"properties":{"id":{"type":"string"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"organizationId":{"type":"string"},"limitEurCents":{"nullable":true,"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"isActive":{"type":"boolean"},"hasBillingHistory":{"type":"boolean"},"allowedModelIds":{"nullable":true,"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rock8routerOrganizationId"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"isActive":{"type":"boolean"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["rock8routerOrganizationId"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"isActive":{"type":"boolean"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["rock8routerOrganizationId"],"properties":{"rock8routerOrganizationId":{"minLength":1,"type":"string"},"isActive":{"type":"boolean"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"keyId","required":true},{"schema":{"type":"string","minLength":1},"in":"query","name":"rock8routerOrganizationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteAiGatewayApiKey","summary":"Delete an AI Gateway API key","description":"Deletes an AI Gateway API key. Rock8Router only deletes a key with no billing history - disable one that has spend instead. A key already gone upstream counts as deleted. The id must be the caller active organization. Requires write:ai-gateway scope for bearer callers. Responds 409 when the key has billing history, 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Organizations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiGatewayDeletedApiKey","type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/project/{projectId}/ai-gateway/usage":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string","format":"date"},"in":"query","name":"from","required":true},{"schema":{"type":"string","format":"date"},"in":"query","name":"to","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getProjectAiGatewayUsage","summary":"Get project AI Gateway usage","description":"Returns AI Gateway spend for the API keys issued to the project services, per UTC day, key and model, across the gateway organizations the caller verified e-mail is a member of. The caller must be an owner of the project organization. Requires read:ai-gateway scope for bearer callers. Responds 403 for non-owners, 503 when the gateway is not configured, 502 on an upstream failure. Returns 404 when the AI Gateway is not enabled on this instance.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ProjectAiGatewayUsage","type":"object","required":["organizations","keys","usage"],"properties":{"organizations":{"type":"array","items":{"title":"AiGatewayOrganization","type":"object","required":["id","name","slug","role","currentBalanceEurCents"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"role":{"type":"string"},"currentBalanceEurCents":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]}}}},"keys":{"type":"array","items":{"type":"object","required":["keyId","keyPrefix","envKey","rock8routerOrganizationId","serviceId","serviceName","environmentId","environmentLabel"],"properties":{"keyId":{"type":"string"},"keyPrefix":{"type":"string"},"envKey":{"type":"string"},"rock8routerOrganizationId":{"type":"string"},"serviceId":{"type":"string"},"serviceName":{"nullable":true,"type":"string"},"environmentId":{"nullable":true,"type":"string"},"environmentLabel":{"nullable":true,"type":"string"}}}},"usage":{"type":"array","items":{"type":"object","required":["rock8routerOrganizationId","period","apiKeyId","model","spentEurCents","tokens","audioSeconds","requests"],"properties":{"rock8routerOrganizationId":{"type":"string"},"period":{"type":"string"},"apiKeyId":{"type":"string"},"model":{"type":"string"},"spentEurCents":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"tokens":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"audioSeconds":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]},"requests":{"anyOf":[{"format":"integer","default":0,"type":"string"},{"type":"integer"}]}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/project/":{"get":{"operationId":"listProjects","summary":"List projects","description":"Lists the projects of the active organization. Requires scope `read:projects`.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"Project","type":"object","required":["id","name","generatedNamespace","organizationId","isSystem","sourceBlueprintId","sourceBlueprintVersion"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"generatedNamespace":{"type":"string"},"organizationId":{"type":"string"},"isSystem":{"type":"boolean"},"sourceBlueprintId":{"nullable":true,"type":"string"},"sourceBlueprintVersion":{"nullable":true,"type":"number"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createProject","summary":"Create a project","description":"Creates a project in the active organization. Requires scopes `read:projects` and `write:projects`. Returns 400 if there is no active organization.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Project","type":"object","required":["id","name","generatedNamespace","organizationId","isSystem","sourceBlueprintId","sourceBlueprintVersion"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"generatedNamespace":{"type":"string"},"organizationId":{"type":"string"},"isSystem":{"type":"boolean"},"sourceBlueprintId":{"nullable":true,"type":"string"},"sourceBlueprintVersion":{"nullable":true,"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}}}},"/api/project/{projectId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteProject","summary":"Delete a project","description":"Deletes a project and its services in one transaction: enqueues GitOps cleanup for their environments, retires the AI Gateway keys issued for the project (best-effort), cancels queued custom-agent runs and revokes their keys, then deletes the project row. Requires scopes `read:projects` and `write:projects`. Returns 404 if not found.","tags":["Projects"],"responses":{"200":{"description":"Project deleted. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getProject","summary":"Get a project","description":"Returns a project with its services, each enriched with computed service state and OOM overlay flags. Requires scope `read:projects`.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"nullable":true,"title":"ProjectWithServices","type":"object","required":["id","name","generatedNamespace","organizationId","isSystem","sourceBlueprintId","sourceBlueprintVersion","services"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"generatedNamespace":{"type":"string"},"organizationId":{"type":"string"},"isSystem":{"type":"boolean"},"sourceBlueprintId":{"nullable":true,"type":"string"},"sourceBlueprintVersion":{"nullable":true,"type":"number"},"services":{"type":"array","items":{"title":"ServiceWithState","anyOf":[{"title":"RepoServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"DatabaseServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"S3ServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"ApplicationServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}},{"title":"ArtifactsServiceWithState","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername","isDeployed","serviceState","podStatus","hasRecentOom","watcherSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"isDeployed":{"type":"boolean"},"activeDeployment":{"title":"ActiveDeployment","type":"object","required":["id","deployedAt","status","deployedBy","deployedByName","targetUrl","environmentType","pullRequestNumber"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedBy":{"type":"string"},"deployedByName":{"type":"string"},"targetUrl":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"}}},"activeAnalysis":{"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"podStatus":{"nullable":true,"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"previews":{"type":"array","items":{"title":"ServicePreviewState","type":"object","required":["id","pullRequestNumber","serviceState","hasRecentOom","watcherSummary","activeDeploymentAt"],"properties":{"id":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"hasRecentOom":{"type":"boolean"},"watcherSummary":{"nullable":true,"title":"WatcherSummary","type":"object","required":["readyCount","desiredCount"],"properties":{"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"failureReason":{"type":"string"}}},"activeDeploymentAt":{"nullable":true,"type":"string","format":"date-time"}}}}}}]}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateProject","summary":"Update a project","description":"Renames a project. Requires scopes `read:projects` and `write:projects`. Returns 404 if not found.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Project","type":"object","required":["id","name","generatedNamespace","organizationId","isSystem","sourceBlueprintId","sourceBlueprintVersion"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"generatedNamespace":{"type":"string"},"organizationId":{"type":"string"},"isSystem":{"type":"boolean"},"sourceBlueprintId":{"nullable":true,"type":"string"},"sourceBlueprintVersion":{"nullable":true,"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}}}},"/api/project/{projectId}/env-sources":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listProjectEnvSources","summary":"List env var sources for a project","description":"Returns each service in the project with the env var keys other services can link to it, used to populate the linked-variable picker. Requires scope `read:projects`.","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"ProjectEnvSource","type":"object","required":["serviceId","name","type","availableKeys"],"properties":{"serviceId":{"type":"string"},"name":{"type":"string"},"type":{"anyOf":[{"enum":["repo"],"type":"string"},{"enum":["s3"],"type":"string"},{"enum":["application"],"type":"string"},{"enum":["db"],"type":"string"}]},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"availableKeys":{"type":"array","items":{"type":"object","required":["key","label","valueType"],"properties":{"key":{"description":"Key name, e.g. HOST, PORT, PASSWORD.","type":"string"},"label":{"type":"string"},"secretKey":{"type":"string"},"value":{"type":"string"},"dependsOn":{"description":"Env vars injected when this key is selected, as env var name to service key.","type":"object","additionalProperties":{"type":"string"}},"valueType":{"description":"Either 'plain' (literal value) or 'secret' (read from a secret).","type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/check-url":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"url","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"checkServiceUrlAvailability","summary":"Check external URL availability","description":"Checks whether an external service URL is free to claim before creating or renaming a service. Rate-limited per client, returns 429 when exceeded. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"UrlAvailability","type":"object","required":["available","url"],"properties":{"available":{"type":"boolean"},"url":{"type":"string"},"error":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createService","summary":"Create a repository service","description":"Creates a repo-backed service in a project, allocates its external URL, and initializes default workflows. Requires scopes `read:services` and `write:services`. Returns 404 if the project is not found, 403 if it belongs to another organization, 400 for an invalid repo URL, Dockerfile location or replica count.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"RepoService","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","containerPort","projectId"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}},"projectId":{"type":"string"},"generateDockerfile":{"type":"boolean"},"replicas":{"minimum":1,"type":"number"},"healthEndpoint":{"type":"string"},"autoDeploy":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","containerPort","projectId"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}},"projectId":{"type":"string"},"generateDockerfile":{"type":"boolean"},"replicas":{"minimum":1,"type":"number"},"healthEndpoint":{"type":"string"},"autoDeploy":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","containerPort","projectId"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}},"projectId":{"type":"string"},"generateDockerfile":{"type":"boolean"},"replicas":{"minimum":1,"type":"number"},"healthEndpoint":{"type":"string"},"autoDeploy":{"type":"boolean"}}}}}}}},"/api/service/by_project/{projectId}":{"get":{"operationId":"listServices","summary":"List services in a project","description":"Lists all services belonging to a project in the active organization. Requires scope `read:services`. Returns 404 if the project is not found, 403 if it belongs to another organization.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"ServiceView","anyOf":[{"title":"RepoServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"DatabaseServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"S3ServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ApplicationServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ArtifactsServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}}]}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/service/{serviceId}/pull-requests":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"q","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServicePullRequests","summary":"List pull requests for a service","description":"Returns paginated pull requests tracked for the service, filterable by state and title search, each with activity counts. Requires scopes `read:services` and `read:agents`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PullRequestList","type":"object","required":["pullRequests","limit","offset"],"properties":{"pullRequests":{"type":"array","items":{"title":"PullRequestListItem","type":"object","required":["id","serviceId","organizationId","number","githubId","title","state","draft","htmlUrl","headBranch","baseBranch","headSha","baseSha","mergeCommitSha","authorLogin","authorId","authorType","origin","sourceIssueNumber","githubCreatedAt","githubUpdatedAt","closedAt","mergedAt","lastSyncedAt","createdAt","updatedAt","counts"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"organizationId":{"type":"string"},"number":{"type":"number"},"githubId":{"nullable":true,"type":"number"},"title":{"type":"string"},"state":{"anyOf":[{"enum":["open"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["merged"],"type":"string"}]},"draft":{"type":"boolean"},"htmlUrl":{"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"headSha":{"nullable":true,"type":"string"},"baseSha":{"nullable":true,"type":"string"},"mergeCommitSha":{"nullable":true,"type":"string"},"authorLogin":{"nullable":true,"type":"string"},"authorId":{"nullable":true,"type":"string"},"authorType":{"nullable":true,"type":"string"},"origin":{"anyOf":[{"enum":["github"],"type":"string"},{"enum":["agent-session"],"type":"string"},{"enum":["custom-agent"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"},{"enum":["dockerfile-init"],"type":"string"}]},"sourceIssueNumber":{"nullable":true,"type":"number"},"githubCreatedAt":{"nullable":true,"type":"string","format":"date-time"},"githubUpdatedAt":{"nullable":true,"type":"string","format":"date-time"},"closedAt":{"nullable":true,"type":"string","format":"date-time"},"mergedAt":{"nullable":true,"type":"string","format":"date-time"},"lastSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"counts":{"type":"object","required":["agentSessionCount","codeReviewCount","environmentCount","sandboxCoderCount"],"properties":{"agentSessionCount":{"type":"number"},"codeReviewCount":{"type":"number"},"environmentCount":{"type":"number"},"sandboxCoderCount":{"type":"number"}}}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/pull-requests/live":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceLivePullRequestSessions","summary":"List live sessions without a pull request","description":"Returns agent sessions for the service that are still running and have not yet opened a pull request, for the PR rail. Requires scopes `read:services` and `read:agents`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"LivePullRequestSessions","type":"object","required":["sessions","count"],"properties":{"sessions":{"type":"array","items":{"type":"object","required":["id","title","status","agentType","mode","coderBranch","baseBranch","createdAt","lastActivityAt"],"properties":{"id":{"type":"string"},"title":{"nullable":true,"type":"string"},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"agentType":{"type":"string"},"mode":{"anyOf":[{"enum":["mutating"],"type":"string"},{"enum":["report"],"type":"string"}]},"coderBranch":{"nullable":true,"type":"string"},"baseBranch":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"}}}},"count":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/pull-requests/{prNumber}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"prNumber","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServicePullRequest","summary":"Get a pull request with its activity","description":"Returns a pull request tracked by the service, aggregated with its agent sessions, code reviews, environment, sandbox coder runs, workflow runs and jobs. Requires scopes `read:services` and `read:agents`. Returns 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PullRequestDetail","type":"object","required":["publicAccessEnabled","pullRequest","agentSessions","codeReviews","environment","sandboxCoders","agentWorkflowRuns","customAgentRuns","jobs"],"properties":{"publicAccessEnabled":{"type":"boolean"},"pullRequest":{"title":"PullRequest","type":"object","required":["id","serviceId","organizationId","number","githubId","title","state","draft","htmlUrl","headBranch","baseBranch","headSha","baseSha","mergeCommitSha","authorLogin","authorId","authorType","origin","sourceIssueNumber","githubCreatedAt","githubUpdatedAt","closedAt","mergedAt","lastSyncedAt","createdAt","updatedAt","body"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"organizationId":{"type":"string"},"number":{"type":"number"},"githubId":{"nullable":true,"type":"number"},"title":{"type":"string"},"state":{"anyOf":[{"enum":["open"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["merged"],"type":"string"}]},"draft":{"type":"boolean"},"htmlUrl":{"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"headSha":{"nullable":true,"type":"string"},"baseSha":{"nullable":true,"type":"string"},"mergeCommitSha":{"nullable":true,"type":"string"},"authorLogin":{"nullable":true,"type":"string"},"authorId":{"nullable":true,"type":"string"},"authorType":{"nullable":true,"type":"string"},"origin":{"anyOf":[{"enum":["github"],"type":"string"},{"enum":["agent-session"],"type":"string"},{"enum":["custom-agent"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"},{"enum":["dockerfile-init"],"type":"string"}]},"sourceIssueNumber":{"nullable":true,"type":"number"},"githubCreatedAt":{"nullable":true,"type":"string","format":"date-time"},"githubUpdatedAt":{"nullable":true,"type":"string","format":"date-time"},"closedAt":{"nullable":true,"type":"string","format":"date-time"},"mergedAt":{"nullable":true,"type":"string","format":"date-time"},"lastSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"body":{"nullable":true,"type":"string"}}},"agentSessions":{"type":"array","items":{"type":"object","required":["id","title","status","agentType","mode","coderBranch","latestCommitSha","createdAt","lastActivityAt"],"properties":{"id":{"type":"string"},"title":{"nullable":true,"type":"string"},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"agentType":{"type":"string"},"mode":{"anyOf":[{"enum":["mutating"],"type":"string"},{"enum":["report"],"type":"string"}]},"coderBranch":{"nullable":true,"type":"string"},"latestCommitSha":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"}}}},"codeReviews":{"type":"array","items":{"type":"object","required":["id","status","commitSha","branch","summary","criticalCount","warningCount","suggestionCount","createdAt","completedAt"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"commitSha":{"type":"string"},"branch":{"type":"string"},"summary":{"nullable":true,"type":"string"},"criticalCount":{"type":"number"},"warningCount":{"type":"number"},"suggestionCount":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"}}}},"environment":{"nullable":true,"type":"object","required":["id","type","previewUrl","podStatus","desiredReplicas","currentReplicas","argoAppName","closedAt"],"properties":{"id":{"type":"string"},"type":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"previewUrl":{"nullable":true,"type":"string"},"podStatus":{"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"desiredReplicas":{"nullable":true,"type":"number"},"currentReplicas":{"nullable":true,"type":"number"},"argoAppName":{"type":"string"},"closedAt":{"nullable":true,"type":"string","format":"date-time"}}},"sandboxCoders":{"type":"array","items":{"type":"object","required":["id","status","prompt","coderBranch","createdAt","completedAt"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"}]},"prompt":{"description":"First 300 characters of the prompt.","type":"string"},"coderBranch":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"}}}},"agentWorkflowRuns":{"type":"array","items":{"type":"object","required":["id","workflowId","organizationId","serviceId","status","triggerKey","planVersion","triggeredBy","parentWorkflowRunId","cancelReason","completedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"triggerKey":{"type":"string"},"planVersion":{"type":"number"},"triggeredBy":{"nullable":true,"type":"string"},"parentWorkflowRunId":{"nullable":true,"type":"string"},"cancelReason":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"customAgentRuns":{"type":"array","items":{"type":"object","required":["id","status","createdAt","completedAt","serviceId","agentName","workflowId","triggerType","hasCommit","hasPr","noChanges","recovered"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"serviceId":{"nullable":true,"type":"string"},"agentName":{"nullable":true,"type":"string"},"workflowId":{"nullable":true,"type":"string"},"triggerType":{"nullable":true,"type":"string"},"hasCommit":{"type":"boolean"},"hasPr":{"type":"boolean"},"noChanges":{"type":"boolean"},"recovered":{"type":"boolean"}}}},"jobs":{"type":"array","items":{"type":"object","required":["id","type","status","createdAt","startedAt","completedAt","error"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"error":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/pull-requests/{prNumber}/mergeability":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"prNumber","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServicePullRequestMergeability","summary":"Get pull request mergeability","description":"Reads mergeability live from GitHub for an open, non-draft pull request. Closed or draft PRs are answered from the stored row without a GitHub call. Requires scopes `read:services` and `read:agents`. Returns 404 if the pull request is not tracked.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PullRequestMergeability","type":"object","required":["state","mergeable","mergeableState","reason"],"properties":{"state":{"type":"string"},"mergeable":{"nullable":true,"description":"Null while GitHub is still computing the merge. Poll until it settles.","type":"boolean"},"mergeableState":{"nullable":true,"type":"string"},"reason":{"nullable":true,"description":"Why the pull request cannot be merged. Null when it is mergeable.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/pull-requests/{prNumber}/merge":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"prNumber","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"mergeServicePullRequest","summary":"Merge a pull request","description":"Squash-merges an open, non-draft pull request on GitHub pinned to its current head SHA, then updates the local row. Requires scopes `read:services`, `write:services`, `read:agents` and `write:agents`. Returns 400 if the PR is not open, is a draft, or GitHub declines the merge, 404 if not tracked.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PullRequestMerged","type":"object","required":["merged","mergeCommitSha"],"properties":{"merged":{"type":"boolean"},"mergeCommitSha":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/pull-requests/{prNumber}/preview":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"prNumber","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createServicePullRequestPreview","summary":"Create a preview deployment for a pull request","description":"Reads the pull request live from GitHub and starts a preview deployment for its current head commit. Requires scopes `read:services`, `write:services`, `read:agents` and `write:agents`. Returns 400 if the pull request is not open, 404 if not tracked.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PullRequestPreview","type":"object","required":["status"],"properties":{"status":{"anyOf":[{"enum":["created"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["duplicate"],"type":"string"}]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}":{"get":{"operationId":"getService","summary":"Get a service","description":"Returns a service by id. Requires scope `read:services`. Returns 404 if the service does not exist, 403 if it belongs to another organization.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceView","anyOf":[{"title":"RepoServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"DatabaseServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"S3ServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ApplicationServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ArtifactsServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateService","summary":"Update a repository service","description":"Updates a repo service settings including URL slug, basic auth and per-service policy toggles, syncing the uptime monitor target when the URL or public access changes. Requires scopes `read:services` and `write:services`. Returns 400 if the service is not a repo type, 403 if basic auth requires a higher tier, 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceView","anyOf":[{"title":"RepoServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","repoUrl","branch","dockerfileLocation","useDockerfileDirAsContext","dependencyScanEnabled","internalUrl","publicAccessEnabled","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["repo"],"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"containerPort":{"type":"string"},"healthEndpoint":{"nullable":true,"type":"string"},"policies":{"nullable":true,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}},"activeAnalysisId":{"type":"string"},"activeAiScanId":{"type":"string"},"pullRequestsSyncedAt":{"nullable":true,"type":"string","format":"date-time"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"DatabaseServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"S3ServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ApplicationServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}},{"title":"ArtifactsServiceView","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes","basicAuthEnabled","basicAuthUsername"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"},"basicAuthEnabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","internalUrl","containerPort"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"moveToVanity":{"type":"boolean"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"healthEndpoint":{"type":"string"},"basicAuth":{"nullable":true,"type":"object","required":["username","password"],"properties":{"username":{"pattern":"^[^:]+$","type":"string"},"password":{"type":"string"}}},"policies":{"additionalProperties":false,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}}},"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","internalUrl","containerPort"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"moveToVanity":{"type":"boolean"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"healthEndpoint":{"type":"string"},"basicAuth":{"nullable":true,"type":"object","required":["username","password"],"properties":{"username":{"pattern":"^[^:]+$","type":"string"},"password":{"type":"string"}}},"policies":{"additionalProperties":false,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}}},"additionalProperties":false}},"text/plain":{"schema":{"type":"object","required":["name","repoUrl","branch","dockerfileLocation","internalUrl","containerPort"],"properties":{"name":{"type":"string"},"repoUrl":{"type":"string"},"branch":{"type":"string"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"dependencyScanEnabled":{"type":"boolean"},"internalUrl":{"type":"string"},"publicAccessEnabled":{"type":"boolean"},"slug":{"type":"string"},"moveToVanity":{"type":"boolean"},"containerPort":{"pattern":"^(?:[1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$","type":"string"},"healthEndpoint":{"type":"string"},"basicAuth":{"nullable":true,"type":"object","required":["username","password"],"properties":{"username":{"pattern":"^[^:]+$","type":"string"},"password":{"type":"string"}}},"policies":{"additionalProperties":false,"type":"object","properties":{"disableNetworkPolicies":{"type":"boolean"}}}},"additionalProperties":false}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteService","summary":"Delete a service","description":"Deletes a service, removes linked env var references from dependent services and redeploys them, removes its uptime monitor, retires the AI Gateway keys issued for it (best-effort) and enqueues GitOps cleanup for its environments. Requires scopes `read:services` and `write:services`. Returns 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Success","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/dependents":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceDependents","summary":"List services depending on a service","description":"Returns the other services in the org whose env vars link to this service. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceDependents","type":"object","required":["dependents"],"properties":{"dependents":{"type":"array","items":{"type":"object","required":["id","name","type"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"anyOf":[{"enum":["repo"],"type":"string"},{"enum":["db"],"type":"string"},{"enum":["s3"],"type":"string"},{"enum":["application"],"type":"string"},{"enum":["artifacts"],"type":"string"}]}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/dockerfile-init":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"triggerServiceDockerfileInit","summary":"Trigger Dockerfile generation for a service","description":"Initializes default workflows if missing and triggers the dockerfile-init workflow, which runs an AI agent to generate a Dockerfile and open a PR. Requires scopes `read:services` and `write:services`. Returns 400 if the service is not a repo type, has an invalid repo URL, no GitHub connection, or no matching installation.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DockerfileInitTriggered","type":"object","required":["success","workflowId","workflowRunId","serviceId"],"properties":{"success":{"type":"boolean"},"workflowId":{"type":"string"},"workflowRunId":{"type":"string"},"serviceId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/connection-info":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceConnectionInfo","summary":"Get database connection info","description":"Returns connection details for a database-type service, resolved from its stable environment deployment. Requires scope `read:services`. Returns 400 if the service is not a database type or has no active deployment, 404 if the project is not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ConnectionInfo","type":"object","required":["host","port","secretName","secretKeys","availableEnvKeys"],"properties":{"host":{"type":"string"},"port":{"type":"number"},"secretName":{"nullable":true,"type":"string"},"secretKeys":{"type":"object","additionalProperties":{"type":"string"}},"availableEnvKeys":{"type":"array","items":{"title":"AvailableEnvKey","type":"object","required":["key","label","valueType"],"properties":{"key":{"description":"Key name, e.g. HOST, PORT, PASSWORD.","type":"string"},"label":{"type":"string"},"valueType":{"description":"Whether the value is plain or comes from a secret.","anyOf":[{"enum":["plain"],"type":"string"},{"enum":["secret"],"type":"string"}]},"secretKey":{"type":"string"},"value":{"type":"string"},"dependsOn":{"description":"Env vars injected when this key is selected, as env var name to service key.","type":"object","additionalProperties":{"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/analyze":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"triggerServiceAnalysis","summary":"Trigger language detection for a service repo","description":"Enqueues a service-analysis job that detects repository languages for the given branch and commit. Requires scopes `read:services` and `write:services` and an active subscription. Returns 400 if the service is not a repo type, has an invalid repo URL, or no GitHub installation covers it.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JobId","type":"object","required":["jobId"],"properties":{"jobId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"branch":{"type":"string"},"commitSha":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"branch":{"type":"string"},"commitSha":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","properties":{"branch":{"type":"string"},"commitSha":{"type":"string"}}}}}}}},"/api/service/{serviceId}/analysis":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceAnalysis","summary":"Get the latest language detection for a service","description":"Returns the most recent service-analysis language detection result, including failed results. Requires scope `read:services`. Returns 404 if no analysis exists yet.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceAnalysis","type":"object","required":["id","serviceId","commitSha","branch","markdown","metadata","status","errorMessage","jobId","createdAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"commitSha":{"type":"string"},"branch":{"type":"string"},"markdown":{"type":"string"},"metadata":{"nullable":true,"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}},"totalFiles":{"type":"number"},"totalBytes":{"type":"number"},"cliVersion":{"type":"string"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/analysis/history":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceAnalysisHistory","summary":"List language detection history for a service","description":"Returns past service-analysis language detection results, including failed results, most recent first, capped at 100. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceAnalysisHistory","type":"object","required":["analyses"],"properties":{"analyses":{"type":"array","items":{"title":"ServiceAnalysis","type":"object","required":["id","serviceId","commitSha","branch","markdown","metadata","status","errorMessage","jobId","createdAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"commitSha":{"type":"string"},"branch":{"type":"string"},"markdown":{"type":"string"},"metadata":{"nullable":true,"type":"object","properties":{"languages":{"type":"object","additionalProperties":{"type":"object","required":["percentage","color"],"properties":{"percentage":{"type":"number"},"color":{"type":"string"}}}},"totalFiles":{"type":"number"},"totalBytes":{"type":"number"},"cliVersion":{"type":"string"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/jobs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"status","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceJobs","summary":"List jobs for a service","description":"Returns paginated background jobs for the service, optionally filtered by comma-separated statuses. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceJobList","type":"object","required":["jobs","limit","offset"],"properties":{"jobs":{"type":"array","items":{"title":"Job","type":"object","required":["id","type","status","createdAt","startedAt","completedAt","params","result","error","retriedFromJobId","entityType","entityId","organizationId","triggeredBy"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"params":{"description":"Job input. Shape depends on the job type."},"result":{"description":"Job output, null until the job finishes. Shape depends on the job type."},"error":{"nullable":true,"type":"string"},"retriedFromJobId":{"nullable":true,"type":"string"},"entityType":{"nullable":true,"type":"string"},"entityId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"triggeredBy":{"nullable":true,"type":"string"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/active-jobs-count":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceActiveJobsCount","summary":"Get active job count for a service","description":"Returns the number of currently running or waiting jobs for the service, for a lightweight badge indicator. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ActiveJobsCount","type":"object","required":["count"],"properties":{"count":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/code-reviews":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"schema":{"type":"string"},"in":"query","name":"pullRequestNumber","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceCodeReviews","summary":"List code reviews for a service","description":"Returns paginated AI code reviews for the service, optionally scoped to one pull request. Requires scope `read:code-reviews` in addition to `read:services`. Returns 400 for an invalid pullRequestNumber.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewList","type":"object","required":["codeReviews","limit","offset"],"properties":{"codeReviews":{"type":"array","items":{"title":"CodeReviewListItem","type":"object","required":["id","serviceId","environmentId","pullRequestId","commitSha","branch","summary","findings","criticalCount","warningCount","suggestionCount","metadata","status","errorMessage","jobId","commentId","checkRunId","createdAt","completedAt","visualDoc","pullRequestNumber","pullRequestTitle"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"environmentId":{"type":"string"},"pullRequestId":{"nullable":true,"type":"string"},"commitSha":{"type":"string"},"branch":{"type":"string"},"summary":{"nullable":true,"type":"string"},"findings":{"type":"array","items":{"title":"CodeReviewFinding","type":"object","required":["id","severity","category","bestPractice","title","description"],"properties":{"id":{"type":"string"},"severity":{"anyOf":[{"enum":["critical"],"type":"string"},{"enum":["warning"],"type":"string"},{"enum":["suggestion"],"type":"string"}]},"category":{"type":"string"},"bestPractice":{"type":"string"},"file":{"type":"string"},"line":{"type":"number"},"title":{"type":"string"},"description":{"type":"string"},"suggestion":{"type":"string"},"fixPrompt":{"type":"string"}}}},"criticalCount":{"type":"number"},"warningCount":{"type":"number"},"suggestionCount":{"type":"number"},"metadata":{"nullable":true,"type":"object","properties":{"model":{"type":"string"},"reviewDuration":{"type":"number"},"bestPracticesVersion":{"type":"string"},"filesAnalyzed":{"type":"number"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"commentId":{"nullable":true,"type":"number"},"checkRunId":{"nullable":true,"type":"number"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"visualDoc":{"description":"Always null in lists. Fetch the code review to get the visual doc.","type":"null"},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestTitle":{"nullable":true,"type":"string"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/code-reviews/{reviewId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceCodeReview","summary":"Get a code review","description":"Returns a single code review with its findings, PR link and any active fix agent session. Requires scope `read:code-reviews` in addition to `read:services`. Returns 404 if not found, 403 if it belongs to a different service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewDetail","type":"object","required":["id","serviceId","environmentId","pullRequestId","commitSha","branch","summary","findings","criticalCount","warningCount","suggestionCount","metadata","status","errorMessage","jobId","commentId","checkRunId","createdAt","completedAt","visualDoc","pullRequestNumber","pullRequestTitle","fixAgentSession","findingStates"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"environmentId":{"type":"string"},"pullRequestId":{"nullable":true,"type":"string"},"commitSha":{"type":"string"},"branch":{"type":"string"},"summary":{"nullable":true,"type":"string"},"findings":{"type":"array","items":{"title":"CodeReviewFinding","type":"object","required":["id","severity","category","bestPractice","title","description"],"properties":{"id":{"type":"string"},"severity":{"anyOf":[{"enum":["critical"],"type":"string"},{"enum":["warning"],"type":"string"},{"enum":["suggestion"],"type":"string"}]},"category":{"type":"string"},"bestPractice":{"type":"string"},"file":{"type":"string"},"line":{"type":"number"},"title":{"type":"string"},"description":{"type":"string"},"suggestion":{"type":"string"},"fixPrompt":{"type":"string"}}}},"criticalCount":{"type":"number"},"warningCount":{"type":"number"},"suggestionCount":{"type":"number"},"metadata":{"nullable":true,"type":"object","properties":{"model":{"type":"string"},"reviewDuration":{"type":"number"},"bestPracticesVersion":{"type":"string"},"filesAnalyzed":{"type":"number"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"commentId":{"nullable":true,"type":"number"},"checkRunId":{"nullable":true,"type":"number"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"visualDoc":{"nullable":true,"title":"VisualReviewDoc","type":"object","required":["version","blocks"],"properties":{"version":{"enum":[1],"type":"number"},"truncated":{"type":"boolean"},"blocks":{"type":"array","items":{"title":"VisualReviewBlock","anyOf":[{"type":"object","required":["type","markdown"],"properties":{"type":{"enum":["summary"],"type":"string"},"markdown":{"type":"string"}}},{"type":"object","required":["type","entries"],"properties":{"type":{"enum":["file-tree"],"type":"string"},"entries":{"type":"array","items":{"type":"object","required":["path","change"],"properties":{"path":{"type":"string"},"change":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["deleted"],"type":"string"},{"enum":["renamed"],"type":"string"}]},"note":{"type":"string"}}}}}},{"type":"object","required":["type","entities"],"properties":{"type":{"enum":["data-model"],"type":"string"},"title":{"type":"string"},"entities":{"type":"array","items":{"type":"object","required":["name","change","fields"],"properties":{"name":{"type":"string"},"change":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["deleted"],"type":"string"}]},"file":{"type":"string"},"fields":{"type":"array","items":{"type":"object","required":["name","dataType"],"properties":{"name":{"type":"string"},"dataType":{"type":"string"},"change":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["deleted"],"type":"string"}]},"note":{"type":"string"}}}}}}},"relations":{"type":"array","items":{"type":"object","required":["from","to"],"properties":{"from":{"type":"string"},"to":{"type":"string"},"label":{"type":"string"}}}}}},{"type":"object","required":["type","endpoints"],"properties":{"type":{"enum":["api-endpoint"],"type":"string"},"title":{"type":"string"},"endpoints":{"type":"array","items":{"type":"object","required":["method","path","change"],"properties":{"method":{"type":"string"},"path":{"type":"string"},"change":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["deleted"],"type":"string"}]},"description":{"type":"string"},"file":{"type":"string"}}}}}},{"type":"object","required":["type","mermaid"],"properties":{"type":{"enum":["architecture"],"type":"string"},"title":{"type":"string"},"mermaid":{"type":"string"}}},{"type":"object","required":["type","tabs"],"properties":{"type":{"enum":["diff-tabs"],"type":"string"},"tabs":{"type":"array","items":{"type":"object","required":["id","title","narrative","files"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"narrative":{"type":"string"},"files":{"type":"array","items":{"type":"object","required":["path"],"properties":{"path":{"type":"string"},"patch":{"type":"string"}}}},"findingIds":{"type":"array","items":{"type":"string"}},"truncated":{"type":"boolean"}}}}}}]}}}},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestTitle":{"nullable":true,"type":"string"},"fixAgentSession":{"nullable":true,"type":"object","required":["id","status","latestCommitSha"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"latestCommitSha":{"nullable":true,"type":"string"}}},"findingStates":{"type":"array","items":{"type":"object","required":["findingId","disposition","dismissReason","fixCommitSha"],"properties":{"findingId":{"type":"string"},"disposition":{"anyOf":[{"enum":["dismissed"],"type":"string"},{"enum":["sent"],"type":"string"},{"enum":["fixed"],"type":"string"}]},"dismissReason":{"nullable":true,"type":"string"},"fixCommitSha":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/code-reviews/{reviewId}/file-diff":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true},{"schema":{"type":"string","minLength":1,"maxLength":1024},"in":"query","name":"path","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceCodeReviewFileDiff","summary":"Get a file diff for a code review","description":"Fetches a single file diff on demand between the base branch and the reviewed commit from GitHub. Requires scope `read:code-reviews` in addition to `read:services`. Returns 400 if not a repo service or GitHub App not configured, 404 if the review or file is not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewFileDiff","type":"object","required":["fileDiff"],"properties":{"fileDiff":{"type":"object","required":["path","status"],"properties":{"path":{"type":"string"},"status":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["removed"],"type":"string"},{"enum":["renamed"],"type":"string"},{"enum":["copied"],"type":"string"},{"enum":["changed"],"type":"string"},{"enum":["unchanged"],"type":"string"}]},"previousPath":{"type":"string"},"patch":{"description":"Unified diff hunks. Absent for binary or oversized files.","type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/code-reviews/{reviewId}/retry":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"retryServiceCodeReview","summary":"Retry a failed code review","description":"Creates a new code review for the current pull request head commit and enqueues the review job, carrying over the GitHub check-run and comment ids. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`. Returns 400 if the review is not in an error state or the service is not a repo type, 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewRetried","type":"object","required":["reviewId","jobId"],"properties":{"reviewId":{"type":"string"},"jobId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/code-reviews/{reviewId}/findings/{findingId}":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true},{"schema":{"type":"string","minLength":1,"maxLength":255},"in":"path","name":"findingId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateServiceCodeReviewFinding","summary":"Dismiss or reopen a code review finding","description":"Sets the triage disposition of a single finding within a code review. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`. Returns 404 if the review or finding is not found, 403 if the review does not belong to this service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewFindingDisposition","type":"object","required":["findingId","disposition"],"properties":{"findingId":{"type":"string"},"disposition":{"anyOf":[{"enum":["dismissed"],"type":"string"},{"enum":["open"],"type":"string"}]}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["disposition"],"properties":{"disposition":{"anyOf":[{"enum":["dismissed"],"type":"string"},{"enum":["open"],"type":"string"}]},"dismissReason":{"minLength":1,"maxLength":255,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["disposition"],"properties":{"disposition":{"anyOf":[{"enum":["dismissed"],"type":"string"},{"enum":["open"],"type":"string"}]},"dismissReason":{"minLength":1,"maxLength":255,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["disposition"],"properties":{"disposition":{"anyOf":[{"enum":["dismissed"],"type":"string"},{"enum":["open"],"type":"string"}]},"dismissReason":{"minLength":1,"maxLength":255,"type":"string"}}}}}}}},"/api/service/{serviceId}/code-reviews/{reviewId}/fix":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"fixServiceCodeReviewFindings","summary":"Spawn an agent to fix code review findings","description":"Selects findings and comments and spawns or reuses a coding agent session that pushes fixes to the pull request branch. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`, and an available sandbox-coder AI harness. Returns 400 if the review is not completed, the service is not a repo type, no findings or comments are selected, finding IDs are unknown, the repository URL is invalid, or AI features or the selected model are unavailable.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewFixStarted","type":"object","required":["reviewId","sessionId","runId"],"properties":{"reviewId":{"type":"string"},"sessionId":{"type":"string"},"runId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["findingIds"],"properties":{"findingIds":{"maxItems":15,"type":"array","items":{"minLength":1,"maxLength":200,"type":"string"}},"comments":{"maxItems":30,"type":"array","items":{"type":"object","required":["file","body"],"properties":{"file":{"minLength":1,"maxLength":1024,"type":"string"},"line":{"minimum":0,"type":"number"},"side":{"anyOf":[{"enum":["additions"],"type":"string"},{"enum":["deletions"],"type":"string"}]},"body":{"minLength":1,"maxLength":4000,"type":"string"}}}}}}},"multipart/form-data":{"schema":{"type":"object","required":["findingIds"],"properties":{"findingIds":{"maxItems":15,"type":"array","items":{"minLength":1,"maxLength":200,"type":"string"}},"comments":{"maxItems":30,"type":"array","items":{"type":"object","required":["file","body"],"properties":{"file":{"minLength":1,"maxLength":1024,"type":"string"},"line":{"minimum":0,"type":"number"},"side":{"anyOf":[{"enum":["additions"],"type":"string"},{"enum":["deletions"],"type":"string"}]},"body":{"minLength":1,"maxLength":4000,"type":"string"}}}}}}},"text/plain":{"schema":{"type":"object","required":["findingIds"],"properties":{"findingIds":{"maxItems":15,"type":"array","items":{"minLength":1,"maxLength":200,"type":"string"}},"comments":{"maxItems":30,"type":"array","items":{"type":"object","required":["file","body"],"properties":{"file":{"minLength":1,"maxLength":1024,"type":"string"},"line":{"minimum":0,"type":"number"},"side":{"anyOf":[{"enum":["additions"],"type":"string"},{"enum":["deletions"],"type":"string"}]},"body":{"minLength":1,"maxLength":4000,"type":"string"}}}}}}}}}}},"/api/service/{serviceId}/code-review-learnings":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceCodeReviewLearnings","summary":"List code review learnings for a service","description":"Returns reviewer instructions taught via dismiss-with-reason, injected into future review prompts for this service. Requires scope `read:code-reviews` in addition to `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewLearningList","type":"object","required":["learnings"],"properties":{"learnings":{"type":"array","items":{"title":"CodeReviewLearning","type":"object","required":["id","serviceId","agentType","instruction","sourcePrCodeReviewId","sourceFindingId","active","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"instruction":{"type":"string"},"sourcePrCodeReviewId":{"nullable":true,"type":"string"},"sourceFindingId":{"nullable":true,"type":"string"},"active":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createServiceCodeReviewLearning","summary":"Create a code review learning","description":"Adds a reviewer instruction for a service, optionally linked to the review and finding it was taught from. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`. Returns 400 if a given source review does not belong to this service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewLearningResult","type":"object","required":["learning"],"properties":{"learning":{"title":"CodeReviewLearning","type":"object","required":["id","serviceId","agentType","instruction","sourcePrCodeReviewId","sourceFindingId","active","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"instruction":{"type":"string"},"sourcePrCodeReviewId":{"nullable":true,"type":"string"},"sourceFindingId":{"nullable":true,"type":"string"},"active":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["instruction"],"properties":{"instruction":{"minLength":1,"maxLength":2000,"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"sourceReviewId":{"type":"string"},"sourceFindingId":{"maxLength":255,"type":"string"}},"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","required":["instruction"],"properties":{"instruction":{"minLength":1,"maxLength":2000,"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"sourceReviewId":{"type":"string"},"sourceFindingId":{"maxLength":255,"type":"string"}},"additionalProperties":false}},"text/plain":{"schema":{"type":"object","required":["instruction"],"properties":{"instruction":{"minLength":1,"maxLength":2000,"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"sourceReviewId":{"type":"string"},"sourceFindingId":{"maxLength":255,"type":"string"}},"additionalProperties":false}}}}}},"/api/service/{serviceId}/code-review-learnings/{learningId}":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"learningId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateServiceCodeReviewLearning","summary":"Update a code review learning","description":"Toggles a learning active/inactive or edits its instruction text. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`. Returns 400 if neither field is provided, 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewLearningResult","type":"object","required":["learning"],"properties":{"learning":{"title":"CodeReviewLearning","type":"object","required":["id","serviceId","agentType","instruction","sourcePrCodeReviewId","sourceFindingId","active","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"agentType":{"anyOf":[{"enum":["code-review"],"type":"string"},{"enum":["sandbox-coder"],"type":"string"}]},"instruction":{"type":"string"},"sourcePrCodeReviewId":{"nullable":true,"type":"string"},"sourceFindingId":{"nullable":true,"type":"string"},"active":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"instruction":{"minLength":1,"maxLength":2000,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"instruction":{"minLength":1,"maxLength":2000,"type":"string"}}}},"text/plain":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"instruction":{"minLength":1,"maxLength":2000,"type":"string"}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"learningId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteServiceCodeReviewLearning","summary":"Delete a code review learning","description":"Removes a reviewer instruction from a service. Requires scopes `read:code-reviews`, `write:code-reviews`, `read:services` and `write:services`. Returns 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewLearningDeleted","type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/environments/stable":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceStableEnvironment","summary":"Get the stable environment of a service","description":"Returns the stable (production) environment of a service with its active deployment and computed service state. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"StableEnvironment","type":"object","required":["environment"],"properties":{"environment":{"nullable":true,"title":"ServiceEnvironment","type":"object","required":["id","serviceId","type","argoAppName","pullRequestNumber","branch","previewUrl","envVars","currentReplicas","desiredReplicas","podStatus","createdAt","closedAt","activeDeployment","latestDeploymentId","latestDeploymentStatus","hasRecentOom","lastOomAt","watcherStatus","watcherMetadata","serviceState","scaledDownAt","scaledDownReason","scaledDownRestartCount","scaledDownPodName"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"type":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"argoAppName":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"branch":{"nullable":true,"type":"string"},"previewUrl":{"nullable":true,"type":"string"},"envVars":{"nullable":true,"description":"Env var entries, each either `{ key, type: \"manual\", value, stage? }` or `{ key, type: \"linked\", serviceId, serviceKey }`.","type":"array","items":{}},"currentReplicas":{"type":"number"},"desiredReplicas":{"type":"number"},"podStatus":{"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"createdAt":{"format":"date-time","type":"string"},"closedAt":{"nullable":true,"format":"date-time","type":"string"},"activeDeployment":{"nullable":true,"type":"object","required":["id","status","deployedAt","commitSha","branch","refType","imageTag","statusInfo"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"deployedAt":{"format":"date-time","type":"string"},"commitSha":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"imageTag":{"nullable":true,"type":"string"},"statusInfo":{"title":"DeploymentStatusInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"queuePosition":{"type":"number"}}}}},"latestDeploymentId":{"nullable":true,"type":"string"},"latestDeploymentStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"lastOomAt":{"nullable":true,"format":"date-time","type":"string"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["down"],"type":"string"},{"enum":["idle"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["podCount","readyCount","desiredCount","lastEventAt"],"properties":{"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"lastEventAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"scaledDownAt":{"nullable":true,"format":"date-time","type":"string"},"scaledDownReason":{"nullable":true,"type":"string"},"scaledDownRestartCount":{"nullable":true,"type":"number"},"scaledDownPodName":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/environments/previews":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServicePreviewEnvironments","summary":"List preview environments for a service","description":"Returns preview environments with active deployments, sorted newest first, excluding envs with no intended pods such as code-review-only ones. Requires scope `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"PreviewEnvironmentList","type":"object","required":["environments"],"properties":{"environments":{"type":"array","items":{"title":"ServiceEnvironment","type":"object","required":["id","serviceId","type","argoAppName","pullRequestNumber","branch","previewUrl","envVars","currentReplicas","desiredReplicas","podStatus","createdAt","closedAt","activeDeployment","latestDeploymentId","latestDeploymentStatus","hasRecentOom","lastOomAt","watcherStatus","watcherMetadata","serviceState","scaledDownAt","scaledDownReason","scaledDownRestartCount","scaledDownPodName"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"type":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"argoAppName":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"branch":{"nullable":true,"type":"string"},"previewUrl":{"nullable":true,"type":"string"},"envVars":{"nullable":true,"description":"Env var entries, each either `{ key, type: \"manual\", value, stage? }` or `{ key, type: \"linked\", serviceId, serviceKey }`.","type":"array","items":{}},"currentReplicas":{"type":"number"},"desiredReplicas":{"type":"number"},"podStatus":{"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"createdAt":{"format":"date-time","type":"string"},"closedAt":{"nullable":true,"format":"date-time","type":"string"},"activeDeployment":{"nullable":true,"type":"object","required":["id","status","deployedAt","commitSha","branch","refType","imageTag","statusInfo"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"deployedAt":{"format":"date-time","type":"string"},"commitSha":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"imageTag":{"nullable":true,"type":"string"},"statusInfo":{"title":"DeploymentStatusInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"queuePosition":{"type":"number"}}}}},"latestDeploymentId":{"nullable":true,"type":"string"},"latestDeploymentStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"lastOomAt":{"nullable":true,"format":"date-time","type":"string"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["down"],"type":"string"},{"enum":["idle"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["podCount","readyCount","desiredCount","lastEventAt"],"properties":{"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"lastEventAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"scaledDownAt":{"nullable":true,"format":"date-time","type":"string"},"scaledDownReason":{"nullable":true,"type":"string"},"scaledDownRestartCount":{"nullable":true,"type":"number"},"scaledDownPodName":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/environments/{environmentId}/deployments":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"environmentId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceEnvironmentDeployments","summary":"List deployments for a service environment","description":"Returns paginated deployments for one environment of a service, enriched with status info. Requires scope `read:services`. Returns 404 if the environment is not found, 403 if it belongs to a different service.","tags":["Services","Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"EnvironmentDeploymentList","type":"object","required":["deployments","total","limit","offset"],"properties":{"deployments":{"type":"array","items":{"title":"DeploymentWithStatusInfo","type":"object","required":["id","deployedAt","status","statusReason","serviceId","organizationId","environmentId","deployedBy","commitSha","imageTag","branch","refType","commitMessage","triggerSource","buildJobId","checkRunId","config","githubInstallationId","previousStatus","cpuMillis","memoryMib","watcherStatus","watcherMetadata","argoOperationObservedAt","dependencyScanEnabled","statusInfo"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"organizationId":{"type":"string"},"environmentId":{"type":"string"},"deployedBy":{"nullable":true,"type":"string"},"commitSha":{"nullable":true,"type":"string"},"imageTag":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"commitMessage":{"nullable":true,"type":"string"},"triggerSource":{"nullable":true,"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["env_change"],"type":"string"}]},"buildJobId":{"nullable":true,"type":"string"},"checkRunId":{"nullable":true,"type":"number"},"config":{"nullable":true,"description":"Config snapshot taken at deploy time. Shape depends on the service type (database, bucket, application).","type":"object","additionalProperties":true},"githubInstallationId":{"nullable":true,"type":"string"},"previousStatus":{"nullable":true,"type":"string"},"cpuMillis":{"nullable":true,"type":"number"},"memoryMib":{"nullable":true,"type":"number"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["rolling-out"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["pods","podCount","readyCount","desiredCount","image","lastEventAt"],"properties":{"pods":{"type":"array","items":{"type":"object","required":["name","image","ready","restartCount","phase"],"properties":{"name":{"type":"string"},"image":{"type":"string"},"ready":{"type":"boolean"},"restartCount":{"type":"number"},"phase":{"type":"string"},"waitingReason":{"type":"string"},"waitingMessage":{"type":"string"},"crashCause":{"anyOf":[{"enum":["app"],"type":"string"},{"enum":["healthcheck"],"type":"string"}]},"observedAt":{"type":"string"},"resourceVersion":{"type":"string"},"deliveryId":{"type":"string"},"sourceVersions":{"type":"object","required":["garageBucket","garageKey"],"properties":{"garageBucket":{"type":"string"},"garageKey":{"type":"string"}}}}}},"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"image":{"type":"string"},"lastEventAt":{"type":"string"},"lastFailureAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"argoOperationObservedAt":{"nullable":true,"type":"string","format":"date-time"},"argoOperationResourceVersion":{"nullable":true,"type":"string"},"argoOperationDeliveryId":{"nullable":true,"type":"string"},"watcherRevision":{"type":"number"},"dependencyScanEnabled":{"type":"boolean"},"dependencyScanReport":{"nullable":true,"type":"object","required":["status","findings","targets","startedAt","completedAt","error"],"properties":{"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"findings":{"type":"array","items":{"type":"object","required":["vulnerabilityId","packageName","installedVersion","fixedVersion","target"],"properties":{"vulnerabilityId":{"type":"string"},"packageName":{"type":"string"},"installedVersion":{"type":"string"},"fixedVersion":{"nullable":true,"type":"string"},"target":{"type":"string"}}}},"targets":{"type":"array","items":{"type":"string"}},"startedAt":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string"},"error":{"nullable":true,"type":"string"}}},"dependencyScanStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"dependencyScanFindingCount":{"type":"number"},"statusInfo":{"title":"DeploymentStatusInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"queuePosition":{"type":"number"}}}}}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/environments/{environmentId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"environmentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceEnvironment","summary":"Get a service environment","description":"Returns one environment of a service with its active deployment and computed service state. Requires scope `read:services`. Returns 404 if the environment is not found, 403 if it belongs to a different service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"EnvironmentResult","type":"object","required":["environment"],"properties":{"environment":{"title":"ServiceEnvironment","type":"object","required":["id","serviceId","type","argoAppName","pullRequestNumber","branch","previewUrl","envVars","currentReplicas","desiredReplicas","podStatus","createdAt","closedAt","activeDeployment","latestDeploymentId","latestDeploymentStatus","hasRecentOom","lastOomAt","watcherStatus","watcherMetadata","serviceState","scaledDownAt","scaledDownReason","scaledDownRestartCount","scaledDownPodName"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"type":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"argoAppName":{"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"branch":{"nullable":true,"type":"string"},"previewUrl":{"nullable":true,"type":"string"},"envVars":{"nullable":true,"description":"Env var entries, each either `{ key, type: \"manual\", value, stage? }` or `{ key, type: \"linked\", serviceId, serviceKey }`.","type":"array","items":{}},"currentReplicas":{"type":"number"},"desiredReplicas":{"type":"number"},"podStatus":{"anyOf":[{"enum":["active"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["suspended"],"type":"string"}]},"createdAt":{"format":"date-time","type":"string"},"closedAt":{"nullable":true,"format":"date-time","type":"string"},"activeDeployment":{"nullable":true,"type":"object","required":["id","status","deployedAt","commitSha","branch","refType","imageTag","statusInfo"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"deployedAt":{"format":"date-time","type":"string"},"commitSha":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"imageTag":{"nullable":true,"type":"string"},"statusInfo":{"title":"DeploymentStatusInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"queuePosition":{"type":"number"}}}}},"latestDeploymentId":{"nullable":true,"type":"string"},"latestDeploymentStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"hasRecentOom":{"type":"boolean"},"lastOomAt":{"nullable":true,"format":"date-time","type":"string"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["down"],"type":"string"},{"enum":["idle"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["podCount","readyCount","desiredCount","lastEventAt"],"properties":{"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"lastEventAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"serviceState":{"title":"ServiceStateInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"},{"enum":["no-deployment"],"type":"string"},{"enum":["blocked"],"type":"string"},{"enum":["paused-billing"],"type":"string"},{"enum":["stopped-crashlooping"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"latestActivity":{"type":"object","required":["kind","label","deploymentId","deploymentStatus"],"properties":{"kind":{"anyOf":[{"enum":["in-flight"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"label":{"type":"string"},"deploymentId":{"type":"string"},"deploymentStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}},"watcherFailureAt":{"type":"string"}}},"scaledDownAt":{"nullable":true,"format":"date-time","type":"string"},"scaledDownReason":{"nullable":true,"type":"string"},"scaledDownRestartCount":{"nullable":true,"type":"number"},"scaledDownPodName":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/environments/{environmentId}/env-vars":{"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"environmentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateServiceEnvironmentEnvVars","summary":"Update env vars for a service environment","description":"Replaces the env vars of one environment, validating unique keys and that any linked service belongs to the same project. Requires scopes `read:services` and `write:services`. Issuing a new AI Gateway key (a gateway row with `keyId: null`) additionally requires `write:ai-gateway` for bearer callers. A stored gateway row the save drops or replaces has its key deleted, or disabled when it has billing history. Keys that could not be issued or retired are listed in `gatewayFailures`. Returns 400 if a new gateway row is submitted while the AI Gateway is not enabled on the instance, 404 if the environment is not found, 403 if a linked service is outside the project or a bearer caller without `write:ai-gateway` submits a new gateway row.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"EnvVarsUpdated","type":"object","required":["success","gatewayFailures"],"properties":{"success":{"type":"boolean"},"gatewayFailures":{"type":"array","items":{"type":"object","required":["key","reason"],"properties":{"key":{"type":"string"},"reason":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["envVars"],"properties":{"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}},"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","required":["envVars"],"properties":{"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}},"additionalProperties":false}},"text/plain":{"schema":{"type":"object","required":["envVars"],"properties":{"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}},"additionalProperties":false}}}}}},"/api/service/{serviceId}/environments/{environmentId}/cleanup":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"environmentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"cleanupServicePreviewEnvironment","summary":"Clean up a preview environment","description":"Deactivates a preview environment, enqueues GitOps cleanup and reconciles the pod pool. Requires scopes `read:services` and `write:services`. Returns 400 if the environment is not a preview type or already closed, 404 if not found.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Success","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/sleep":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"sleepService","summary":"Sleep a service","description":"Suspends a service stable environment immediately, scaling pods to zero and freeing its pool budget. Requires scopes `read:services` and `write:services` and an active subscription.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceSleepResult","type":"object","required":["success","podStatus"],"properties":{"success":{"type":"boolean"},"podStatus":{"enum":["suspended"],"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/wake":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"wakeService","summary":"Wake a service","description":"Restores a suspended service stable environment, gated on free pool budget before flipping to active. Requires scopes `read:services` and `write:services` and an active subscription. Returns 409 if there is not enough free capacity to wake it.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceWakeResult","type":"object","required":["success","podStatus"],"properties":{"success":{"type":"boolean"},"podStatus":{"enum":["active"],"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/resources":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateServiceResources","summary":"Update CPU and memory allocation for a service","description":"Validates the new allocation against pool capacity, persists it, and applies it with a rolling restart. Requires scopes `read:services` and `write:services` and an active subscription. Returns 400 for storage services, which have no resource allocation.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceResourcesUpdated","type":"object","required":["success","cpuMillis","memoryMib"],"properties":{"success":{"type":"boolean"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["cpuMillis","memoryMib"],"properties":{"cpuMillis":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"memoryMib":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["cpuMillis","memoryMib"],"properties":{"cpuMillis":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"memoryMib":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["cpuMillis","memoryMib"],"properties":{"cpuMillis":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"memoryMib":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}}}}}},"/api/service/{serviceId}/replicas":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateServiceReplicas","summary":"Update replica count for a service","description":"Updates the desired replica count of the stable environment without a rebuild, validated against tier limits and pool capacity, then reconciles pods. Requires scopes `read:services` and `write:services` and an active subscription. Returns 409 if the pool cannot fit the requested replicas, 404 if the service has no stable environment yet.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ServiceReplicasUpdated","type":"object","required":["success","replicas"],"properties":{"success":{"type":"boolean"},"replicas":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["replicas"],"properties":{"replicas":{"minimum":1,"maximum":100,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"maximum":100,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["replicas"],"properties":{"replicas":{"minimum":1,"maximum":100,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"maximum":100,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["replicas"],"properties":{"replicas":{"minimum":1,"maximum":100,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"maximum":100,"type":"integer"}]}}}}}}}},"/api/service/{serviceId}/ai-sandbox-code":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"triggerServiceAiSandboxCoder","summary":"Trigger the AI sandbox coder","description":"Creates a coder run on a fresh branch and enqueues its first turn. Requires scopes `read:ai-sandbox-coder`, `write:ai-sandbox-coder`, `read:services` and `write:services`. Returns 400 if the service is not a repo type, has an invalid repo URL, or no GitHub installation covers it.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiSandboxCoderStarted","type":"object","required":["coderId","jobId"],"properties":{"coderId":{"type":"string"},"jobId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"},"baseBranch":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9_][A-Za-z0-9._/-]{0,254}$","type":"string"},"branchPrefix":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9][A-Za-z0-9._/-]{0,60}$","type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"},"baseBranch":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9_][A-Za-z0-9._/-]{0,254}$","type":"string"},"branchPrefix":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9][A-Za-z0-9._/-]{0,60}$","type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"},"baseBranch":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9_][A-Za-z0-9._/-]{0,254}$","type":"string"},"branchPrefix":{"pattern":"^(?!.*\\.\\.)[A-Za-z0-9][A-Za-z0-9._/-]{0,60}$","type":"string"}}}}}}}},"/api/service/{serviceId}/ai-sandbox-coders/{coderId}/respond":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"coderId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"respondServiceAiSandboxCoder","summary":"Send a follow-up turn to an AI sandbox coder run","description":"Enqueues another turn on an existing coder run. Requires scopes `read:ai-sandbox-coder`, `write:ai-sandbox-coder`, `read:services` and `write:services`. Returns 409 if a turn is already in progress, 404 if the run is not found, 403 if it belongs to a different service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JobId","type":"object","required":["jobId"],"properties":{"jobId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"minLength":1,"maxLength":100000,"type":"string"}}}}}}}},"/api/service/{serviceId}/ai-sandbox-coders":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceAiSandboxCoders","summary":"List AI sandbox coder runs for a service","description":"Returns past AI sandbox coder runs for the service, most recent first. Requires scope `read:ai-sandbox-coder` in addition to `read:services`.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiSandboxCoderList","type":"object","required":["aiSandboxCoders"],"properties":{"aiSandboxCoders":{"type":"array","items":{"title":"AiSandboxCoder","type":"object","required":["id","serviceId","prompt","baseBranch","coderBranch","baseCommitSha","coderCommitSha","pullRequestNumber","pullRequestId","pullRequestUrl","changeSummary","filesChanged","conversation","metadata","status","errorMessage","jobId","turnJobIds","createdAt","completedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"prompt":{"type":"string"},"baseBranch":{"type":"string"},"coderBranch":{"nullable":true,"type":"string"},"baseCommitSha":{"nullable":true,"type":"string"},"coderCommitSha":{"nullable":true,"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestId":{"nullable":true,"type":"string"},"pullRequestUrl":{"nullable":true,"type":"string"},"changeSummary":{"nullable":true,"type":"string"},"filesChanged":{"type":"array","items":{"type":"string"}},"conversation":{"type":"array","items":{"type":"object","required":["role","content"],"properties":{"role":{"anyOf":[{"enum":["user"],"type":"string"},{"enum":["assistant"],"type":"string"},{"enum":["tool"],"type":"string"}]},"content":{"type":"string"},"timestamp":{"type":"number"},"toolName":{"type":"string"},"toolInput":{},"toolOutput":{}}}},"metadata":{"nullable":true,"type":"object","properties":{"model":{"type":"string"},"duration":{"type":"number"},"linesAdded":{"type":"number"},"linesRemoved":{"type":"number"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"turnJobIds":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/ai-sandbox-coders/{coderId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"coderId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getServiceAiSandboxCoder","summary":"Get an AI sandbox coder run","description":"Returns a single AI sandbox coder run with its turn jobs. Requires scope `read:ai-sandbox-coder` in addition to `read:services`. Returns 404 if not found, 403 if it belongs to a different service.","tags":["Services"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AiSandboxCoderDetail","type":"object","required":["id","serviceId","prompt","baseBranch","coderBranch","baseCommitSha","coderCommitSha","pullRequestNumber","pullRequestId","pullRequestUrl","changeSummary","filesChanged","conversation","metadata","status","errorMessage","jobId","turnJobIds","createdAt","completedAt","turns"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"prompt":{"type":"string"},"baseBranch":{"type":"string"},"coderBranch":{"nullable":true,"type":"string"},"baseCommitSha":{"nullable":true,"type":"string"},"coderCommitSha":{"nullable":true,"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestId":{"nullable":true,"type":"string"},"pullRequestUrl":{"nullable":true,"type":"string"},"changeSummary":{"nullable":true,"type":"string"},"filesChanged":{"type":"array","items":{"type":"string"}},"conversation":{"type":"array","items":{"type":"object","required":["role","content"],"properties":{"role":{"anyOf":[{"enum":["user"],"type":"string"},{"enum":["assistant"],"type":"string"},{"enum":["tool"],"type":"string"}]},"content":{"type":"string"},"timestamp":{"type":"number"},"toolName":{"type":"string"},"toolInput":{},"toolOutput":{}}}},"metadata":{"nullable":true,"type":"object","properties":{"model":{"type":"string"},"duration":{"type":"number"},"linesAdded":{"type":"number"},"linesRemoved":{"type":"number"}}},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"}]},"errorMessage":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"turnJobIds":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"turns":{"type":"array","items":{"title":"Job","type":"object","required":["id","type","status","createdAt","startedAt","completedAt","params","result","error","retriedFromJobId","entityType","entityId","organizationId","triggeredBy"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"params":{"description":"Job input. Shape depends on the job type."},"result":{"description":"Job output, null until the job finishes. Shape depends on the job type."},"error":{"nullable":true,"type":"string"},"retriedFromJobId":{"nullable":true,"type":"string"},"entityType":{"nullable":true,"type":"string"},"entityId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"triggeredBy":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/service/{serviceId}/custom-domain":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"customDomains":{"type":"array","items":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}}},"required":["customDomains"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"customDomains":{"type":"array","items":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}}},"required":["customDomains"]}},"text/plain":{"schema":{"type":"object","properties":{"customDomains":{"type":"array","items":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}}},"required":["customDomains"]}}},"description":"OK","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"operationId":"listServiceCustomDomains","summary":"List custom domains for a service","description":"Returns the custom domains configured on a service. Requires scope `read:services`.","tags":["Custom domains"]},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"202":{"content":{"application/json":{"schema":{"type":"object","properties":{"customDomain":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}},"required":["customDomain"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"customDomain":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}},"required":["customDomain"]}},"text/plain":{"schema":{"type":"object","properties":{"customDomain":{"type":"object","required":["id","serviceId","domain","normalizedDomain","status","statusReason","tlsStatus","tlsStatusReason","verificationCheckedAt","verifiedAt","verificationToken","verificationHost","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"domain":{"type":"string"},"normalizedDomain":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["verified"],"type":"string"},{"enum":["failed"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"tlsStatus":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["issuing"],"type":"string"},{"enum":["ready"],"type":"string"},{"enum":["failed"],"type":"string"}]},"tlsStatusReason":{"nullable":true,"type":"string"},"verificationCheckedAt":{"nullable":true,"type":"string"},"verifiedAt":{"nullable":true,"type":"string"},"verificationToken":{"type":"string"},"verificationHost":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}},"required":["customDomain"]}}},"description":"Accepted","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}}},"description":"Bad Request","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_tier_limit"],"type":"string"},"maxAllowed":{"type":"number"}},"required":["error","reason","maxAllowed"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_tier_limit"],"type":"string"},"maxAllowed":{"type":"number"}},"required":["error","reason","maxAllowed"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_tier_limit"],"type":"string"},"maxAllowed":{"type":"number"}},"required":["error","reason","maxAllowed"]}}},"description":"Forbidden","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"},"normalizedDomain":{"type":"string"}},"required":["error","reason","normalizedDomain"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"},"normalizedDomain":{"type":"string"}},"required":["error","reason","normalizedDomain"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"},"normalizedDomain":{"type":"string"}},"required":["error","reason","normalizedDomain"]}}},"description":"Conflict","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"operationId":"addServiceCustomDomain","summary":"Add a custom domain to a service","description":"Registers a custom domain on a service and enqueues its verification job. Requires scopes `read:services` and `write:services` and public access enabled on the service. Returns 400 for an invalid domain, 403 if the org tier custom domain limit is exceeded, 409 if the domain is already verified on another service.","tags":["Custom domains"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}}}}}}},"/api/service/{serviceId}/custom-domain/{domainId}/verify":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"domainId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"202":{"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"text/plain":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}}},"description":"Accepted","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}}},"description":"Not Found","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"operationId":"verifyServiceCustomDomain","summary":"Re-trigger verification of a custom domain","description":"Enqueues a new verification attempt for a custom domain. Requires scopes `read:services` and `write:services` and public access enabled on the service. Returns 404 if the domain is not configured.","tags":["Custom domains"]}},"/api/service/{serviceId}/custom-domain/{domainId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"domainId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"text/plain":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}}},"description":"OK","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"enum":["custom_domain_not_configured"],"type":"string"}},"required":["error","reason"]}}},"description":"Not Found","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"502":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}}},"description":"Bad Gateway","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"503":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}},"text/plain":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}},"required":["error","reason"]}}},"description":"Service Unavailable","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}}},"operationId":"removeServiceCustomDomain","summary":"Remove a custom domain from a service","description":"Deletes a custom domain, removes its uptime monitor if any, and redeploys the service to drop the hostname. Requires scopes `read:services` and `write:services`. Returns 404 if the domain is not configured, 502 or 503 if the uptime monitor cleanup fails.","tags":["Custom domains"]}},"/api/service/{serviceId}/uptime-monitor":{"get":{"operationId":"getUptimeMonitor","summary":"Get a service's uptime monitor","description":"Returns the uptime monitor configured for a repository service identified by `serviceId`, if any. Requires scope `read:uptime-monitors`. Returns 200 with available:false if the integration is not configured, 400 if the service is not a repository service, 404 if the service is missing, 403 if the service belongs to another organization, and 502 on an upstream integration error, including a missing upstream monitor.","tags":["Uptime monitors"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"UptimeMonitorState","anyOf":[{"type":"object","required":["available","configured","paused","options"],"properties":{"available":{"enum":[false],"type":"boolean"},"configured":{"enum":[false],"type":"boolean"},"paused":{"type":"boolean"},"options":{"type":"array","items":{"title":"UptimeDomainOption","type":"object","required":["domainType","customDomainId","host","status","selectable"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"nullable":true,"type":"string"},"host":{"type":"string"},"status":{"anyOf":[{"enum":["verified"],"type":"string"},{"enum":["pending"],"type":"string"},{"enum":["failed"],"type":"string"}]},"selectable":{"type":"boolean"}}}}}},{"type":"object","required":["available","configured","paused","options","defaultPath"],"properties":{"available":{"enum":[true],"type":"boolean"},"configured":{"enum":[false],"type":"boolean"},"paused":{"type":"boolean"},"options":{"type":"array","items":{"title":"UptimeDomainOption","type":"object","required":["domainType","customDomainId","host","status","selectable"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"nullable":true,"type":"string"},"host":{"type":"string"},"status":{"anyOf":[{"enum":["verified"],"type":"string"},{"enum":["pending"],"type":"string"},{"enum":["failed"],"type":"string"}]},"selectable":{"type":"boolean"}}}},"defaultPath":{"type":"string"}}},{"type":"object","required":["available","configured","paused","options","monitor"],"properties":{"available":{"enum":[true],"type":"boolean"},"configured":{"enum":[true],"type":"boolean"},"paused":{"type":"boolean"},"options":{"type":"array","items":{"title":"UptimeDomainOption","type":"object","required":["domainType","customDomainId","host","status","selectable"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"nullable":true,"type":"string"},"host":{"type":"string"},"status":{"anyOf":[{"enum":["verified"],"type":"string"},{"enum":["pending"],"type":"string"},{"enum":["failed"],"type":"string"}]},"selectable":{"type":"boolean"}}}},"monitor":{"type":"object","required":["target","status","inMaintenance","uptimeRatio","averageLatencyInMs","lastCheck","history"],"properties":{"target":{"title":"UptimeMonitorTarget","type":"object","required":["domainType","customDomainId","path","url"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"nullable":true,"type":"string"},"path":{"type":"string"},"url":{"type":"string"}}},"status":{"nullable":true,"anyOf":[{"enum":["UP"],"type":"string"},{"enum":["DOWN"],"type":"string"}]},"inMaintenance":{"type":"boolean"},"uptimeRatio":{"nullable":true,"type":"number"},"averageLatencyInMs":{"nullable":true,"type":"number"},"lastCheck":{"nullable":true,"type":"string"},"history":{"type":"array","items":{"type":"object","required":["date","outageCount"],"properties":{"date":{"type":"string"},"outageCount":{"nullable":true,"type":"number"}}}}}}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createUptimeMonitor","summary":"Create or update a service's uptime monitor","description":"Creates or updates the uptime monitor for a repository service identified by `serviceId`, pointing it at a platform or custom domain path. Requires scopes `read:uptime-monitors` and `write:uptime-monitors` and public access to be enabled for the service. Returns 400 if the service is not a repository service, 503 if the uptime monitor integration is not configured, and 502 on an upstream integration error.","tags":["Uptime monitors"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"UptimeMonitorUpsertResult","type":"object","required":["created","changed","target"],"properties":{"created":{"type":"boolean"},"changed":{"type":"boolean"},"target":{"title":"UptimeMonitorTarget","type":"object","required":["domainType","customDomainId","path","url"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"nullable":true,"type":"string"},"path":{"type":"string"},"url":{"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domainType","path"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"type":"string"},"path":{"maxLength":255,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["domainType","path"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"type":"string"},"path":{"maxLength":255,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["domainType","path"],"properties":{"domainType":{"anyOf":[{"enum":["platform"],"type":"string"},{"enum":["custom"],"type":"string"}]},"customDomainId":{"type":"string"},"path":{"maxLength":255,"type":"string"}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteUptimeMonitor","summary":"Delete a service's uptime monitor","description":"Removes the uptime monitor configured for a repository service identified by `serviceId`. Requires scopes `read:uptime-monitors` and `write:uptime-monitors`. Returns 400 if the service is not a repository service, 503 if a monitor exists but the integration is not configured, and 502 on an upstream integration error. Succeeds if no monitor is configured for the service.","tags":["Uptime monitors"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"UptimeMonitorDeleteResult","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/templates/databases/types":{"get":{"operationId":"listDatabaseTypes","summary":"List available database types","description":"Lists database engine types enabled on this instance, for populating the database creation dropdown. Requires scope `read:databases`.","tags":["Databases"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabaseTypeList","type":"object","required":["types"],"properties":{"types":{"type":"array","items":{"type":"object","required":["id","name","description","icon","defaults","options"],"properties":{"id":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"name":{"type":"string"},"description":{"type":"string"},"icon":{"type":"string"},"defaults":{"type":"object","required":["version","storage","replicas"],"properties":{"version":{"type":"string"},"storage":{"type":"string"},"replicas":{"type":"number"}}},"options":{"type":"object","required":["version","storage","replicas"],"properties":{"version":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}}}},"storage":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}}}},"replicas":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"number"},"label":{"type":"string"}}}}}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/templates/databases/service":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"provisionDatabase","summary":"Provision a database service","description":"Creates a database service record in a project for a Postgres or Dragonfly database. Requires scopes `read:databases` and `write:databases`. Returns 404 if the project is not found, 403 if it belongs to another organization, 400 if the database type is not enabled or the replica count exceeds the tier limit.","tags":["Databases"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabaseProvisioned","type":"object","required":["service"],"properties":{"service":{"title":"DatabaseService","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","dbType","projectId"],"properties":{"name":{"type":"string"},"dbType":{"type":"string"},"projectId":{"type":"string"},"replicas":{"minimum":1,"type":"number"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","dbType","projectId"],"properties":{"name":{"type":"string"},"dbType":{"type":"string"},"projectId":{"type":"string"},"replicas":{"minimum":1,"type":"number"}}}},"text/plain":{"schema":{"type":"object","required":["name","dbType","projectId"],"properties":{"name":{"type":"string"},"dbType":{"type":"string"},"projectId":{"type":"string"},"replicas":{"minimum":1,"type":"number"}}}}}}}},"/api/templates/databases/service/{serviceId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getDatabaseService","summary":"Get a database service","description":"Returns a database service with its latest deployment config. Requires scope `read:databases`. Returns 400 if the service is not a database type.","tags":["Databases"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabaseServiceDetail","type":"object","required":["service","latestDeployment"],"properties":{"service":{"title":"DatabaseService","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","dbType"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["db"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"internalUrl":{"type":"string"}}},"latestDeployment":{"nullable":true,"title":"DeploymentConfigSnapshot","type":"object","required":["id","status","deployedAt","config"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedAt":{"format":"date-time","type":"string"},"config":{"description":"Config snapshot taken at deploy time. Shape depends on the service type (database, bucket, application).","type":"object","additionalProperties":true}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"provisionS3Bucket","summary":"Provision an S3 bucket","description":"Creates an S3-compatible bucket for a project, allocating part of the organization's storage quota and starting an async deployment. Requires scopes `read:services` and `write:services`. Returns 404 if the project is not found, 403 if it belongs to a different organization, and 402 if the requested size exceeds the organization's remaining storage quota.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketProvisioned","type":"object","required":["service","deploymentId"],"properties":{"service":{"description":"Always the `s3` variant for this endpoint. The repository declares the union with the artifacts bucket.","anyOf":[{"title":"S3Service","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"}}},{"title":"ArtifactsService","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["artifacts"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"}}}]},"deploymentId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","projectId"],"properties":{"name":{"type":"string"},"projectId":{"type":"string"},"storageGb":{"exclusiveMinimum":0,"type":"number"},"public":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","projectId"],"properties":{"name":{"type":"string"},"projectId":{"type":"string"},"storageGb":{"exclusiveMinimum":0,"type":"number"},"public":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["name","projectId"],"properties":{"name":{"type":"string"},"projectId":{"type":"string"},"storageGb":{"exclusiveMinimum":0,"type":"number"},"public":{"type":"boolean"}}}}}}}},"/api/services/s3/{serviceId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getS3Bucket","summary":"Get an S3 bucket service","description":"Returns an S3 bucket's service record and the deployment config that is actually live on the bucket, identified by `serviceId`. Requires scope `read:services`. Returns 404 if the service does not exist or is not an S3 bucket.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketDetail","type":"object","required":["service","latestDeployment"],"properties":{"service":{"title":"S3Service","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","storageQuotaBytes"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["s3"],"type":"string"},"internalUrl":{"type":"string"},"storageQuotaBytes":{"type":"number"}}},"latestDeployment":{"description":"The deployment config live on the bucket. Null until a deployment has been reconciled.","nullable":true,"title":"DeploymentConfigSnapshot","type":"object","required":["id","status","deployedAt","config"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"deployedAt":{"format":"date-time","type":"string"},"config":{"description":"Config snapshot taken at deploy time. Shape depends on the service type (database, bucket, application).","type":"object","additionalProperties":true}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteS3Bucket","summary":"Delete an S3 bucket","description":"Deletes an S3 bucket identified by `serviceId`, removes env vars that other services linked to it and redeploys those services, then enqueues a destroy job for the bucket's stable environment. Requires scopes `read:services` and `write:services`. Returns 404 if the service is not an S3 bucket.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Success","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/credentials":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getS3BucketCredentials","summary":"Get live S3 bucket credentials","description":"Returns live decrypted access key, secret key, endpoint and bucket URLs for an S3 bucket identified by `serviceId`. Despite being a GET, this requires write-level access because live credentials are effectively write access: the caller needs a write-capable organization role and, for bearer tokens, the `write:services` scope. Returns 403 if the role or token scope is insufficient, and 404 if the service is not an S3 bucket or has no credentials yet.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketCredentials","type":"object","required":["accessKeyId","secretAccessKey","externalUrl","endpoint","bucketName","region","public"],"properties":{"accessKeyId":{"type":"string"},"secretAccessKey":{"type":"string"},"externalUrl":{"type":"string"},"endpoint":{"type":"string"},"bucketName":{"type":"string"},"region":{"type":"string"},"publicUrl":{"type":"string"},"public":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/public":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"setS3BucketPublicAccess","summary":"Toggle public access on an S3 bucket","description":"Toggles public read access on an S3 bucket identified by `serviceId` and redeploys it with the updated config. Requires scopes `read:services` and `write:services`. Returns 404 if the service is not an S3 bucket or has no deployment config yet.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketPublicAccess","type":"object","required":["deploymentId","public"],"properties":{"deploymentId":{"type":"string"},"public":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}}}}}},"/api/services/s3/{serviceId}/storage":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"resizeS3BucketStorage","summary":"Resize an S3 bucket's storage quota","description":"Resizes an S3 bucket's storage quota, identified by `serviceId`, and redeploys it. Requires scopes `read:services` and `write:services`. Returns 400 if the requested size is not greater than 0, 402 if it exceeds the organization's remaining storage quota, and 404 if the service is not an S3 bucket or has no deployment config yet.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketStorageResized","type":"object","required":["deploymentId","storageGb"],"properties":{"deploymentId":{"type":"string"},"storageGb":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}},"multipart/form-data":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}},"text/plain":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}}}}}},"/api/services/s3/{serviceId}/rotate-credentials":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"rotateS3BucketCredentials","summary":"Rotate an S3 bucket's credentials","description":"Generates new access and secret keys for an S3 bucket identified by `serviceId` and redeploys it with the rotated credentials. Requires scopes `read:services` and `write:services`. Returns 404 if the service is not an S3 bucket or has no deployment config yet, and 500 if the deploy job fails to enqueue.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3BucketCredentialsRotated","type":"object","required":["deploymentId"],"properties":{"deploymentId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/objects":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"prefix","required":false},{"schema":{"type":"string"},"in":"query","name":"continuationToken","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listS3Objects","summary":"List objects in an S3 bucket","description":"Lists objects in an S3 bucket identified by `serviceId`, under an optional key prefix, paginated via a continuation token. Requires scope `read:s3-objects`.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3ObjectList","type":"object","required":["prefixes","objects","isTruncated","nextContinuationToken"],"properties":{"prefixes":{"type":"array","items":{"type":"string"}},"objects":{"type":"array","items":{"type":"object","required":["key","size","lastModified","etag"],"properties":{"key":{"type":"string"},"size":{"type":"number"},"lastModified":{"nullable":true,"format":"date-time","type":"string"},"etag":{"nullable":true,"type":"string"}}}},"isTruncated":{"type":"boolean"},"nextContinuationToken":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/objects/head":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"headS3Object","summary":"Get metadata for an S3 object","description":"Returns object metadata (size, content type, etc.) for a single key in an S3 bucket identified by `serviceId`, without downloading its body. Requires scope `read:s3-objects`.","tags":["Object storage"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3ObjectMetadata","type":"object","required":["key","size","contentType","lastModified","etag"],"properties":{"key":{"type":"string"},"size":{"type":"number"},"contentType":{"nullable":true,"type":"string"},"lastModified":{"nullable":true,"format":"date-time","type":"string"},"etag":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/objects/download":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"downloadS3Object","summary":"Download an S3 object","description":"Streams the raw contents of one object from an S3 bucket identified by `serviceId`, for download. Requires scope `read:s3-objects`.","tags":["Object storage"],"responses":{"200":{"description":"Raw object bytes served as an attachment with the stored content type. Empty body (204) if the object has no content.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/s3/{serviceId}/objects/preview":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"previewS3Object","summary":"Preview an S3 object","description":"Returns a preview-safe representation of an object from an S3 bucket identified by `serviceId`, for in-browser viewing. Requires scope `read:s3-objects`.","tags":["Object storage"],"responses":{"200":{"description":"Inline preview. Text-like objects (including SVG) are returned as plain text capped at 256 KiB. Images up to 5 MiB are returned with their own content type.","content":{"text/plain":{"schema":{"type":"string"}},"image/*":{"schema":{"type":"string","format":"binary"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"publishArtifact","summary":"Publish a page (artifact)","description":"Idempotently publishes a page (artifact) under a slug: full-syncs the given files to the organization pages bucket and provisions that bucket on first use. Private by default, so a new slug needs basicAuthUsername and basicAuthPassword or public:true. Requires scopes `read:artifacts` and `write:artifacts`. Returns 202 while the bucket provisions or a hostname is still needed, and 402 when the storage quota is exceeded.","tags":["Pages"],"responses":{"200":{"description":"Page published","content":{"application/json":{"schema":{"title":"ArtifactPublished","type":"object","required":["slug","status","publicationStatus","url","legacyUrl","hostname","uploaded","deleted"],"properties":{"slug":{"type":"string"},"status":{"enum":["published"],"type":"string"},"publicationStatus":{"enum":["published"],"type":"string"},"url":{"nullable":true,"type":"string"},"legacyUrl":{"nullable":true,"type":"string"},"hostname":{"nullable":true,"type":"string"},"uploaded":{"type":"number"},"deleted":{"type":"number"},"warning":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"202":{"description":"Accepted: the bucket is still provisioning (retry the same publish) or files were uploaded and a hostname is still needed","content":{"application/json":{"schema":{"anyOf":[{"title":"ArtifactProvisioning","type":"object","required":["status"],"properties":{"status":{"enum":["provisioning"],"type":"string"}}},{"title":"ArtifactNeedsHostname","type":"object","required":["slug","status","publicationStatus","url","legacyUrl","hostname","uploaded","deleted","warning"],"properties":{"slug":{"type":"string"},"status":{"enum":["needs_hostname"],"type":"string"},"publicationStatus":{"enum":["draft"],"type":"string"},"url":{"type":"null"},"legacyUrl":{"type":"null"},"hostname":{"type":"null"},"uploaded":{"type":"number"},"deleted":{"type":"number"},"warning":{"type":"string"}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["files"],"properties":{"slug":{"type":"string"},"hostname":{"maxLength":63,"type":"string"},"title":{"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"storageMb":{"minimum":100,"type":"number"},"files":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","required":["path","content"],"properties":{"path":{"minLength":1,"type":"string"},"content":{"type":"string"},"encoding":{"anyOf":[{"enum":["utf8"],"type":"string"},{"enum":["base64"],"type":"string"}]}}}}}}},"multipart/form-data":{"schema":{"type":"object","required":["files"],"properties":{"slug":{"type":"string"},"hostname":{"maxLength":63,"type":"string"},"title":{"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"storageMb":{"minimum":100,"type":"number"},"files":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","required":["path","content"],"properties":{"path":{"minLength":1,"type":"string"},"content":{"type":"string"},"encoding":{"anyOf":[{"enum":["utf8"],"type":"string"},{"enum":["base64"],"type":"string"}]}}}}}}},"text/plain":{"schema":{"type":"object","required":["files"],"properties":{"slug":{"type":"string"},"hostname":{"maxLength":63,"type":"string"},"title":{"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"storageMb":{"minimum":100,"type":"number"},"files":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","required":["path","content"],"properties":{"path":{"minLength":1,"type":"string"},"content":{"type":"string"},"encoding":{"anyOf":[{"enum":["utf8"],"type":"string"},{"enum":["base64"],"type":"string"}]}}}}}}}}}},"get":{"parameters":[{"schema":{"minimum":1,"maximum":100,"anyOf":[{"format":"numeric","default":0,"type":"string"},{"minimum":1,"maximum":100,"type":"number"}]},"in":"query","name":"limit","required":false},{"schema":{"minimum":0,"anyOf":[{"format":"numeric","default":0,"type":"string"},{"minimum":0,"type":"number"}]},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listArtifacts","summary":"List pages (artifacts)","description":"Lists published and draft pages (artifacts) for the active organization, offset-paginated. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ArtifactList","type":"object","required":["artifacts","limit","offset"],"properties":{"artifacts":{"type":"array","items":{"title":"Artifact","type":"object","required":["slug","publicationStatus","title","sizeBytes","fileCount","url","legacyUrl","hostname","isPublic","isDisabled","basicAuthUsername","createdAt","updatedAt"],"properties":{"slug":{"type":"string"},"publicationStatus":{"anyOf":[{"enum":["draft"],"type":"string"},{"enum":["published"],"type":"string"}]},"title":{"nullable":true,"type":"string"},"sizeBytes":{"type":"number"},"fileCount":{"type":"number"},"url":{"nullable":true,"type":"string"},"legacyUrl":{"nullable":true,"type":"string"},"hostname":{"nullable":true,"type":"string"},"isPublic":{"type":"boolean"},"isDisabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/hostname-available":{"get":{"parameters":[{"schema":{"type":"string","maxLength":63},"in":"query","name":"name","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"checkArtifactHostnameAvailability","summary":"Check page hostname availability","description":"Checks whether a vanity hostname is available for a page (artifact) on the name.rock8cloud.page namespace. Rate-limited per user. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ArtifactHostnameAvailability","type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"error":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/{slug}":{"get":{"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$","maxLength":63},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getArtifact","summary":"Get a page (artifact)","description":"Returns one page (artifact) identified by `slug` in the active organization. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ArtifactDetail","type":"object","required":["artifact"],"properties":{"artifact":{"title":"Artifact","type":"object","required":["slug","publicationStatus","title","sizeBytes","fileCount","url","legacyUrl","hostname","isPublic","isDisabled","basicAuthUsername","createdAt","updatedAt"],"properties":{"slug":{"type":"string"},"publicationStatus":{"anyOf":[{"enum":["draft"],"type":"string"},{"enum":["published"],"type":"string"}]},"title":{"nullable":true,"type":"string"},"sizeBytes":{"type":"number"},"fileCount":{"type":"number"},"url":{"nullable":true,"type":"string"},"legacyUrl":{"nullable":true,"type":"string"},"hostname":{"nullable":true,"type":"string"},"isPublic":{"type":"boolean"},"isDisabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$","maxLength":63},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateArtifact","summary":"Update a page (artifact)","description":"Updates the title, access gating (public or basic-auth), hostname or publication state of the page (artifact) identified by `slug`. A takedown by an instance admin blocks the owner from renaming or republishing it. Requires scopes `read:artifacts` and `write:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Artifact","type":"object","required":["slug","publicationStatus","title","sizeBytes","fileCount","url","legacyUrl","hostname","isPublic","isDisabled","basicAuthUsername","createdAt","updatedAt"],"properties":{"slug":{"type":"string"},"publicationStatus":{"anyOf":[{"enum":["draft"],"type":"string"},{"enum":["published"],"type":"string"}]},"title":{"nullable":true,"type":"string"},"sizeBytes":{"type":"number"},"fileCount":{"type":"number"},"url":{"nullable":true,"type":"string"},"legacyUrl":{"nullable":true,"type":"string"},"hostname":{"nullable":true,"type":"string"},"isPublic":{"type":"boolean"},"isDisabled":{"type":"boolean"},"basicAuthUsername":{"nullable":true,"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"nullable":true,"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"hostname":{"minLength":1,"maxLength":63,"type":"string"},"published":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"title":{"nullable":true,"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"hostname":{"minLength":1,"maxLength":63,"type":"string"},"published":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","properties":{"title":{"nullable":true,"maxLength":255,"type":"string"},"public":{"type":"boolean"},"basicAuthUsername":{"minLength":1,"type":"string"},"basicAuthPassword":{"minLength":1,"type":"string"},"hostname":{"minLength":1,"maxLength":63,"type":"string"},"published":{"type":"boolean"}}}}}}},"delete":{"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$","maxLength":63},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteArtifact","summary":"Delete a page (artifact)","description":"Deletes the page (artifact) identified by `slug`: purges its objects from storage and releases its hostname claim. A takedown by an instance admin blocks the owner from deleting it. Requires scopes `read:artifacts` and `write:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ArtifactDeleteResult","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/objects":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"prefix","required":false},{"schema":{"type":"string"},"in":"query","name":"continuationToken","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listArtifactObjects","summary":"List objects in the pages bucket","description":"Lists raw storage objects under `prefix` in the org pages bucket, for the pages object-browsing UI. Requires the bucket to already exist. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3ObjectList","type":"object","required":["prefixes","objects","isTruncated","nextContinuationToken"],"properties":{"prefixes":{"type":"array","items":{"type":"string"}},"objects":{"type":"array","items":{"type":"object","required":["key","size","lastModified","etag"],"properties":{"key":{"type":"string"},"size":{"type":"number"},"lastModified":{"nullable":true,"format":"date-time","type":"string"},"etag":{"nullable":true,"type":"string"}}}},"isTruncated":{"type":"boolean"},"nextContinuationToken":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/objects/head":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"headArtifactObject","summary":"Get metadata for a pages bucket object","description":"Returns size and content-type metadata for one object at `key` in the org pages bucket. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"S3ObjectMetadata","type":"object","required":["key","size","contentType","lastModified","etag"],"properties":{"key":{"type":"string"},"size":{"type":"number"},"contentType":{"nullable":true,"type":"string"},"lastModified":{"nullable":true,"format":"date-time","type":"string"},"etag":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/objects/download":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"downloadArtifactObject","summary":"Download a pages bucket object","description":"Streams the raw bytes of one object at `key` in the org pages bucket. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"Raw object bytes served as an attachment with the stored content type. Empty body (204) if the object has no content.","content":{"application/octet-stream":{"schema":{"format":"binary","type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/objects/preview":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"key","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"previewArtifactObject","summary":"Preview a pages bucket object","description":"Returns an inline, renderable preview of one object at `key` in the org pages bucket. Requires scope `read:artifacts`.","tags":["Pages"],"responses":{"200":{"description":"Inline preview. Text-like objects (including SVG) are returned as plain text capped at 256 KiB. Images up to 5 MiB are returned with their own content type.","content":{"text/plain":{"schema":{"type":"string"}},"image/*":{"schema":{"format":"binary","type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/artifacts/storage":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"resizeArtifactStorage","summary":"Resize the pages storage bucket","description":"Changes the storage cap of the org pages bucket to `storageGb`, redeploying it to apply the new quota. Requires scopes `read:artifacts` and `write:artifacts`. Returns 402 when the new cap exceeds the remaining organization storage quota.","tags":["Pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ArtifactStorage","type":"object","required":["storageGb"],"properties":{"storageGb":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}},"multipart/form-data":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}},"text/plain":{"schema":{"type":"object","required":["storageGb"],"properties":{"storageGb":{"exclusiveMinimum":0,"type":"number"}}}}}}}},"/api/templates/applications/":{"get":{"operationId":"listApplicationTemplates","summary":"List application templates","description":"Lists one-click application templates enabled for this instance, with their config defaults and required env vars. Requires scope `read:services`. Returns 404 if the Applications category is disabled for this instance.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ApplicationTemplateList","type":"object","required":["applications"],"properties":{"applications":{"type":"array","items":{"title":"ApplicationTemplateSummary","type":"object","required":["id","name","description","icon","containerPort","defaults","options","requiredEnvVars"],"properties":{"id":{"enum":["pgweb"],"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"icon":{"type":"string"},"containerPort":{"type":"string"},"defaults":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"string"},"replicas":{"type":"number"}}},"options":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}}}},"replicas":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"number"},"label":{"type":"string"}}}}}}}},"requiredEnvVars":{"type":"array","items":{"type":"object","required":["key","label"],"properties":{"key":{"description":"Env variable name, e.g. DATABASE_URL.","type":"string"},"label":{"type":"string"},"description":{"type":"string"},"linkHint":{"type":"object","required":["serviceType"],"properties":{"serviceType":{"anyOf":[{"enum":["repo"],"type":"string"},{"enum":["db"],"type":"string"},{"enum":["s3"],"type":"string"},{"enum":["application"],"type":"string"},{"enum":["artifacts"],"type":"string"}]},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"key":{"type":"string"}}},"defaultValue":{"type":"string"},"required":{"description":"Deployment is rejected unless the key is filled or linked.","type":"boolean"},"prefill":{"type":"boolean"},"generate":{"enum":["password"],"type":"string"},"secret":{"type":"boolean"},"hidden":{"type":"boolean"}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/templates/applications/{applicationId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"applicationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getApplicationTemplate","summary":"Get an application template","description":"Returns the full definition for one application template identified by `applicationId`. Requires scope `read:services`. Returns 404 if the Applications category is disabled, or the application does not exist or is not enabled.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ApplicationTemplate","type":"object","required":["application"],"properties":{"application":{"title":"ApplicationDefinition","type":"object","required":["id","name","description","icon","containerPort","defaults","options","requiredEnvVars","image","resourceLimits"],"properties":{"id":{"enum":["pgweb"],"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"icon":{"type":"string"},"containerPort":{"type":"string"},"defaults":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"string"},"replicas":{"type":"number"}}},"options":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}}}},"replicas":{"type":"object","required":["label","type"],"properties":{"label":{"type":"string"},"type":{"anyOf":[{"enum":["select"],"type":"string"},{"enum":["input"],"type":"string"}]},"choices":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"number"},"label":{"type":"string"}}}}}}}},"requiredEnvVars":{"type":"array","items":{"type":"object","required":["key","label"],"properties":{"key":{"description":"Env variable name, e.g. DATABASE_URL.","type":"string"},"label":{"type":"string"},"description":{"type":"string"},"linkHint":{"type":"object","required":["serviceType"],"properties":{"serviceType":{"anyOf":[{"enum":["repo"],"type":"string"},{"enum":["db"],"type":"string"},{"enum":["s3"],"type":"string"},{"enum":["application"],"type":"string"},{"enum":["artifacts"],"type":"string"}]},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"key":{"type":"string"}}},"defaultValue":{"type":"string"},"required":{"description":"Deployment is rejected unless the key is filled or linked.","type":"boolean"},"prefill":{"type":"boolean"},"generate":{"enum":["password"],"type":"string"},"secret":{"type":"boolean"},"hidden":{"type":"boolean"}}}},"image":{"type":"string"},"resourceLimits":{"type":"object","required":["cpu","memory"],"properties":{"cpu":{"type":"string"},"memory":{"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/application/":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createApplicationService","summary":"Create an application service","description":"Creates a one-click application service in a project from an enabled template, validates required env vars, allocates an external URL, and starts an async deployment. Requires scopes `read:services` and `write:services`. Returns 404 if the Applications category is disabled or the project is not found, 403 if the project belongs to a different organization, and 400 if the template is missing or disabled or the config is invalid.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ApplicationServiceCreated","type":"object","required":["service","deploymentId"],"properties":{"service":{"title":"ApplicationService","type":"object","required":["id","name","projectId","cpuMillis","memoryMib","type","applicationId","internalUrl","containerPort"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"},"resourcesPendingSince":{"nullable":true,"type":"string","format":"date-time"},"type":{"enum":["application"],"type":"string"},"applicationId":{"type":"string"},"internalUrl":{"type":"string"},"externalUrl":{"type":"string"},"containerPort":{"type":"string"}}},"deploymentId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","applicationId","projectId","version","replicas"],"properties":{"name":{"type":"string"},"applicationId":{"type":"string"},"projectId":{"type":"string"},"version":{"type":"string"},"replicas":{"type":"number"},"internalUrl":{"type":"string"},"slug":{"type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","applicationId","projectId","version","replicas"],"properties":{"name":{"type":"string"},"applicationId":{"type":"string"},"projectId":{"type":"string"},"version":{"type":"string"},"replicas":{"type":"number"},"internalUrl":{"type":"string"},"slug":{"type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}}}},"text/plain":{"schema":{"type":"object","required":["name","applicationId","projectId","version","replicas"],"properties":{"name":{"type":"string"},"applicationId":{"type":"string"},"projectId":{"type":"string"},"version":{"type":"string"},"replicas":{"type":"number"},"internalUrl":{"type":"string"},"slug":{"type":"string"},"envVars":{"type":"array","items":{"anyOf":[{"type":"object","required":["key","type","value"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["manual"],"type":"string"},"value":{"type":"string"},"stage":{"default":"runtime","anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]}}},{"type":"object","required":["key","type","serviceId","serviceKey"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["linked"],"type":"string"},"serviceId":{"type":"string"},"serviceKey":{"type":"string"}}},{"type":"object","required":["key","type","rock8routerOrganizationId","keyId","models","limitEurCents"],"properties":{"key":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","minLength":1,"maxLength":253,"type":"string"},"type":{"enum":["gateway"],"type":"string"},"value":{"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"keyId":{"nullable":true,"minLength":1,"type":"string"},"models":{"minItems":1,"type":"array","items":{"minLength":1,"type":"string"}},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"keyPrefix":{"type":"string"},"isActive":{"type":"boolean"}}}]}}}}}}}}},"/api/services/application/{serviceId}/deploy":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deployApplicationService","summary":"Redeploy an application service","description":"Redeploys an existing application service, identified by `serviceId`, with an updated version and replica count. Requires scopes `read:services` and `write:services`. Returns 400 if the service is not an application service or the config is invalid, and 404 if the project or stable environment is not found.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ApplicationDeployResult","type":"object","required":["success","deploymentId"],"properties":{"success":{"description":"False when the deploy job could not be enqueued. The deployment is then marked failed.","type":"boolean"},"deploymentId":{"type":"string"},"status":{"enum":["pending"],"type":"string"},"error":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"string"},"replicas":{"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"string"},"replicas":{"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["version","replicas"],"properties":{"version":{"type":"string"},"replicas":{"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}}}}}}}},"/api/services/database/{serviceId}/pgweb":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getDatabasePgweb","summary":"Get the pgweb browser of a database","description":"Returns the pgweb application service whose `PGWEB_DATABASE_URL` is linked to the PostgreSQL database `serviceId`, with its deployment status, or `pgweb: null` when none exists. The login is served by `getDatabasePgwebCredentials`. Requires scope `read:services`. Returns 400 if the service is not a PostgreSQL database and 404 if the Applications category is disabled.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabasePgweb","type":"object","required":["pgweb"],"properties":{"pgweb":{"nullable":true,"type":"object","required":["serviceId","environmentId","name","externalUrl","deploymentStatus"],"properties":{"serviceId":{"type":"string"},"environmentId":{"type":"string"},"name":{"type":"string"},"externalUrl":{"nullable":true,"description":"Full public URL pgweb is served on, including the https:// scheme.","type":"string"},"deploymentStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deployDatabasePgweb","summary":"Deploy pgweb for a database","description":"Creates and deploys a pgweb application service linked to the PostgreSQL database `serviceId`, with a generated login, and returns its deployment status. Idempotent: returns the existing pgweb when one is already linked. The login is served by `getDatabasePgwebCredentials`. Requires scopes `read:services` and `write:services`. Returns 400 if the service is not a PostgreSQL database, 404 if the Applications category is disabled, and 409 if another deploy for the same database is still in progress.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabasePgweb","type":"object","required":["pgweb"],"properties":{"pgweb":{"nullable":true,"type":"object","required":["serviceId","environmentId","name","externalUrl","deploymentStatus"],"properties":{"serviceId":{"type":"string"},"environmentId":{"type":"string"},"name":{"type":"string"},"externalUrl":{"nullable":true,"description":"Full public URL pgweb is served on, including the https:// scheme.","type":"string"},"deploymentStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/database/{serviceId}/pgweb/credentials":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getDatabasePgwebCredentials","summary":"Get the pgweb login of a database","description":"Returns the login (`user`, `password`) of the pgweb service linked to the PostgreSQL database `serviceId`. Requires scope `read:services` and a write-capable organization role, and for tokens also scope `write:services`. Viewing the login is audit-logged as `service:credentials-view`. Returns 400 if the service is not a PostgreSQL database, 403 if the role or token cannot view the login, and 404 if the Applications category is disabled or no pgweb is linked.","tags":["Applications"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DatabasePgwebCredentials","type":"object","required":["user","password"],"properties":{"user":{"nullable":true,"description":"PGWEB_AUTH_USER of the pgweb service.","type":"string"},"password":{"nullable":true,"description":"PGWEB_AUTH_PASS of the pgweb service.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/deployment/{serviceId}":{"get":{"operationId":"listServiceDeployments","summary":"List deployments for a service","description":"Lists deployments for a service, enriched with the effective target URL and repo metadata. Requires scope `read:deployments`.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"ServiceDeployment","type":"object","required":["id","deployedAt","status","statusReason","serviceId","organizationId","environmentId","deployedBy","commitSha","imageTag","branch","refType","commitMessage","triggerSource","buildJobId","checkRunId","config","githubInstallationId","previousStatus","cpuMillis","memoryMib","watcherStatus","watcherMetadata","argoOperationObservedAt","dependencyScanEnabled","repoUrl","targetUrl","appName","containerPort","dockerfilePath"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"organizationId":{"type":"string"},"environmentId":{"type":"string"},"deployedBy":{"nullable":true,"type":"string"},"commitSha":{"nullable":true,"type":"string"},"imageTag":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"commitMessage":{"nullable":true,"type":"string"},"triggerSource":{"nullable":true,"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["env_change"],"type":"string"}]},"buildJobId":{"nullable":true,"type":"string"},"checkRunId":{"nullable":true,"type":"number"},"config":{"nullable":true,"description":"Config snapshot taken at deploy time. Shape depends on the service type (database, bucket, application).","type":"object","additionalProperties":true},"githubInstallationId":{"nullable":true,"type":"string"},"previousStatus":{"nullable":true,"type":"string"},"cpuMillis":{"nullable":true,"type":"number"},"memoryMib":{"nullable":true,"type":"number"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["rolling-out"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["pods","podCount","readyCount","desiredCount","image","lastEventAt"],"properties":{"pods":{"type":"array","items":{"type":"object","required":["name","image","ready","restartCount","phase"],"properties":{"name":{"type":"string"},"image":{"type":"string"},"ready":{"type":"boolean"},"restartCount":{"type":"number"},"phase":{"type":"string"},"waitingReason":{"type":"string"},"waitingMessage":{"type":"string"},"crashCause":{"anyOf":[{"enum":["app"],"type":"string"},{"enum":["healthcheck"],"type":"string"}]},"observedAt":{"type":"string"},"resourceVersion":{"type":"string"},"deliveryId":{"type":"string"},"sourceVersions":{"type":"object","required":["garageBucket","garageKey"],"properties":{"garageBucket":{"type":"string"},"garageKey":{"type":"string"}}}}}},"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"image":{"type":"string"},"lastEventAt":{"type":"string"},"lastFailureAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"argoOperationObservedAt":{"nullable":true,"type":"string","format":"date-time"},"argoOperationResourceVersion":{"nullable":true,"type":"string"},"argoOperationDeliveryId":{"nullable":true,"type":"string"},"watcherRevision":{"type":"number"},"dependencyScanEnabled":{"type":"boolean"},"dependencyScanReport":{"nullable":true,"type":"object","required":["status","findings","targets","startedAt","completedAt","error"],"properties":{"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"findings":{"type":"array","items":{"type":"object","required":["vulnerabilityId","packageName","installedVersion","fixedVersion","target"],"properties":{"vulnerabilityId":{"type":"string"},"packageName":{"type":"string"},"installedVersion":{"type":"string"},"fixedVersion":{"nullable":true,"type":"string"},"target":{"type":"string"}}}},"targets":{"type":"array","items":{"type":"string"}},"startedAt":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string"},"error":{"nullable":true,"type":"string"}}},"dependencyScanStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"dependencyScanFindingCount":{"type":"number"},"repoUrl":{"nullable":true,"type":"string"},"targetUrl":{"nullable":true,"description":"Effective public URL of this deployment. Null for private repo services.","type":"string"},"appName":{"type":"string"},"containerPort":{"nullable":true,"type":"string"},"dockerfilePath":{"nullable":true,"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createDeployment","summary":"Create a deployment","description":"Starts a deployment for a service (repo, database, S3 or application type), creating its stable environment if needed and enqueuing the build/deploy job. Requires scopes `read:deployments` and `write:deployments`. Returns 400 for missing type-specific config or an over-tier replica count, 404 if the service or project is not found, or a `blocked` response body if the pod pool has no free capacity.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DeploymentCreated","anyOf":[{"title":"DeploymentQueued","type":"object","required":["success","id","status"],"properties":{"success":{"enum":[true],"type":"boolean"},"id":{"type":"string"},"status":{"enum":["pending"],"type":"string"}}},{"title":"DeploymentStarted","type":"object","required":["success","id","commitSha","commitMessage","branch"],"properties":{"success":{"enum":[true],"type":"boolean"},"id":{"type":"string"},"commitSha":{"nullable":true,"type":"string"},"commitMessage":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"}}},{"title":"DeploymentBlocked","description":"Returned with status 200 instead of a deployment when the organization resource pool has no free capacity. Nothing was built or deployed.","type":"object","required":["success","blocked","environmentId","reason","usage","violated","requested","tier"],"properties":{"success":{"enum":[true],"type":"boolean"},"blocked":{"enum":[true],"type":"boolean"},"environmentId":{"type":"string"},"reason":{"nullable":true,"type":"string"},"usage":{"type":"object","required":["cpu","memory"],"properties":{"cpu":{"type":"object","required":["usedMillis","poolMillis"],"properties":{"usedMillis":{"type":"number"},"poolMillis":{"nullable":true,"type":"number"}}},"memory":{"type":"object","required":["usedMib","poolMib"],"properties":{"usedMib":{"type":"number"},"poolMib":{"nullable":true,"type":"number"}}}}},"violated":{"description":"Pool dimensions that stopped the environment. Empty for non-capacity blocks such as a sleeping service.","type":"array","items":{"type":"string","enum":["cpu","memory"]}},"requested":{"nullable":true,"description":"The environment own demand. Null unless blocked for capacity.","type":"object","required":["cpuMillis","memMib"],"properties":{"cpuMillis":{"type":"number"},"memMib":{"type":"number"}}},"tier":{"type":"string","enum":["pluto","mercury","earth","neptune","enterprise"]}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"},"storage":{"type":"string"},"replicas":{"minimum":1,"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}},"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","properties":{"version":{"type":"string"},"storage":{"type":"string"},"replicas":{"minimum":1,"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}},"additionalProperties":false}},"text/plain":{"schema":{"type":"object","properties":{"version":{"type":"string"},"storage":{"type":"string"},"replicas":{"minimum":1,"type":"number"},"triggerSource":{"enum":["env_change"],"type":"string"}},"additionalProperties":false}}}}}},"/api/deployment/{serviceId}/deployment/{deploymentId}":{"get":{"operationId":"getDeployment","summary":"Get a deployment","description":"Returns the canonical deployment detail projection for one deployment of a service, or null if unbound. Requires scope `read:deployments`.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"nullable":true,"title":"DeploymentDetail","type":"object","required":["id","deployedAt","status","statusReason","serviceId","organizationId","environmentId","deployedBy","commitSha","imageTag","branch","refType","commitMessage","triggerSource","buildJobId","checkRunId","config","githubInstallationId","previousStatus","cpuMillis","memoryMib","watcherStatus","watcherMetadata","argoOperationObservedAt","dependencyScanEnabled","statusInfo","repoUrl","targetUrl","appName","containerPort","dockerfilePath","number"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"organizationId":{"type":"string"},"environmentId":{"type":"string"},"deployedBy":{"nullable":true,"type":"string"},"commitSha":{"nullable":true,"type":"string"},"imageTag":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"commitMessage":{"nullable":true,"type":"string"},"triggerSource":{"nullable":true,"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["env_change"],"type":"string"}]},"buildJobId":{"nullable":true,"type":"string"},"checkRunId":{"nullable":true,"type":"number"},"config":{"nullable":true,"description":"Config snapshot taken at deploy time. Shape depends on the service type (database, bucket, application).","type":"object","additionalProperties":true},"githubInstallationId":{"nullable":true,"type":"string"},"previousStatus":{"nullable":true,"type":"string"},"cpuMillis":{"nullable":true,"type":"number"},"memoryMib":{"nullable":true,"type":"number"},"watcherStatus":{"nullable":true,"anyOf":[{"enum":["unknown"],"type":"string"},{"enum":["rolling-out"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"watcherMetadata":{"nullable":true,"type":"object","required":["pods","podCount","readyCount","desiredCount","image","lastEventAt"],"properties":{"pods":{"type":"array","items":{"type":"object","required":["name","image","ready","restartCount","phase"],"properties":{"name":{"type":"string"},"image":{"type":"string"},"ready":{"type":"boolean"},"restartCount":{"type":"number"},"phase":{"type":"string"},"waitingReason":{"type":"string"},"waitingMessage":{"type":"string"},"crashCause":{"anyOf":[{"enum":["app"],"type":"string"},{"enum":["healthcheck"],"type":"string"}]},"observedAt":{"type":"string"},"resourceVersion":{"type":"string"},"deliveryId":{"type":"string"},"sourceVersions":{"type":"object","required":["garageBucket","garageKey"],"properties":{"garageBucket":{"type":"string"},"garageKey":{"type":"string"}}}}}},"podCount":{"type":"number"},"readyCount":{"type":"number"},"desiredCount":{"type":"number"},"image":{"type":"string"},"lastEventAt":{"type":"string"},"lastFailureAt":{"type":"string"},"failureReason":{"type":"string"},"failedPod":{"type":"string"}}},"argoOperationObservedAt":{"nullable":true,"type":"string","format":"date-time"},"argoOperationResourceVersion":{"nullable":true,"type":"string"},"argoOperationDeliveryId":{"nullable":true,"type":"string"},"watcherRevision":{"type":"number"},"dependencyScanEnabled":{"type":"boolean"},"dependencyScanReport":{"nullable":true,"type":"object","required":["status","findings","targets","startedAt","completedAt","error"],"properties":{"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"findings":{"type":"array","items":{"type":"object","required":["vulnerabilityId","packageName","installedVersion","fixedVersion","target"],"properties":{"vulnerabilityId":{"type":"string"},"packageName":{"type":"string"},"installedVersion":{"type":"string"},"fixedVersion":{"nullable":true,"type":"string"},"target":{"type":"string"}}}},"targets":{"type":"array","items":{"type":"string"}},"startedAt":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string"},"error":{"nullable":true,"type":"string"}}},"dependencyScanStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"dependencyScanFindingCount":{"type":"number"},"statusInfo":{"title":"DeploymentStatusInfo","type":"object","required":["kind","label","tone"],"properties":{"kind":{"anyOf":[{"enum":["queued"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["starting"],"type":"string"},{"enum":["live"],"type":"string"},{"enum":["degraded"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["unknown"],"type":"string"},{"enum":["transitioning"],"type":"string"}]},"label":{"type":"string"},"tone":{"anyOf":[{"enum":["success"],"type":"string"},{"enum":["progress"],"type":"string"},{"enum":["danger"],"type":"string"},{"enum":["neutral"],"type":"string"},{"enum":["warning"],"type":"string"}]},"queuePosition":{"type":"number"}}},"repoUrl":{"nullable":true,"type":"string"},"targetUrl":{"nullable":true,"description":"Effective public URL of this deployment. Null for private repo services.","type":"string"},"appName":{"type":"string"},"containerPort":{"nullable":true,"type":"string"},"dockerfilePath":{"nullable":true,"type":"string"},"number":{"description":"Sequence number within the environment.","type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteDeployment","summary":"Delete a deployment","description":"Deletes a deployment from the cluster and removes its record. Requires scopes `read:deployments` and `write:deployments`. Returns 401 if the account is missing, 404 if the deployment or its environment is not found, 500 if the cluster deletion fails.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SuccessMessage","type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/deployment/{serviceId}/deployment/{deploymentId}/cancel":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"cancelDeployment","summary":"Cancel a running deployment","description":"Requests cancellation of a deployment that is pending, building or deploying, and broadcasts an abort signal to the build worker. Requires scopes `read:deployments` and `write:deployments`. Returns 404 if not found, 400 if the deployment is not in a cancellable state.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SuccessMessage","type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/deployment/{serviceId}/rebuild/{sourceDeploymentId}":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"sourceDeploymentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"rebuildDeployment","summary":"Rebuild a deployment","description":"Creates a new deployment from a source deployment commit SHA, in the same environment as the source. Requires scopes `read:deployments` and `write:deployments`. Returns 404 if the source deployment is not found, 400 if it has no commit SHA or no GitHub installation covers the repository, or a `blocked` response body if the pod pool has no free capacity.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DeploymentRebuilt","anyOf":[{"title":"DeploymentStarted","type":"object","required":["success","id","commitSha","commitMessage","branch"],"properties":{"success":{"enum":[true],"type":"boolean"},"id":{"type":"string"},"commitSha":{"nullable":true,"type":"string"},"commitMessage":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"}}},{"title":"DeploymentBlocked","description":"Returned with status 200 instead of a deployment when the organization resource pool has no free capacity. Nothing was built or deployed.","type":"object","required":["success","blocked","environmentId","reason","usage","violated","requested","tier"],"properties":{"success":{"enum":[true],"type":"boolean"},"blocked":{"enum":[true],"type":"boolean"},"environmentId":{"type":"string"},"reason":{"nullable":true,"type":"string"},"usage":{"type":"object","required":["cpu","memory"],"properties":{"cpu":{"type":"object","required":["usedMillis","poolMillis"],"properties":{"usedMillis":{"type":"number"},"poolMillis":{"nullable":true,"type":"number"}}},"memory":{"type":"object","required":["usedMib","poolMib"],"properties":{"usedMib":{"type":"number"},"poolMib":{"nullable":true,"type":"number"}}}}},"violated":{"description":"Pool dimensions that stopped the environment. Empty for non-capacity blocks such as a sleeping service.","type":"array","items":{"type":"string","enum":["cpu","memory"]}},"requested":{"nullable":true,"description":"The environment own demand. Null unless blocked for capacity.","type":"object","required":["cpuMillis","memMib"],"properties":{"cpuMillis":{"type":"number"},"memMib":{"type":"number"}}},"tier":{"type":"string","enum":["pluto","mercury","earth","neptune","enterprise"]}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/deployment/{serviceId}/rollback":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"rollbackDeployment","summary":"Roll back a service to a previous deployment","description":"Creates a new deployment reusing a source deployment image tag, optionally restoring its CPU/memory allocation on a stable environment. Requires scopes `read:deployments` and `write:deployments`, and an active subscription when restoring resources. Returns 404 if the source deployment is not found, 400 if it has no image tag.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DeploymentRolledBack","type":"object","required":["success","id","resourcesRestored"],"properties":{"success":{"enum":[true],"type":"boolean"},"id":{"type":"string"},"resourcesRestored":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sourceDeploymentId"],"properties":{"sourceDeploymentId":{"type":"string"},"restoreResources":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["sourceDeploymentId"],"properties":{"sourceDeploymentId":{"type":"string"},"restoreResources":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["sourceDeploymentId"],"properties":{"sourceDeploymentId":{"type":"string"},"restoreResources":{"type":"boolean"}}}}}}}},"/api/deployments/":{"get":{"operationId":"listDeployments","summary":"List deployments for the organization","description":"Lists all deployments across every service in the active organization. Requires scope `read:deployments`.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"OrganizationDeployment","type":"object","required":["id","deployedAt","status","statusReason","serviceId","projectId","userId","userPreferredUsername","appName","repoUrl","branch","refType","targetUrl","imageTag","containerPort","dockerfilePath","commitMessage","environmentType"],"properties":{"id":{"type":"string"},"deployedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["building"],"type":"string"},{"enum":["deploying"],"type":"string"},{"enum":["waiting-for-healthcheck"],"type":"string"},{"enum":["deployed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"},{"enum":["superseded"],"type":"string"}]},"statusReason":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"projectId":{"type":"string"},"userId":{"nullable":true,"type":"string"},"userPreferredUsername":{"description":"Display name of the deployer, or \"Webhook\" for webhook-triggered deployments.","type":"string"},"appName":{"type":"string"},"repoUrl":{"nullable":true,"type":"string"},"branch":{"description":"The deployed ref, or \"unknown\" when the deployment has none.","type":"string"},"refType":{"nullable":true,"anyOf":[{"enum":["branch"],"type":"string"},{"enum":["tag"],"type":"string"}]},"targetUrl":{"nullable":true,"type":"string"},"imageTag":{"description":"The image tag, or \"unknown\" when none is built yet.","type":"string"},"containerPort":{"nullable":true,"type":"string"},"dockerfilePath":{"nullable":true,"type":"string"},"envVars":{"description":"Decrypted env var entries of the deployment environment. Same entries as ServiceEnvironment.envVars."},"commitMessage":{"nullable":true,"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]},"triggerSource":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["env_change"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"},"previewUrl":{"nullable":true,"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/deployments/dependency-scans":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"serviceId","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDependencyScans","summary":"List dependency scans of repo services","description":"Lists every repo service in the active organization with the critical dependency vulnerabilities found by the lockfile scan of its latest stable build. Services never scanned have a null scan. Optionally filter to one service with serviceId. Requires scope `read:deployments`.","tags":["Deployments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DependencyScanList","type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"title":"ServiceDependencyScan","type":"object","required":["serviceId","serviceName","projectId","projectName","scanEnabled","scan"],"properties":{"serviceId":{"type":"string"},"serviceName":{"type":"string"},"projectId":{"type":"string"},"projectName":{"type":"string"},"scanEnabled":{"description":"Dependency scanning runs on every build of this service.","type":"boolean"},"scan":{"description":"Latest scan of the stable environment, null when never scanned.","nullable":true,"type":"object","required":["deploymentId","status","commitSha","branch","scannedAt","error","targets","findings"],"properties":{"deploymentId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["passed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["error"],"type":"string"}]},"commitSha":{"nullable":true,"type":"string"},"branch":{"nullable":true,"type":"string"},"scannedAt":{"nullable":true,"description":"When the scan completed.","type":"string"},"error":{"nullable":true,"description":"Why the scan itself could not run.","type":"string"},"targets":{"description":"Lockfiles scanned.","type":"array","items":{"type":"string"}},"findings":{"description":"Critical findings, set when status is failed.","type":"array","items":{"type":"object","required":["vulnerabilityId","packageName","installedVersion","fixedVersion","target"],"properties":{"vulnerabilityId":{"type":"string"},"packageName":{"type":"string"},"installedVersion":{"type":"string"},"fixedVersion":{"nullable":true,"type":"string"},"target":{"type":"string"}}}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/debug/jobs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDebugJobs","summary":"List recent jobs for debugging","description":"Returns the most recent jobs for the active organization. Requires scope `read:deployments`.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DebugJobList","type":"object","required":["jobs"],"properties":{"jobs":{"type":"array","items":{"title":"Job","type":"object","required":["id","type","status","createdAt","startedAt","completedAt","params","result","error","retriedFromJobId","entityType","entityId","organizationId","triggeredBy"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"params":{"description":"Job input. Shape depends on the job type."},"result":{"description":"Job output, null until the job finishes. Shape depends on the job type."},"error":{"nullable":true,"type":"string"},"retriedFromJobId":{"nullable":true,"type":"string"},"entityType":{"nullable":true,"type":"string"},"entityId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"triggeredBy":{"nullable":true,"type":"string"}}}},"events":{"description":"Always empty. Present only when the session has no active organization.","type":"array","items":{}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/debug/events":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDebugEvents","summary":"List recent domain events for debugging","description":"Returns the most recent domain events for the active organization. Requires scope `read:deployments`.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DebugEventList","type":"object","required":["events"],"properties":{"events":{"type":"array","items":{"title":"DomainEvent","type":"object","required":["id","type","payload","emittedBy","emittedAt","status","processedAt","error","correlationId","organizationId"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"payload":{"description":"Event payload. Shape depends on the event type."},"emittedBy":{"type":"string"},"emittedAt":{"type":"string","format":"date-time"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["processing"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"}]},"processedAt":{"nullable":true,"type":"string","format":"date-time"},"error":{"nullable":true,"type":"string"},"correlationId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/debug/group-queue":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"environmentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getDebugGroupQueueState","summary":"Get grouped queue state for an environment","description":"Returns the grouped-queue FIFO state for a service environment, for debugging job serialization. Requires scope `read:deployments`. Returns 404 if the environment is not found.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GroupQueueState","type":"object","required":["waitingJobIds","items"],"properties":{"activeJobId":{"type":"string"},"waitingJobIds":{"type":"array","items":{"type":"string"}},"items":{"type":"array","items":{"type":"object","required":["id","groupId","data","status"],"properties":{"id":{"type":"string"},"groupId":{"type":"string"},"data":{"description":"Queued pipeline payload. Shape depends on the job type."},"status":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/{jobId}":{"get":{"operationId":"getJob","summary":"Get a job","description":"Returns a job by id. Requires scope `read:deployments`.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"Job","type":"object","required":["id","type","status","createdAt","startedAt","completedAt","params","result","error","retriedFromJobId","entityType","entityId","organizationId","triggeredBy"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"params":{"description":"Job input. Shape depends on the job type."},"result":{"description":"Job output, null until the job finishes. Shape depends on the job type."},"error":{"nullable":true,"type":"string"},"retriedFromJobId":{"nullable":true,"type":"string"},"entityType":{"nullable":true,"type":"string"},"entityId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"triggeredBy":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/job/{jobId}/cancel":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"cancelJob","summary":"Cancel a job","description":"Requests cancellation of a job, routed by job kind: generic jobs emit a cancel event, a waiting custom-agent run cancels through the kernel completion primitive, and a waiting custom-agent delivery cancels directly. Requires scopes `read:deployments` and `write:deployments`. Returns 400 if the job is neither waiting nor running. Running custom-agent runs and deliveries cannot be cancelled and return 409, including when a waiting job races to running.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SuccessMessage","type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/{jobId}/retry":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"retryJob","summary":"Retry a failed or cancelled job","description":"Creates a new job as a retry of a failed or cancelled job and enqueues it. Requires scopes `read:deployments` and `write:deployments`. Returns 422 for custom-agent job types, which must be re-run from their workflow instead, 400 if the job is not in a retryable state.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JobRetried","type":"object","required":["success","jobId","retriedFromJobId"],"properties":{"success":{"type":"boolean"},"jobId":{"type":"string"},"retriedFromJobId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/{jobId}/logs/history":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string"},"in":"query","name":"level","required":false},{"schema":{"anyOf":[{"format":"numeric","default":0,"type":"string"},{"type":"number"}]},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"before","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getJobBuildLogHistory","summary":"Get paginated build log history for a job","description":"Returns a page of historical build log lines from Loki for a job, cursor-paginated backwards from the given timestamp. Requires scope `read:deployments`. Returns 400 for an invalid cursor, 503 if Loki is not enabled or the query fails.","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BuildLogHistory","type":"array","items":{"type":"object","required":["id","message","logLevel","timestamp","cursor"],"properties":{"id":{"type":"number"},"message":{"type":"string"},"logLevel":{"enum":["info"],"type":"string"},"timestamp":{"description":"Unix time in milliseconds.","type":"number"},"stage":{"type":"string"},"cursor":{"description":"Pass as `before` to fetch the page of older lines.","type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/job/{jobId}/logs/stream":{"get":{"operationId":"streamJobLogs","summary":"Stream live build logs for a job","description":"Server-sent event stream of live build log lines from Loki for a job, with a safety-net polling backfill and a fallback sentinel on terminal status. Requires scope `read:deployments`. Returns 503 if Loki is not enabled or the initial query fails.","tags":["Jobs"],"responses":{"200":{"description":"Server-sent event stream. `logs` events carry `{ logs: [{ id, message, logLevel, timestamp, stage? }] }`, a `done` event carries the final job status and build duration, and an `error` event carries `{ error }`.","content":{"text/event-stream":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true},{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/custom-agents":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"projectId","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listCustomAgents","summary":"List custom agents","description":"Lists custom agents in the active organization, optionally scoped to a project. Requires scope `read:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["agents"],"properties":{"agents":{"type":"array","items":{"title":"CustomAgent","type":"object","required":["id","organizationId","projectId","name","description","systemPrompt","allowedTools","repoCheckout","aiProviderModelId","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createCustomAgent","summary":"Create a custom agent","description":"Creates a custom agent definition in the active organization, optionally scoped to a project. Requires scopes `read:workflows` and `write:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["agent"],"properties":{"agent":{"title":"CustomAgent","type":"object","required":["id","organizationId","projectId","name","description","systemPrompt","allowedTools","repoCheckout","aiProviderModelId","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","description","systemPrompt"],"properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"projectId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","description","systemPrompt"],"properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"projectId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["name","description","systemPrompt"],"properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"projectId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}}}}}},"/api/custom-agents/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getCustomAgent","summary":"Get a custom agent","description":"Returns one custom agent identified by `id`. Requires scope `read:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["agent"],"properties":{"agent":{"title":"CustomAgent","type":"object","required":["id","organizationId","projectId","name","description","systemPrompt","allowedTools","repoCheckout","aiProviderModelId","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateCustomAgent","summary":"Update a custom agent","description":"Edits a custom agent identified by `id`. Later edits only affect later run admissions since runs snapshot the agent at admission time. Requires scopes `read:workflows` and `write:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["agent"],"properties":{"agent":{"title":"CustomAgent","type":"object","required":["id","organizationId","projectId","name","description","systemPrompt","allowedTools","repoCheckout","aiProviderModelId","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}},"text/plain":{"schema":{"type":"object","properties":{"name":{"minLength":1,"maxLength":100,"type":"string"},"description":{"minLength":1,"maxLength":500,"type":"string"},"systemPrompt":{"minLength":1,"type":"string"},"allowedTools":{"maxItems":5,"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"format":"uuid","type":"string"}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteCustomAgent","summary":"Delete a custom agent","description":"Soft-deletes a custom agent identified by `id`. Admitted runs keep their snapshots and reads exclude the deleted row. Queued runs cancel when their preflight agent lookup fails. Requires scopes `read:workflows` and `write:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/custom-agent-runs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"serviceId","required":false},{"schema":{"type":"string"},"in":"query","name":"workflowId","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listCustomAgentRuns","summary":"List custom agent runs","description":"Lists custom agent runs in the active organization, offset-paginated and optionally filtered by service or workflow. Requires scope `read:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runs","limit","offset"],"properties":{"runs":{"type":"array","items":{"title":"CustomAgentRunSummary","type":"object","required":["id","status","createdAt","completedAt","serviceId","agentName","workflowId","triggerType","hasCommit","hasPr","noChanges","recovered"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"serviceId":{"nullable":true,"type":"string"},"agentName":{"nullable":true,"type":"string"},"workflowId":{"nullable":true,"type":"string"},"triggerType":{"nullable":true,"type":"string"},"hasCommit":{"type":"boolean"},"hasPr":{"type":"boolean"},"noChanges":{"type":"boolean"},"recovered":{"type":"boolean"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/custom-agent-runs/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getCustomAgentRun","summary":"Get a custom agent run","description":"Returns one custom agent run identified by `id`, with its agent snapshot, trigger context, result envelope and per-delivery status. Never returns webhook delivery secrets. Requires scope `read:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["run"],"properties":{"run":{"title":"CustomAgentRun","type":"object","required":["id","status","createdAt","startedAt","completedAt","serviceId","workflowId","triggerType","triggerAgent","agentName","snapshot","envelope","cancellation","deliveries"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"nullable":true,"type":"string","format":"date-time"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"serviceId":{"nullable":true,"type":"string"},"workflowId":{"nullable":true,"type":"string"},"triggerType":{"nullable":true,"type":"string"},"triggerAgent":{"nullable":true,"type":"object","required":["sourceRunId","sourceJobId","sourceWorkflowId","sourceWorkflowName","sourceAgentName","sourceServiceId","sourceServiceName","sourceProjectId","sourceEnvironmentId"],"properties":{"sourceRunId":{"type":"string"},"sourceJobId":{"type":"string"},"sourceWorkflowId":{"type":"string"},"sourceWorkflowName":{"type":"string"},"sourceAgentName":{"type":"string"},"sourceServiceId":{"type":"string"},"sourceServiceName":{"type":"string"},"sourceProjectId":{"type":"string"},"sourceEnvironmentId":{"nullable":true,"type":"string"}}},"agentName":{"nullable":true,"type":"string"},"snapshot":{"nullable":true,"type":"object","required":["systemPrompt","allowedTools","repoCheckout","name","configHash"],"properties":{"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"name":{"type":"string"},"aiProviderModelId":{"nullable":true,"type":"string"},"configHash":{"type":"string"}}},"envelope":{"nullable":true,"title":"CustomAgentRunEnvelope","type":"object","required":["agentId","runId","trigger","status","finalText","filesChanged"],"properties":{"agentId":{"type":"string"},"runId":{"type":"string"},"trigger":{"anyOf":[{"type":"object","required":["type","runUuid"],"properties":{"type":{"enum":["manual"],"type":"string"},"runUuid":{"type":"string"}}},{"type":"object","required":["type","prNumber","mergeCommitSha"],"properties":{"type":{"enum":["pull_request"],"type":"string"},"prNumber":{"type":"number"},"mergeCommitSha":{"nullable":true,"type":"string"}}},{"type":"object","required":["type","headSha","branch"],"properties":{"type":{"enum":["push"],"type":"string"},"headSha":{"type":"string"},"branch":{"type":"string"}}},{"type":"object","required":["type","deploymentId","outcome"],"properties":{"type":{"enum":["deployment"],"type":"string"},"deploymentId":{"type":"string"},"outcome":{"type":"string"}}},{"type":"object","required":["type","buildJobId","outcome"],"properties":{"type":{"enum":["build"],"type":"string"},"buildJobId":{"type":"string"},"outcome":{"type":"string"}}},{"type":"object","required":["type","sourceRunId","sourceJobId"],"properties":{"type":{"enum":["agent"],"type":"string"},"sourceRunId":{"type":"string"},"sourceJobId":{"type":"string"}}},{"type":"object","required":["type","scheduleId","occurrenceId","scheduledAt","timezone"],"properties":{"type":{"enum":["cron"],"type":"string"},"scheduleId":{"type":"string"},"occurrenceId":{"type":"string"},"scheduledAt":{"type":"string"},"timezone":{"type":"string"},"contextMarkdown":{"type":"string"}}}]},"status":{"anyOf":[{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"}]},"error":{"type":"object","required":["category","message"],"properties":{"category":{"anyOf":[{"enum":["timeout"],"type":"string"},{"enum":["tool-limit"],"type":"string"},{"enum":["git-finalize"],"type":"string"},{"enum":["sandbox"],"type":"string"},{"enum":["internal"],"type":"string"}]},"message":{"type":"string"}}},"finalText":{"type":"string"},"filesChanged":{"description":"Committed files only.","type":"array","items":{"type":"string"}},"commitSha":{"type":"string"},"prUrl":{"type":"string"},"recovered":{"type":"boolean"},"noChanges":{"type":"boolean"}}},"cancellation":{"nullable":true,"type":"object","required":["reason","at"],"properties":{"reason":{"nullable":true,"type":"string"},"at":{"nullable":true,"type":"string","format":"date-time"}}},"deliveries":{"type":"array","items":{"type":"object","required":["deliveryIndex","type","status"],"properties":{"deliveryIndex":{"type":"number"},"type":{"nullable":true,"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"status":{"type":"string"},"reason":{"type":"string"},"httpStatus":{"type":"number"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/custom-agents/{id}/enable":{"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"setCustomAgentEnabled","summary":"Enable or disable a custom agent","description":"Sets the enabled flag on a custom agent identified by `id`. Requires scopes `read:workflows` and `write:workflows`.","tags":["Custom agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["agent"],"properties":{"agent":{"title":"CustomAgent","type":"object","required":["id","organizationId","projectId","name","description","systemPrompt","allowedTools","repoCheckout","aiProviderModelId","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"aiProviderModelId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}}}}}},"/api/healthcheck/stream":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"targetUrl","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"streamServiceHealthcheck","summary":"Stream a one-off HTTP healthcheck","description":"Server-sent event stream that probes a target URL and reports each attempt line plus a final result. Requires authentication only, no resource scope.","tags":["Health"],"responses":{"200":{"description":"Server-sent event stream. Unnamed `data` events carry JSON-encoded attempt log lines. A final `done` event carries `{ externalUrl, status: \"healthy\" | \"unhealthy\", logs: string[] }`. An `error` event carries `{ error: string }`.","content":{"text/event-stream":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/branches":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"owner","required":true},{"schema":{"type":"string"},"in":"query","name":"repo","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listServiceBranches","summary":"List branches for a GitHub repository","description":"Lists branches for a GitHub repository reachable by the active organization GitHub App installation. Requires scope `read:services`. Returns an error payload (not a thrown error) if there is no active organization, the GitHub App is not configured, or the repository is inaccessible.","tags":["Branches"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BranchListResult","anyOf":[{"type":"array","items":{"title":"Branch","type":"object","required":["name"],"properties":{"name":{"type":"string"}}}},{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/org-access":{"get":{"operationId":"checkOrganizationAccess","summary":"Check the caller's organization access","description":"Returns ok after authPlugin validates a session or bearer token. Returns 401 for missing or invalid credentials. Does not perform an additional organization access check.","tags":["Access"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"OrganizationAccess","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/signup-intent/":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createSignupIntent","security":[],"summary":"Store a pre-signup plan selection","description":"Stores the plan and billing interval a visitor picked before creating an account in a short-lived cookie, so signup can resume it after the OAuth callback chain. Unauthenticated, called before any session exists. Returns 400 if the plan or billing interval is invalid.","tags":["Signup"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SignupIntentResult","type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan","billing"],"properties":{"plan":{"type":"string"},"billing":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["plan","billing"],"properties":{"plan":{"type":"string"},"billing":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["plan","billing"],"properties":{"plan":{"type":"string"},"billing":{"type":"string"}}}}}}},"delete":{"operationId":"clearSignupIntent","security":[],"summary":"Clear the pre-signup plan selection","description":"Clears the signup intent cookie set by the plan picker. Unauthenticated, called before any session exists.","tags":["Signup"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SignupIntentResult","type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/github-repos":{"get":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listGithubRepositories","summary":"List accessible GitHub repositories","description":"Lists GitHub repositories accessible to the current user via their linked GitHub App installations, grouped by installation. Requires scope `read:services`. Returns `requiresReauth: true` if GitHub access has expired.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["reposByInstallation"],"properties":{"reposByInstallation":{"type":"array","items":{"type":"object","required":["installationId","accountLogin","accountType","repos"],"properties":{"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repos":{"type":"array","items":{"title":"GithubRepository","type":"object","required":["id","name","fullName","cloneUrl","sshUrl","defaultBranch","isPrivate"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"fullName":{"type":"string"},"cloneUrl":{"type":"string"},"sshUrl":{"type":"string"},"defaultBranch":{"type":"string"},"isPrivate":{"type":"boolean"}}}}}}},"requiresReauth":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-repos/{owner}/repository/{repo}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"owner","required":true},{"schema":{"type":"string"},"in":"path","name":"repo","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getGithubRepository","summary":"Get GitHub repository details and branches","description":"Returns repository details and branch names for one GitHub repository identified by `owner`/`repo`, resolved through the organization's GitHub App installation. Requires scope `read:services`. Returns 403 if the repository is not connected to this organization.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubRepositoryDetails","type":"object","required":["repo","branches","derivedAppName"],"properties":{"repo":{"title":"GithubRepository","type":"object","required":["id","name","fullName","cloneUrl","sshUrl","defaultBranch","isPrivate"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"fullName":{"type":"string"},"cloneUrl":{"type":"string"},"sshUrl":{"type":"string"},"defaultBranch":{"type":"string"},"isPrivate":{"type":"boolean"}}},"branches":{"type":"array","items":{"type":"string"}},"derivedAppName":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-repos/{owner}/repository/{repo}/dockerfiles":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"owner","required":true},{"schema":{"type":"string"},"in":"path","name":"repo","required":true},{"schema":{"type":"string"},"in":"query","name":"branch","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listGithubRepositoryDockerfiles","summary":"List Dockerfiles in a GitHub repository","description":"Finds Dockerfiles in a GitHub repository identified by `owner`/`repo` at a given branch, parsing each one's EXPOSE port and returning a size-bounded content preview. Requires scope `read:services`. Returns 403 if the repository is not connected to this organization.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["dockerfiles"],"properties":{"dockerfiles":{"type":"array","items":{"title":"Dockerfile","type":"object","required":["path","detectedPort","content"],"properties":{"path":{"type":"string"},"detectedPort":{"nullable":true,"type":"string"},"content":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-repos/{owner}/repository/{repo}/dockerfile-args":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"owner","required":true},{"schema":{"type":"string"},"in":"path","name":"repo","required":true},{"schema":{"type":"string"},"in":"query","name":"branch","required":false},{"schema":{"type":"string"},"in":"query","name":"path","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listGithubRepositoryDockerfileArgs","summary":"List ARG declarations in a Dockerfile","description":"Parses ARG declarations from a specific Dockerfile in a GitHub repository identified by `owner`/`repo`. Requires scope `read:services`. Returns 403 if the repository is not connected to this organization.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["args"],"properties":{"args":{"type":"array","items":{"title":"DockerfileArg","type":"object","required":["name","defaultValue"],"properties":{"name":{"type":"string"},"defaultValue":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/github-installation":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listGithubInstallations","summary":"List GitHub App installations for an organization","description":"Lists the GitHub App installations linked to an organization identified by `orgId`, or an install URL when none exist yet. Requires scope `read:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubInstallationList","type":"object","required":["installed","installations"],"properties":{"installed":{"type":"boolean"},"installations":{"type":"array","items":{"title":"GithubInstallationSummary","type":"object","required":["id","installationId","accountLogin","accountType","repositorySelection","installedAt"],"properties":{"id":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"},"installedAt":{"nullable":true,"type":"string","format":"date-time"}}}},"installUrl":{"nullable":true,"type":"string"},"appName":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-installation/{installationId}/permissions":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"installationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getGithubInstallationPermissions","summary":"Get a GitHub installation's permission status","description":"Mints an installation token to read GitHub's live granted permissions for `installationId` and compares them against the required permission set, returning any pending updates. Requires scope `read:organization`. Returns 400 if there is no active organization, 404 if the installation is not linked to it, and 503 if the GitHub App is not configured.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubInstallationPermissions","type":"object","required":["installationId","accountLogin","accountType","repositorySelection","permissions","pendingPermissions","hasPendingUpdates","manageUrl"],"properties":{"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"},"permissions":{"type":"object","additionalProperties":{"type":"string"}},"pendingPermissions":{"type":"array","items":{"type":"object","required":["key","required","granted"],"properties":{"key":{"type":"string"},"required":{"anyOf":[{"enum":["read"],"type":"string"},{"enum":["write"],"type":"string"},{"enum":["admin"],"type":"string"}]},"granted":{"nullable":true,"type":"string"}}}},"hasPendingUpdates":{"type":"boolean"},"manageUrl":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/github-installation/{installationId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string"},"in":"path","name":"installationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"unlinkGithubInstallation","summary":"Unlink a GitHub installation from an organization","description":"Unlinks a GitHub App installation from an organization without uninstalling the app on GitHub. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubSuccess","type":"object","required":["success"],"properties":{"success":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-installation/{installationId}/details":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"installationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getGithubInstallationDetails","summary":"Get GitHub installation details from GitHub","description":"Fetches installation account and permission details directly from GitHub for `installationId`, used after the OAuth install redirect. Requires scope `read:organization`. Returns 404 if the installation is not found or not accessible.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubInstallationDetails","type":"object","required":["success","installation"],"properties":{"success":{"enum":[true],"type":"boolean"},"installation":{"type":"object","required":["installationId","accountLogin","accountType","repositorySelection","permissions"],"properties":{"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"anyOf":[{"enum":["User"],"type":"string"},{"enum":["Organization"],"type":"string"}]},"avatarUrl":{"type":"string"},"repositorySelection":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["selected"],"type":"string"}]},"permissions":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/github-installation/state":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createGithubInstallationState","summary":"Create a GitHub App install state token","description":"Creates a one-time state token and install URL used before redirecting the user to GitHub to install the App onto `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubInstallationState","type":"object","required":["success","state","installUrl","expiresAt"],"properties":{"success":{"enum":[true],"type":"boolean"},"state":{"type":"string"},"installUrl":{"nullable":true,"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/github-installation/validate-state":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"validateGithubInstallationState","summary":"Validate a GitHub install callback state token","description":"Validates the state token from the GitHub install callback and links or updates the installation record for the token's organization. Requires scopes `read:organization` and `write:organization`. Returns 400 if the state token is invalid or expired, and 403 if it does not belong to the caller.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubInstallationValidation","type":"object","required":["success","installation","organizationId"],"properties":{"success":{"enum":[true],"type":"boolean"},"installation":{"nullable":true,"title":"GithubInstallationRecord","type":"object","required":["id","organizationId","installationId","accountLogin","accountType","source","permissions","repositorySelection","installedAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"source":{"type":"string"},"permissions":{},"repositorySelection":{"nullable":true,"type":"string"},"installedAt":{"nullable":true,"type":"string","format":"date-time"},"updatedAt":{"nullable":true,"type":"string","format":"date-time"}}},"organizationId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","installationId","accountLogin","accountType"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"permissions":{"type":"object","additionalProperties":{"type":"string"}},"repositorySelection":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["state","installationId","accountLogin","accountType"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"permissions":{"type":"object","additionalProperties":{"type":"string"}},"repositorySelection":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["state","installationId","accountLogin","accountType"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"permissions":{"type":"object","additionalProperties":{"type":"string"}},"repositorySelection":{"type":"string"}}}}}}}},"/api/github-installation/pending-approval":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createGithubInstallationPendingApproval","summary":"Record a pending GitHub installation approval","description":"Records a pending approval request when the user clicked Request instead of Install on GitHub, so the webhook handler can later resolve it. Requires scopes `read:organization` and `write:organization`. Returns 400 if the state token is invalid or expired, or the user has no linked GitHub account.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubSuccess","type":"object","required":["success"],"properties":{"success":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["state"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["state"],"properties":{"state":{"type":"string"},"installationId":{"type":"string"}}}}}}}},"/api/github-installation/pending-approval/{installationId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"installationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"cancelGithubInstallationPendingApproval","summary":"Cancel a pending GitHub installation approval","description":"Cancels a pending GitHub installation approval request identified by `installationId`, both locally and on GitHub when possible. Requires scopes `read:organization` and `write:organization`. Returns 404 if the pending request is not found, and 403 if the caller did not initiate it.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubSuccess","type":"object","required":["success"],"properties":{"success":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/pending-installations":{"get":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listPendingGithubInstallations","summary":"List pending GitHub installation approvals","description":"Lists pending GitHub installation approval requests for the current user's linked GitHub account. Requires scope `read:organization`.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubPendingInstallationList","type":"object","required":["pending"],"properties":{"pending":{"type":"array","items":{"title":"GithubPendingInstallation","type":"object","required":["id","installationId","targetLogin","targetType","repositorySelection","approvalStatus","createdAt"],"properties":{"id":{"type":"string"},"installationId":{"type":"string"},"targetLogin":{"nullable":true,"type":"string"},"targetType":{"nullable":true,"type":"string"},"repositorySelection":{"nullable":true,"type":"string"},"approvalStatus":{"anyOf":[{"enum":["pending_approval"],"type":"string"},{"enum":["approved_unclaimed"],"type":"string"},{"enum":["rejected"],"type":"string"},{"enum":["claimed"],"type":"string"}]},"createdAt":{"type":"string","format":"date-time"}}}},"message":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/available-installations":{"get":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAvailableGithubInstallations","summary":"List installations available for auto-link","description":"Lists GitHub App installations linked to any organization the current user belongs to, for auto-linking into a new organization. Requires scope `read:organization`.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubAvailableInstallationList","type":"object","required":["installations"],"properties":{"installations":{"type":"array","items":{"title":"GithubAvailableInstallation","type":"object","required":["installationId","accountLogin","accountType","repositorySelection","fromOrganizationId"],"properties":{"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"},"fromOrganizationId":{"type":"string"},"fromOrganizationName":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/github-installation/link":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"linkGithubInstallation","summary":"Link an existing GitHub installation to an org","description":"Links an existing GitHub App installation the user already has access to onto `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 409 if the organization already has an installation, and 403 if the user lacks access to the source installation.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubLinkInstallationResult","type":"object","required":["success","installation"],"properties":{"success":{"enum":[true],"type":"boolean"},"installation":{"title":"GithubLinkedInstallation","type":"object","required":["id","installationId","accountLogin","accountType","repositorySelection"],"properties":{"id":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}}}}}},"/api/pending-installations/{pendingId}/claim":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"pendingId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"claimPendingGithubInstallation","summary":"Claim a pending GitHub installation into an org","description":"Claims a pending GitHub installation approval request identified by `pendingId` into an organization, creating the installation record. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match the request body's `organizationId`. Returns 404 if the pending installation is not found, 403 if the caller did not initiate it, and 409 if the organization already has an installation.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubLinkInstallationResult","type":"object","required":["success","installation"],"properties":{"success":{"enum":[true],"type":"boolean"},"installation":{"title":"GithubLinkedInstallation","type":"object","required":["id","installationId","accountLogin","accountType","repositorySelection"],"properties":{"id":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string"}}}}}}}},"/api/github-installations/discoverable":{"get":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDiscoverableGithubInstallations","summary":"List discoverable unlinked GitHub installations","description":"Lists GitHub App installations the user can access on GitHub but that are not yet linked to the active organization. Requires scope `read:organization`. Returns 400 if there is no active organization, and 401 if the user has no valid GitHub access token.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubDiscoverableInstallationList","type":"object","required":["installations"],"properties":{"installations":{"type":"array","items":{"title":"GithubDiscoverableInstallation","type":"object","required":["installationId","accountLogin","accountType","avatarUrl","repositorySelection","isLinkedElsewhere"],"properties":{"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"avatarUrl":{"type":"string"},"repositorySelection":{"type":"string"},"isLinkedElsewhere":{"type":"boolean"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/github-installation/link-discovered":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"linkDiscoveredGithubInstallation","summary":"Link a discovered GitHub installation","description":"Links a discoverable GitHub App installation to `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 409 if the installation is already linked to this organization, and 403 if the user lacks access to it.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubLinkInstallationResult","type":"object","required":["success","installation"],"properties":{"success":{"enum":[true],"type":"boolean"},"installation":{"title":"GithubLinkedInstallation","type":"object","required":["id","installationId","accountLogin","accountType","repositorySelection"],"properties":{"id":{"type":"string"},"installationId":{"type":"string"},"accountLogin":{"type":"string"},"accountType":{"type":"string"},"repositorySelection":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["installationId"],"properties":{"installationId":{"type":"string"}}}}}}}},"/api/organizations/{orgId}/github-installation/auto-link":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"autoLinkGithubInstallation","summary":"Auto-link a GitHub installation by account login","description":"Silently discovers and links a GitHub App installation matching the given account login onto `orgId`, combining discovery and linking into one call. Used by the MCP deploy flow. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 401 if GitHub reauthentication is required.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubAutoLinkResult","type":"object","required":["linked"],"properties":{"linked":{"type":"boolean"},"alreadyExisted":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountLogin"],"properties":{"accountLogin":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["accountLogin"],"properties":{"accountLogin":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["accountLogin"],"properties":{"accountLogin":{"type":"string"}}}}}}}},"/api/github-app/config":{"get":{"operationId":"getGithubAppConfig","summary":"Get GitHub App configuration","description":"Returns whether the GitHub App is configured on this instance and the install URL the frontend should use. Requires scope `read:organization`.","tags":["GitHub"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"GithubAppConfig","type":"object","required":["configured","appName","installUrl"],"properties":{"configured":{"type":"boolean"},"appName":{"nullable":true,"type":"string"},"installUrl":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/svc-status/deployment/{deploymentId}/logs/history":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"schema":{"type":"string"},"in":"query","name":"start","required":false},{"schema":{"type":"string"},"in":"query","name":"end","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string"},"in":"query","name":"level","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDeploymentRuntimeLogHistory","summary":"List historical runtime logs for a deployment","description":"Returns paginated historical runtime logs from Loki for a deployment, bounded by its lifetime plus a grace window. Requires authentication. Returns 404 if the deployment is not found, 403 if it belongs to another organization, 503 if Loki is not enabled.","tags":["Service status"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"RuntimeLogHistory","type":"object","required":["logs"],"properties":{"logs":{"type":"array","items":{"type":"object","required":["timestamp","content","pod"],"properties":{"timestamp":{"description":"Loki nanosecond timestamp.","type":"string"},"content":{"type":"string"},"pod":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/svc-status/deployment/{deploymentId}/metrics":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"schema":{"anyOf":[{"enum":["1h"],"type":"string"},{"enum":["6h"],"type":"string"},{"enum":["24h"],"type":"string"}]},"in":"query","name":"range","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getDeploymentRuntimeMetrics","summary":"Get runtime metrics for a deployment","description":"Returns CPU and memory metrics from Prometheus for a deployment or its database service, overlaid with OOM events and deployment markers. Requires authentication and the deployment metrics feature flag. Returns 404 if disabled or the deployment is not found, 403 if it belongs to another organization, 503 if Prometheus is not enabled or the query fails.","tags":["Service status"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DeploymentRuntimeMetrics","type":"object","required":["range","start","end","step","cpu","memory","oomEvents","deploymentMarkers"],"properties":{"range":{"anyOf":[{"enum":["1h"],"type":"string"},{"enum":["6h"],"type":"string"},{"enum":["24h"],"type":"string"}]},"start":{"description":"Unix time in seconds.","type":"number"},"end":{"description":"Unix time in seconds.","type":"number"},"step":{"description":"Resolution in seconds.","type":"number"},"cpu":{"type":"object","required":["usage","limit"],"properties":{"usage":{"type":"array","items":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"description":"Unix time in seconds.","type":"number"},"value":{"type":"number"}}}},"limit":{"description":"Null when no resource limit is configured.","nullable":true,"type":"array","items":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"description":"Unix time in seconds.","type":"number"},"value":{"type":"number"}}}}}},"memory":{"type":"object","required":["usage","limit"],"properties":{"usage":{"type":"array","items":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"description":"Unix time in seconds.","type":"number"},"value":{"type":"number"}}}},"limit":{"description":"Null when no resource limit is configured.","nullable":true,"type":"array","items":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"description":"Unix time in seconds.","type":"number"},"value":{"type":"number"}}}}}},"oomEvents":{"type":"array","items":{"type":"object","required":["id","timestamp"],"properties":{"id":{"type":"string"},"timestamp":{"description":"Unix time in seconds.","type":"number"}}}},"deploymentMarkers":{"type":"array","items":{"type":"object","required":["id","timestamp"],"properties":{"id":{"type":"string"},"timestamp":{"description":"Unix time in seconds.","type":"number"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/svc-status/deployment/{deploymentId}/logs/stream":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"deploymentId","required":true},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string"},"in":"query","name":"level","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"streamDeploymentRuntimeLogs","summary":"Stream live runtime logs for a deployment","description":"Server-sent event stream of live runtime logs for a deployment, tailed from Loki. Requires authentication. Returns 404 if the deployment is not found, 403 if it belongs to another organization, 503 if Loki is not enabled.","tags":["Service status"],"responses":{"200":{"description":"Server-sent event stream. A `connected` event opens it, `logs` events carry `{ lines: [{ id, timestamp, pod, content }] }`, a `done` event ends it with `{ reason }`, and an `error` event carries `{ error }`.","content":{"text/event-stream":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/project/{projectId}/notification-channels":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listNotificationChannels","summary":"List notification channels for a project","description":"Lists notification channels configured for a project identified by `projectId`. Requires scope `read:projects`.","tags":["Notification channels"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"NotificationChannel","type":"object","required":["id","projectId","type","name","config","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"type":{"anyOf":[{"enum":["slack"],"type":"string"},{"enum":["discord"],"type":"string"},{"enum":["webhook"],"type":"string"}]},"name":{"type":"string"},"config":{"anyOf":[{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}}]},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createNotificationChannel","summary":"Create a notification channel for a project","description":"Creates a Slack, Discord or webhook notification channel for a project identified by `projectId`. Webhook URLs must be https, credential-free and resolve to a public address. Requires scopes `read:projects` and `write:projects`. Returns 400 if the webhook URL is invalid or blocked, or the project already has too many Slack or Discord channels.","tags":["Notification channels"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"NotificationChannel","type":"object","required":["id","projectId","type","name","config","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"type":{"anyOf":[{"enum":["slack"],"type":"string"},{"enum":["discord"],"type":"string"},{"enum":["webhook"],"type":"string"}]},"name":{"type":"string"},"config":{"anyOf":[{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}}]},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}},"multipart/form-data":{"schema":{"anyOf":[{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}},"text/plain":{"schema":{"anyOf":[{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type","config","name"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}}}}}},"/api/project/{projectId}/notification-channels/{channelId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string"},"in":"path","name":"channelId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getNotificationChannel","summary":"Get a notification channel","description":"Returns a single notification channel identified by `channelId`. Requires scope `read:projects`. Returns 404 if the channel does not exist or does not belong to `projectId`.","tags":["Notification channels"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"NotificationChannel","type":"object","required":["id","projectId","type","name","config","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"type":{"anyOf":[{"enum":["slack"],"type":"string"},{"enum":["discord"],"type":"string"},{"enum":["webhook"],"type":"string"}]},"name":{"type":"string"},"config":{"anyOf":[{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}}]},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string"},"in":"path","name":"channelId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateNotificationChannel","summary":"Update a notification channel","description":"Updates a notification channel's name, config or enabled state. Webhook URLs are re-validated the same way as on create. Requires scopes `read:projects` and `write:projects`. Returns 404 if the channel does not exist or does not belong to `projectId`, and 400 if the webhook URL is invalid or blocked, or the project already has too many Slack or Discord channels.","tags":["Notification channels"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"NotificationChannel","type":"object","required":["id","projectId","type","name","config","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"type":{"anyOf":[{"enum":["slack"],"type":"string"},{"enum":["discord"],"type":"string"},{"enum":["webhook"],"type":"string"}]},"name":{"type":"string"},"config":{"anyOf":[{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}}]},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}},"multipart/form-data":{"schema":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}},"text/plain":{"schema":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["slack"],"type":"string"},"config":{"type":"object","required":["channel","teamId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"teamId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["discord"],"type":"string"},"config":{"type":"object","required":["channel","guildId"],"properties":{"channel":{"type":"string"},"channelName":{"type":"string"},"guildId":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","required":["type"],"properties":{"type":{"enum":["webhook"],"type":"string"},"config":{"type":"object","required":["webhookUrl"],"properties":{"webhookUrl":{"type":"string"}}},"name":{"type":"string"},"enabled":{"type":"boolean"}}},{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"}}}]}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string"},"in":"path","name":"channelId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteNotificationChannel","summary":"Delete a notification channel","description":"Deletes a notification channel identified by `channelId`. Requires scopes `read:projects` and `write:projects`. Returns 404 if the channel does not exist or does not belong to `projectId`.","tags":["Notification channels"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DeletedNotificationChannel","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/events/stream":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"streamOrganizationEvents","summary":"Stream real-time organization events","description":"Opens a server-sent events stream of real-time updates for an organization identified by `orgId` (deployment status, job status, analysis completion) used to invalidate frontend caches. Requires scope `read:organization` and membership in the organization. Returns 401 if unauthenticated and 403 if the user is not a member.","tags":["Organization events"],"responses":{"200":{"description":"Server-sent event stream. Starts with a `connected` event carrying `{ orgId, message }`. Each later event is named after the organization event `type` (for example `deployment:status-changed`, `job:status-changed`) and carries the JSON-encoded event as data. An `error` event carries `{ message }` when the subscription fails.","content":{"text/event-stream":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/audit/logs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"schema":{"type":"string"},"in":"query","name":"action","required":false},{"schema":{"type":"string"},"in":"query","name":"userId","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string"},"in":"query","name":"sortDir","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAuditLogs","summary":"List audit logs for an organization","description":"Lists audit log entries for the active organization with pagination, filtering by action or user, full-text search, and sorting. Requires scope `read:organization`. Returns an empty list if there is no active organization.","tags":["Audit log"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AuditLogList","type":"object","required":["logs","total"],"properties":{"logs":{"type":"array","items":{"title":"AuditLogEntry","type":"object","required":["id","organizationId","userId","action","entityType","entityId","metadata","createdAt","userName","userEmail","userImage"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"userId":{"description":"Acting user id, or `system` for webhook-triggered actions.","type":"string"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"metadata":{"nullable":true,"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"userName":{"nullable":true,"type":"string"},"userEmail":{"nullable":true,"type":"string"},"userImage":{"nullable":true,"type":"string"}}}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/audit/users":{"get":{"operationId":"listAuditLogUsers","summary":"List users with audit log entries","description":"Lists the distinct users who have audit log entries in the active organization, for populating a filter dropdown. Requires scope `read:organization`.","tags":["Audit log"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AuditLogUserList","type":"object","required":["users"],"properties":{"users":{"type":"array","items":{"type":"object","required":["id","name","email"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/audit/actions":{"get":{"operationId":"listAuditLogActions","summary":"List available audit log action types","description":"Lists all audit action types the API can record, for populating a filter dropdown. Requires scope `read:organization`.","tags":["Audit log"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AuditActionList","type":"object","required":["actions"],"properties":{"actions":{"type":"array","items":{"type":"string","enum":["api-key:create","api-key:update","api-key:revoke","artifact:delete","artifact:publish","artifact:update","blueprint:create","blueprint:delete","blueprint:deploy","blueprint:update","chat-platform:connect","chat-platform:disconnect","custom-agent:create","custom-agent:delete","custom-agent:disable","custom-agent:enable","custom-agent:update","custom-agent-run:cancel","deployment:cancel","deployment:crashloop-scale-down","deployment:create","deployment:delete","deployment:rollback","github-installation:link","github-installation:pending-approval-cancel","github-installation:pending-approval-request","github-installation:unlink","github-installation:update","job:cancel","notification-channel:create","notification-channel:delete","notification-channel:update","organization:ai-budget:topup","organization:ai-budget:topup-reversed","organization:ai-config:update","organization:ai-gateway:key:create","organization:ai-gateway:key:delete","organization:ai-gateway:key:update","organization:ai-gateway:org:create","organization:ai-gateway:topup","organization:ai-gateway:topup-withheld","organization:audit-config:update","organization:create","organization:delete","organization:member:accept","organization:member:invite","organization:member:invite:cancel","organization:member:remove","organization:member:scopes:update","organization:registry:reconcile","organization:service-config:update","organization:tier:update","organization:update","project:create","project:delete","project:reassign","project:update","service:agent-session:cancel-turn","service:agent-session:close","service:agent-session:create","service:agent-session:run","service:ai-sandbox-code:respond","service:ai-sandbox-code:trigger","service:analysis:trigger","service:code-review:fix","service:code-review:finding-dismiss","service:code-review:finding-reopen","service:code-review:learning-create","service:code-review:learning-delete","service:code-review:learning-update","service:code-review:retry","service:create","service:credentials-rotate","service:credentials-view","service:custom-domain:add","service:custom-domain:remove","service:custom-domain:verify","service:delete","service:deploy:skipped","service:pgweb-open","service:preview:trigger","service:dockerfile-init:trigger","service:pod-blocked","service:pod-promoted","service:preview:cleanup","service:public-toggle","service:s3-object:download","service:s3-object:head","service:s3-object:list","service:s3-object:preview","service:sleep","service:update","service:uptime-monitor:add","service:uptime-monitor:remove","service:uptime-monitor:update","service:wake","slack-installation:connect","slack-installation:disconnect","subscription:activate","subscription:cancel","subscription:cancel-scheduled","subscription:create","subscription:expire","subscription:past-due","subscription:promo-applied","subscription:promo-removed","subscription:promo-stripped-ineligible","subscription:recovered","subscription:scale-down","subscription:scale-up","subscription:trial-card-removed","subscription:trial-ended-on-card","subscription:trial-extended","subscription:update","user:delete","user:marketing-trial-consumed","workflow:agent-trigger-staged","workflow:create","workflow:delete","workflow:manual-run","workflow:toggle","workflow:update"]}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/audit/entity/{entityType}/{entityId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"entityType","required":true},{"schema":{"type":"string"},"in":"path","name":"entityId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAuditLogEntity","summary":"Get entity details for an audit log entry","description":"Resolves the current details and a deep link for the entity referenced by an audit log entry (deployment, service, project, organization, GitHub installation, workflow, notification channel or subscription). Requires scope `read:organization`. Returns 403 if no active organization is selected. Returns `entity: null` if the entity type is unknown, deleted, or belongs to a different organization.","tags":["Audit log"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AuditEntity","type":"object","required":["entity"],"properties":{"entity":{"nullable":true,"type":"object","required":["type","id","name","link","details"],"properties":{"type":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"link":{"description":"Dashboard path to the entity.","type":"string"},"details":{"description":"Entity-type specific fields, such as status, branch or namespace.","type":"object","additionalProperties":true}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/build-metrics/":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"jobId","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBuildMetric","summary":"Get build metrics for a job","description":"Returns the recorded build duration and cache statistics for a job. Requires scope `read:deployments`. Returns 400 if jobId is missing, 404 if the job or its metric is not found in the caller organization.","tags":["Build metrics"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BuildMetric","type":"object","required":["id","jobId","gitCloneDurationMs","dockerBuildDurationMs","imagePushDurationMs","cacheHitCount","cacheMissCount","projectSlug","serviceSlug","collectedAt"],"properties":{"id":{"type":"string"},"jobId":{"type":"string"},"gitCloneDurationMs":{"type":"number"},"dockerBuildDurationMs":{"type":"number"},"imagePushDurationMs":{"type":"number"},"cacheHitCount":{"type":"number"},"cacheMissCount":{"type":"number"},"projectSlug":{"nullable":true,"type":"string"},"serviceSlug":{"nullable":true,"type":"string"},"collectedAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/build-metrics/stats":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"projectSlug","required":false},{"schema":{"type":"string"},"in":"query","name":"timeRange","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBuildMetricStats","summary":"Get build metric stats for a project","description":"Returns aggregated build duration and cache statistics for a project over a time range, capped at 365 days. Requires scope `read:deployments`. Returns 400 if projectSlug is missing, 403 if there is no active organization, 404 if the project slug does not belong to the caller organization.","tags":["Build metrics"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BuildMetricStats","type":"object","required":["avgGitCloneDuration","avgDockerBuildDuration","avgImagePushDuration","p95GitCloneDuration","p95DockerBuildDuration","p95ImagePushDuration","totalBuilds","avgCacheHitRate"],"properties":{"avgGitCloneDuration":{"nullable":true,"type":"number"},"avgDockerBuildDuration":{"nullable":true,"type":"number"},"avgImagePushDuration":{"nullable":true,"type":"number"},"p95GitCloneDuration":{"nullable":true,"type":"number"},"p95DockerBuildDuration":{"nullable":true,"type":"number"},"p95ImagePushDuration":{"nullable":true,"type":"number"},"totalBuilds":{"type":"number"},"avgCacheHitRate":{"nullable":true,"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/build-metrics/outliers":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"projectSlug","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBuildMetricOutliers","summary":"Get build duration outliers for a project","description":"Returns the slowest recent builds for a project, capped at 1000 rows. Requires scope `read:deployments`. Returns 400 if projectSlug is missing, 403 if there is no active organization, 404 if the project slug does not belong to the caller organization.","tags":["Build metrics"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BuildMetricOutliers","type":"object","required":["outliers"],"properties":{"outliers":{"type":"array","items":{"title":"BuildMetric","type":"object","required":["id","jobId","gitCloneDurationMs","dockerBuildDurationMs","imagePushDurationMs","cacheHitCount","cacheMissCount","projectSlug","serviceSlug","collectedAt"],"properties":{"id":{"type":"string"},"jobId":{"type":"string"},"gitCloneDurationMs":{"type":"number"},"dockerBuildDurationMs":{"type":"number"},"imagePushDurationMs":{"type":"number"},"cacheHitCount":{"type":"number"},"cacheMissCount":{"type":"number"},"projectSlug":{"nullable":true,"type":"string"},"serviceSlug":{"nullable":true,"type":"string"},"collectedAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/chat-platforms/config":{"get":{"operationId":"getChatPlatformConfig","security":[],"summary":"Get instance chat platform configuration","description":"Returns which chat platforms (Slack, Discord) are configured at the instance level. No authentication required.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ChatPlatformConfig","type":"object","required":["slack","discord"],"properties":{"slack":{"type":"boolean"},"discord":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/organizations/{orgId}/chat-platforms":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listChatPlatformConnections","summary":"List connected chat platforms for an organization","description":"Lists chat platforms (Slack, Discord) connected to an organization identified by `orgId`. Requires scope `read:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ChatPlatformConnectionList","type":"object","required":["platforms"],"properties":{"platforms":{"type":"array","items":{"type":"object","required":["platform","platformAccountId","platformAccountName","botId","installedAt"],"properties":{"platform":{"anyOf":[{"enum":["slack"],"type":"string"},{"enum":["discord"],"type":"string"}]},"platformAccountId":{"type":"string"},"platformAccountName":{"type":"string"},"botId":{"nullable":true,"type":"string"},"installedAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/chat-platforms/slack/oauth":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createSlackOauthState","summary":"Start Slack OAuth for an organization","description":"Creates a Slack OAuth state token and returns the authorization URL to start connecting a Slack workspace to `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ, and 503 if Slack is not configured.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ChatPlatformOauthState","type":"object","required":["success","state","authUrl","expiresAt"],"properties":{"success":{"type":"boolean"},"state":{"type":"string"},"authUrl":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/chat-platforms/slack/callback":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"completeSlackOauthCallback","summary":"Complete Slack OAuth callback","description":"Completes the Slack OAuth flow using the code and state from the redirect, storing the workspace token and installation. Requires authentication, scopes `read:organization` and `write:organization` for bearer callers, and organization management capability for session callers with an active organization. Returns 400 if the state token is invalid, expired, or the OAuth exchange fails, and 403 if the state token does not belong to the caller.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SlackOauthCallbackResult","type":"object","required":["success","organizationId","platform","platformAccountId"],"properties":{"success":{"type":"boolean"},"organizationId":{"type":"string"},"platform":{"enum":["slack"],"type":"string"},"platformAccountId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","code"],"properties":{"state":{"type":"string"},"code":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["state","code"],"properties":{"state":{"type":"string"},"code":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["state","code"],"properties":{"state":{"type":"string"},"code":{"type":"string"}}}}}}}},"/api/organizations/{orgId}/chat-platforms/slack/channels":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listSlackChannels","summary":"List Slack channels for a workspace","description":"Lists public Slack channels the bot is a member of for `orgId`'s workspace, for the channel picker. Requires scope `read:organization` and the caller's active organization to match `orgId`. Returns 404 if Slack is not connected, and 401 if the stored token is no longer valid.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"SlackChannelList","type":"object","required":["channels"],"properties":{"channels":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/chat-platforms/discord/oauth":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createDiscordOauthState","summary":"Start Discord OAuth for an organization","description":"Creates a Discord OAuth state token and returns the bot invite URL to start connecting a Discord server to `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 403 if they differ, and 503 if Discord is not configured.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ChatPlatformOauthState","type":"object","required":["success","state","authUrl","expiresAt"],"properties":{"success":{"type":"boolean"},"state":{"type":"string"},"authUrl":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/chat-platforms/discord/callback":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"completeDiscordOauthCallback","summary":"Complete Discord OAuth callback","description":"Completes the Discord bot-add flow using the guild id and state from the redirect, resolving the guild name and storing the installation. Requires authentication, scopes `read:organization` and `write:organization` for bearer callers, and organization management capability for session callers with an active organization. Returns 400 if the state token is invalid, expired, or the setup fails, and 403 if the state token does not belong to the caller.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DiscordOauthCallbackResult","type":"object","required":["success","organizationId","platform","platformAccountId","platformAccountName"],"properties":{"success":{"type":"boolean"},"organizationId":{"type":"string"},"platform":{"enum":["discord"],"type":"string"},"platformAccountId":{"type":"string"},"platformAccountName":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","guildId"],"properties":{"state":{"type":"string"},"guildId":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["state","guildId"],"properties":{"state":{"type":"string"},"guildId":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["state","guildId"],"properties":{"state":{"type":"string"},"guildId":{"type":"string"}}}}}}}},"/api/organizations/{orgId}/chat-platforms/discord/channels":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listDiscordChannels","summary":"List Discord channels for a guild","description":"Lists text channels in the Discord guild connected to `orgId`, for the channel picker. Requires scope `read:organization` and the caller's active organization to match `orgId`. Returns 404 if Discord is not connected.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"DiscordChannelList","type":"object","required":["channels","guildId"],"properties":{"channels":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}}},"guildId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/organizations/{orgId}/chat-platforms/{platform}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgId","required":true},{"schema":{"type":"string"},"in":"path","name":"platform","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"disconnectChatPlatform","summary":"Disconnect a chat platform from an organization","description":"Disconnects a Slack or Discord installation from `orgId`. Requires scopes `read:organization` and `write:organization` and the caller's active organization to match `orgId`. Returns 400 for an unknown platform, 404 if it is not connected, and 403 if the organizations differ.","tags":["Chat platforms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"ChatPlatformDisconnectResult","type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/jira/remote/lifecycle":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraForgeLifecycle","summary":"Record a Jira app install or upgrade event","description":"Records a Jira app install or upgrade event and reconciles the installation's Jira-side setup afterward without blocking the response. Called directly by Forge on the installed and upgraded lifecycle events, authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraOk","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"siteUrl":{"type":"string"},"productType":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"siteUrl":{"type":"string"},"productType":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","properties":{"siteUrl":{"type":"string"},"productType":{"type":"string"}}}}}}}},"/api/jira/remote/pre-uninstall":{"post":{"operationId":"jiraForgePreUninstall","summary":"Release organizations before a Jira app uninstall","description":"Marks a Jira installation uninstalled and releases every organization linked to it. Called by Forge just before the app is removed, is never retried, and only performs local writes since nothing else can be relied on to run. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraOk","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/remote/token-refresh":{"post":{"operationId":"jiraForgeTokenRefresh","summary":"Refresh a Jira installation's cached token","description":"Refreshes the cached Jira system token, heals the stored site URL, records the Forge environment id, matches pending pairing requests and sweeps stalled Jira runs for an installation. Called hourly by a Forge scheduled trigger, authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeTokenRefresh","type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"},"swept":{"type":"object","required":["written","pending","stale","running"],"properties":{"written":{"type":"number"},"pending":{"type":"number"},"stale":{"type":"number"},"running":{"type":"number"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/remote/admin-state":{"post":{"operationId":"jiraForgeAdminState","summary":"Get state for the Jira app's admin page","description":"Returns the state rendered on the Jira app's admin page: the site's pending pairing requests, linked organizations and their project mappings. Registers the installation if no row exists yet, refreshes the cached system token and heals the site URL. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeAdminState","type":"object","required":["siteUrl","settingsUrl","pendingRequests","organizations"],"properties":{"siteUrl":{"type":"string"},"settingsUrl":{"nullable":true,"type":"string"},"pendingRequests":{"type":"array","items":{"type":"object","required":["id","organizationName","requestedByName","requestedByEmail","createdAt","expiresAt"],"properties":{"id":{"type":"string"},"organizationName":{"nullable":true,"type":"string"},"requestedByName":{"nullable":true,"type":"string"},"requestedByEmail":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}}},"organizations":{"type":"array","items":{"type":"object","required":["organizationId","organizationName","linkedAt","mappings"],"properties":{"organizationId":{"type":"string"},"organizationName":{"nullable":true,"type":"string"},"linkedAt":{"type":"string","format":"date-time"},"mappings":{"type":"array","items":{"type":"object","required":["projectKey","serviceName","enabled"],"properties":{"projectKey":{"type":"string"},"serviceName":{"type":"string"},"enabled":{"type":"boolean"}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/remote/pairing-requests/accept":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraForgeAcceptPairingRequest","summary":"Accept a Jira pairing request","description":"Accepts a pairing request and links its organization to the site named by the invocation token, looking the request up by that installation so a forwarded id cannot target another site. Called from the Jira admin page, where `jira:adminPage` already restricts rendering to a site admin. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeAcceptPairingRequest","anyOf":[{"type":"object","required":["ok","organizationId"],"properties":{"ok":{"enum":[true],"type":"boolean"},"organizationId":{"type":"string"}}},{"type":"object","required":["ok","reason"],"properties":{"ok":{"enum":[false],"type":"boolean"},"reason":{"anyOf":[{"enum":["not-installed"],"type":"string"},{"enum":["gone"],"type":"string"},{"enum":["link-failed"],"type":"string"}]}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}}}}}},"/api/jira/remote/pairing-requests/decline":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraForgeDeclinePairingRequest","summary":"Decline a Jira pairing request","description":"Declines a pending pairing request for the site named by the invocation token. Called from the Jira admin page, restricted to a site admin by `jira:adminPage`, and returns ok even if the request is already settled. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeDeclinePairingRequest","type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"minLength":1,"maxLength":64,"type":"string"}}}}}}}},"/api/jira/remote/disconnect":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraForgeDisconnect","summary":"Disconnect an organization from a Jira site","description":"Releases one organization from the Jira site named by the invocation token, given its organizationId in the request body. Called from the Jira admin page, restricted to a site admin by `jira:adminPage`, and returns ok with zero released if the link is already gone. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeDisconnect","type":"object","required":["ok","released"],"properties":{"ok":{"type":"boolean"},"released":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"minLength":1,"maxLength":64,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"minLength":1,"maxLength":64,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"minLength":1,"maxLength":64,"type":"string"}}}}}}}},"/api/jira/remote/issue-repositories":{"post":{"operationId":"jiraForgeIssueRepositories","summary":"List repositories for a Jira work item field","description":"Lists the repo-backed services mapped to the Jira project named in the invocation context, for the work item's Repository field picker. The project comes only from the signed token, never the request body, so no caller can enumerate another organization's mappings. Authenticated by a Forge Invocation Token that `forgeAuthPlugin` verifies against Atlassian's JWKS.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraForgeIssueRepositories","type":"object","required":["repositories"],"properties":{"repositories":{"type":"array","items":{"type":"object","required":["serviceId","name","selectable","unavailable"],"properties":{"serviceId":{"type":"string"},"name":{"type":"string"},"selectable":{"type":"boolean"},"unavailable":{"nullable":true,"anyOf":[{"enum":["paused"],"type":"string"},{"enum":["no-repository"],"type":"string"}]}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/.well-known/agent-card.json":{"get":{"operationId":"jiraGetAgentCard","summary":"Serve the A2A agent card","description":"Serves the A2A agent card describing Rock8Cloud's Jira agent connector, at the conventional well-known discovery path. Unauthenticated, since Jira must discover the agent before it can send any credential.","tags":["Jira","Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"A2aAgentCard","additionalProperties":true,"type":"object","required":["name","description","version","capabilities","defaultInputModes","defaultOutputModes","skills","supportedInterfaces"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"capabilities":{"type":"object","required":["streaming","pushNotifications"],"properties":{"streaming":{"type":"boolean"},"pushNotifications":{"type":"boolean"}}},"defaultInputModes":{"type":"array","items":{"type":"string"}},"defaultOutputModes":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"object","required":["id","name","description","tags"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}},"supportedInterfaces":{"type":"array","items":{"type":"object","required":["url","protocolBinding","protocolVersion"],"properties":{"url":{"type":"string"},"protocolBinding":{"type":"string"},"protocolVersion":{"type":"string"}}}}}}}}}}}},"/.well-known/agent.json":{"get":{"operationId":"jiraGetAgentCardLegacy","summary":"Serve the A2A agent card at the legacy path","description":"Serves the same A2A agent card at a legacy well-known path, kept because it is unclear which one the platform looks for. Unauthenticated, since Jira must discover the agent before it can send any credential.","tags":["Jira","Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"A2aAgentCard","additionalProperties":true,"type":"object","required":["name","description","version","capabilities","defaultInputModes","defaultOutputModes","skills","supportedInterfaces"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"capabilities":{"type":"object","required":["streaming","pushNotifications"],"properties":{"streaming":{"type":"boolean"},"pushNotifications":{"type":"boolean"}}},"defaultInputModes":{"type":"array","items":{"type":"string"}},"defaultOutputModes":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"object","required":["id","name","description","tags"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}},"supportedInterfaces":{"type":"array","items":{"type":"object","required":["url","protocolBinding","protocolVersion"],"properties":{"url":{"type":"string"},"protocolBinding":{"type":"string"},"protocolVersion":{"type":"string"}}}}}}}}}}}},"/api/jira/a2a":{"get":{"operationId":"jiraGetAgentCardAtEndpoint","summary":"Serve the A2A agent card at the endpoint path","description":"Serves the same A2A agent card at the JSON-RPC endpoint's own path, as a fallback discovery location. Unauthenticated, since Jira must discover the agent before it can send any credential.","tags":["Jira","Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"A2aAgentCard","additionalProperties":true,"type":"object","required":["name","description","version","capabilities","defaultInputModes","defaultOutputModes","skills","supportedInterfaces"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"capabilities":{"type":"object","required":["streaming","pushNotifications"],"properties":{"streaming":{"type":"boolean"},"pushNotifications":{"type":"boolean"}}},"defaultInputModes":{"type":"array","items":{"type":"string"}},"defaultOutputModes":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"object","required":["id","name","description","tags"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}},"supportedInterfaces":{"type":"array","items":{"type":"object","required":["url","protocolBinding","protocolVersion"],"properties":{"url":{"type":"string"},"protocolBinding":{"type":"string"},"protocolVersion":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraA2aJsonRpc","summary":"Handle A2A JSON-RPC requests from Jira","description":"Handles the A2A JSON-RPC protocol for Rock8Cloud's Jira agent connector: SendMessage claims a work item assignment or mention and enqueues the run, GetTask polls its progress. Requires a Forge Invocation Token verified against Atlassian's JWKS, checked in the handler rather than declared on the manifest so Forge does not require a client it cannot authenticate. Always answers 200 with a JSON-RPC envelope, using its error field for authentication, validation and internal failures instead of an HTTP error status.","tags":["Jira","Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JsonRpcResponse","anyOf":[{"type":"object","required":["jsonrpc","id","result"],"properties":{"jsonrpc":{"enum":["2.0"],"type":"string"},"id":{"nullable":true,"anyOf":[{"type":"string"},{"type":"number"}]},"result":{}}},{"type":"object","required":["jsonrpc","id","error"],"properties":{"jsonrpc":{"enum":["2.0"],"type":"string"},"id":{"nullable":true,"anyOf":[{"type":"string"},{"type":"number"}]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"number"},"message":{"type":"string"},"data":{}}}}}]}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","properties":{"jsonrpc":{"type":"string"},"id":{"nullable":true,"anyOf":[{"type":"string"},{"type":"number"}]},"method":{"type":"string"},"params":{}}}},"multipart/form-data":{"schema":{"additionalProperties":true,"type":"object","properties":{"jsonrpc":{"type":"string"},"id":{"nullable":true,"anyOf":[{"type":"string"},{"type":"number"}]},"method":{"type":"string"},"params":{}}}},"text/plain":{"schema":{"additionalProperties":true,"type":"object","properties":{"jsonrpc":{"type":"string"},"id":{"nullable":true,"anyOf":[{"type":"string"},{"type":"number"}]},"method":{"type":"string"},"params":{}}}}}}}},"/api/jira/pairing-request":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraCreatePairingRequest","summary":"Start a pairing request with a Jira site","description":"Starts a pairing between the active organization and a Jira site given its hostname. Verifies the site exists before creating a request, and requires the organization owner role for session callers or the `read:organization` and `write:organization` scopes for bearer tokens. Rate limited per organization, returns 429 when exceeded and 503 if the site can't be reached.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["request"],"properties":{"request":{"title":"JiraPairingRequest","type":"object","required":["id","siteHost","status","expiresAt","createdAt","jiraAppUrl"],"properties":{"id":{"type":"string"},"siteHost":{"type":"string"},"status":{"type":"string"},"expiresAt":{"type":"string"},"createdAt":{"type":"string"},"jiraAppUrl":{"nullable":true,"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["siteHost"],"properties":{"siteHost":{"minLength":1,"maxLength":255,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["siteHost"],"properties":{"siteHost":{"minLength":1,"maxLength":255,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["siteHost"],"properties":{"siteHost":{"minLength":1,"maxLength":255,"type":"string"}}}}}}},"get":{"operationId":"jiraListPairingRequests","summary":"List the organization's Jira pairing requests","description":"Lists the pairing requests the active organization started within the recent history window, including settled ones so the popup UI can show an outcome. Requires an active organization and the `read:organization` scope for bearer tokens. Any organization member may call it.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["requests"],"properties":{"requests":{"type":"array","items":{"title":"JiraPairingRequest","type":"object","required":["id","siteHost","status","expiresAt","createdAt","jiraAppUrl"],"properties":{"id":{"type":"string"},"siteHost":{"type":"string"},"status":{"type":"string"},"expiresAt":{"type":"string"},"createdAt":{"type":"string"},"jiraAppUrl":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/pairing-request/{id}/open":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraOpenPairingRequest","summary":"Continue a pairing request in Jira","description":"Redirects to continue an open pairing request in Jira, or back to the Jira settings page if it has already settled. `id` identifies the pairing request, scoped to the active organization. Requires the organization owner role for all callers and the `read:organization` scope for bearer tokens. Returns 404 if the pairing request is not found in the active organization.","tags":["Jira"],"responses":{"302":{"description":"Redirects to the Jira app page or install link for an open request, or to the Jira settings page once it has settled. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/jira/pairing-request/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraCancelPairingRequest","summary":"Cancel a Jira pairing request","description":"Cancels a pending pairing request. `id` identifies the pairing request, scoped to the active organization. Requires the organization owner role for session callers or the `read:organization` and `write:organization` scopes for bearer tokens. Already settled requests are treated as success rather than an error.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraOk","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/jira/installation":{"get":{"operationId":"jiraListInstallations","summary":"List the organization's linked Jira sites","description":"Lists every Jira site linked to the active organization, including the Jira admin page URL for each. Requires `read:organization` for bearer tokens or organization member read access for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["installations"],"properties":{"installations":{"type":"array","items":{"title":"JiraInstallation","type":"object","required":["id","siteUrl","cloudId","productType","linkedAt","installedAt","jiraAppUrl"],"properties":{"id":{"type":"string"},"siteUrl":{"type":"string"},"cloudId":{"nullable":true,"type":"string"},"productType":{"type":"string"},"linkedAt":{"type":"string","format":"date-time"},"installedAt":{"type":"string","format":"date-time"},"jiraAppUrl":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/mappable-services":{"get":{"operationId":"jiraListMappableServices","summary":"List services a Jira project can be mapped onto","description":"Lists every repo-backed service in the active organization that a Jira project can be mapped onto. Requires `read:organization` for bearer tokens or organization member read access for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"title":"JiraMappableService","type":"object","required":["id","name","projectId","projectName","branch","repoUrl"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"projectName":{"type":"string"},"branch":{"nullable":true,"type":"string"},"repoUrl":{"nullable":true,"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/jira/projects":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"installationId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraListProjects","summary":"List a linked Jira site's projects","description":"Lists the Jira projects visible through a linked site's app installation, given its id in the `installationId` query param. Marks which projects are already mapped to a service in this organization and which are held by another organization on the same site, without naming the holder. Requires `read:organization` for bearer tokens or organization member read access for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["projects"],"properties":{"projects":{"type":"array","items":{"title":"JiraProject","type":"object","required":["key","name","mapped","mappedServiceIds"],"properties":{"key":{"type":"string"},"name":{"type":"string"},"mapped":{"type":"boolean"},"mappedServiceIds":{"type":"array","items":{"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/jira/installation/{id}":{"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraReleaseInstallation","summary":"Release a Jira site from the organization","description":"Releases a Jira site from the active organization so it can be re-paired later with a new code. `id` identifies the installation, scoped to the active organization. Requires `read:organization` and `write:organization` for bearer tokens or the organization owner role for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraOk","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/jira/project-mappings":{"get":{"operationId":"jiraListProjectMappings","summary":"List the organization's Jira project mappings","description":"Lists every Jira project to service mapping owned by the active organization, across all its linked sites. Requires `read:organization` for bearer tokens or organization member read access for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["mappings"],"properties":{"mappings":{"type":"array","items":{"title":"JiraProjectMappingSummary","type":"object","required":["id","jiraInstallationId","jiraProjectKey","serviceId","serviceName","projectId","baseBranch","effectiveBaseBranch","enabled","serviceHasRepository","createdAt"],"properties":{"id":{"type":"string"},"jiraInstallationId":{"type":"string"},"jiraProjectKey":{"type":"string"},"serviceId":{"type":"string"},"serviceName":{"type":"string"},"projectId":{"type":"string"},"baseBranch":{"nullable":true,"type":"string"},"effectiveBaseBranch":{"type":"string"},"enabled":{"type":"boolean"},"serviceHasRepository":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraCreateProjectMapping","summary":"Map a Jira project to a service","description":"Creates a mapping from a Jira project to a repo-backed service and emits an audit log entry. Requires `read:organization` and `write:organization` for bearer tokens or the organization owner role for session callers. Returns 409 if the repository is already mapped or the project is already claimed by another organization on the same site.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["mapping"],"properties":{"mapping":{"title":"JiraProjectMapping","type":"object","required":["id","jiraInstallationId","jiraProjectKey","jiraProjectId","organizationId","serviceId","baseBranch","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"jiraInstallationId":{"type":"string"},"jiraProjectKey":{"type":"string"},"jiraProjectId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"baseBranch":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jiraInstallationId","jiraProjectKey","serviceId"],"properties":{"jiraInstallationId":{"format":"uuid","type":"string"},"jiraProjectKey":{"minLength":1,"maxLength":100,"type":"string"},"jiraProjectId":{"maxLength":50,"type":"string"},"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"maxLength":255,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["jiraInstallationId","jiraProjectKey","serviceId"],"properties":{"jiraInstallationId":{"format":"uuid","type":"string"},"jiraProjectKey":{"minLength":1,"maxLength":100,"type":"string"},"jiraProjectId":{"maxLength":50,"type":"string"},"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"maxLength":255,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["jiraInstallationId","jiraProjectKey","serviceId"],"properties":{"jiraInstallationId":{"format":"uuid","type":"string"},"jiraProjectKey":{"minLength":1,"maxLength":100,"type":"string"},"jiraProjectId":{"maxLength":50,"type":"string"},"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"maxLength":255,"type":"string"}}}}}}}},"/api/jira/project-mappings/{id}":{"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraUpdateProjectMapping","summary":"Update a Jira project mapping","description":"Updates a project mapping's service, base branch or enabled state, scoped to a mapping owned by the active organization, and emits an audit log entry. `id` identifies the mapping. Requires `read:organization` and `write:organization` for bearer tokens or the organization owner role for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["mapping"],"properties":{"mapping":{"title":"JiraProjectMapping","type":"object","required":["id","jiraInstallationId","jiraProjectKey","jiraProjectId","organizationId","serviceId","baseBranch","enabled","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"jiraInstallationId":{"type":"string"},"jiraProjectKey":{"type":"string"},"jiraProjectId":{"nullable":true,"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"baseBranch":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"nullable":true,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"nullable":true,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","properties":{"serviceId":{"format":"uuid","type":"string"},"baseBranch":{"nullable":true,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}}}}},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"jiraDeleteProjectMapping","summary":"Delete a Jira project mapping","description":"Deletes a project mapping owned by the active organization and emits an audit log entry, freeing the Jira project key for another organization to claim. `id` identifies the mapping. Requires `read:organization` and `write:organization` for bearer tokens or the organization owner role for session callers.","tags":["Jira"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"JiraOk","type":"object","required":["ok"],"properties":{"ok":{"enum":[true],"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/{serviceId}/workflows":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listWorkflows","summary":"List automation workflows for a service","description":"Lists deploy-on-push, preview and other automation workflows defined on a service, with their steps. Requires scope `read:workflows`.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflows"],"properties":{"workflows":{"type":"array","items":{"title":"WorkflowWithSteps","type":"object","required":["id","serviceId","name","slug","description","templateId","enabled","notificationChannelIds","notificationConfig","triggerType","triggerConfig","filterConfig","createdAt","updatedAt","steps"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"WorkflowStep","type":"object","required":["id","workflowId","name","actionType","config","position","dependsOn","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"name":{"type":"string"},"actionType":{"anyOf":[{"enum":["build_and_deploy"],"type":"string"},{"enum":["preview_deploy"],"type":"string"},{"enum":["ai_project_scan"],"type":"string"},{"enum":["ai_code_review"],"type":"string"},{"enum":["ai_coder"],"type":"string"},{"enum":["service_analysis"],"type":"string"},{"enum":["changelog_generate"],"type":"string"},{"enum":["github_check_run"],"type":"string"},{"enum":["github_pr_comment"],"type":"string"},{"enum":["dockerfile_init"],"type":"string"}]},"config":{"additionalProperties":true,"type":"object","properties":{}},"position":{"type":"number"},"dependsOn":{"nullable":true,"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/{serviceId}/workflows/from-template":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createWorkflowFromTemplate","summary":"Create an automation workflow from a template","description":"Creates an automation workflow on a service from a built-in template identified by `templateId`. Fails with a conflict when the template is a singleton already installed for the service. Requires scopes `read:workflows` and `write:workflows`.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"WorkflowWithSteps","type":"object","required":["id","serviceId","name","slug","description","templateId","enabled","notificationChannelIds","notificationConfig","triggerType","triggerConfig","filterConfig","createdAt","updatedAt","steps"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"WorkflowStep","type":"object","required":["id","workflowId","name","actionType","config","position","dependsOn","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"name":{"type":"string"},"actionType":{"anyOf":[{"enum":["build_and_deploy"],"type":"string"},{"enum":["preview_deploy"],"type":"string"},{"enum":["ai_project_scan"],"type":"string"},{"enum":["ai_code_review"],"type":"string"},{"enum":["ai_coder"],"type":"string"},{"enum":["service_analysis"],"type":"string"},{"enum":["changelog_generate"],"type":"string"},{"enum":["github_check_run"],"type":"string"},{"enum":["github_pr_comment"],"type":"string"},{"enum":["dockerfile_init"],"type":"string"}]},"config":{"additionalProperties":true,"type":"object","properties":{}},"position":{"type":"number"},"dependsOn":{"nullable":true,"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["templateId"],"properties":{"templateId":{"type":"string"},"enabled":{"type":"boolean"},"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}}}}},"multipart/form-data":{"schema":{"type":"object","required":["templateId"],"properties":{"templateId":{"type":"string"},"enabled":{"type":"boolean"},"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}}}}},"text/plain":{"schema":{"type":"object","required":["templateId"],"properties":{"templateId":{"type":"string"},"enabled":{"type":"boolean"},"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}}}}}}}}},"/api/services/{serviceId}/workflow-templates":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listWorkflowTemplates","summary":"List available automation workflow templates","description":"Lists built-in automation workflow templates visible for a service, excluding ones whose required agent feature is disabled for the organization, each flagged with whether a singleton instance already exists. Requires scope `read:workflows`.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["templates"],"properties":{"templates":{"type":"array","items":{"title":"WorkflowTemplate","type":"object","required":["id","name","slug","description","triggerType","triggerConfig","steps","singleton","alreadyExists"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"steps":{"type":"array","items":{"type":"object","required":["name","actionType","position"],"properties":{"name":{"type":"string"},"actionType":{"anyOf":[{"enum":["build_and_deploy"],"type":"string"},{"enum":["preview_deploy"],"type":"string"},{"enum":["ai_project_scan"],"type":"string"},{"enum":["ai_code_review"],"type":"string"},{"enum":["ai_coder"],"type":"string"},{"enum":["service_analysis"],"type":"string"},{"enum":["changelog_generate"],"type":"string"},{"enum":["github_check_run"],"type":"string"},{"enum":["github_pr_comment"],"type":"string"},{"enum":["dockerfile_init"],"type":"string"}]},"position":{"type":"number"}}}},"singleton":{"type":"boolean"},"alreadyExists":{"type":"boolean"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/{serviceId}/workflows/{workflowId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"workflowId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getWorkflow","summary":"Get an automation workflow","description":"Returns one automation workflow identified by `workflowId` on a service, with its steps. Requires scope `read:workflows`.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"WorkflowWithSteps","type":"object","required":["id","serviceId","name","slug","description","templateId","enabled","notificationChannelIds","notificationConfig","triggerType","triggerConfig","filterConfig","createdAt","updatedAt","steps"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"WorkflowStep","type":"object","required":["id","workflowId","name","actionType","config","position","dependsOn","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"name":{"type":"string"},"actionType":{"anyOf":[{"enum":["build_and_deploy"],"type":"string"},{"enum":["preview_deploy"],"type":"string"},{"enum":["ai_project_scan"],"type":"string"},{"enum":["ai_code_review"],"type":"string"},{"enum":["ai_coder"],"type":"string"},{"enum":["service_analysis"],"type":"string"},{"enum":["changelog_generate"],"type":"string"},{"enum":["github_check_run"],"type":"string"},{"enum":["github_pr_comment"],"type":"string"},{"enum":["dockerfile_init"],"type":"string"}]},"config":{"additionalProperties":true,"type":"object","properties":{}},"position":{"type":"number"},"dependsOn":{"nullable":true,"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"workflowId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateWorkflow","summary":"Update an automation workflow","description":"Edits an automation workflow identified by `workflowId`: name, description, notification channels, trigger config or filter config. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"Workflow","type":"object","required":["id","serviceId","name","slug","description","templateId","enabled","notificationChannelIds","notificationConfig","triggerType","triggerConfig","filterConfig","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}}}}},"text/plain":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"workflowId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteWorkflow","summary":"Delete an automation workflow","description":"Deletes an automation workflow identified by `workflowId`. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/services/{serviceId}/workflows/{workflowId}/toggle":{"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"workflowId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"toggleWorkflow","summary":"Enable or disable an automation workflow","description":"Sets the enabled flag on an automation workflow identified by `workflowId`. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"Workflow","type":"object","required":["id","serviceId","name","slug","description","templateId","enabled","notificationChannelIds","notificationConfig","triggerType","triggerConfig","filterConfig","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string"},"enabled":{"type":"boolean"},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"notificationConfig":{"type":"object","required":["notifyOn"],"properties":{"notifyOn":{"anyOf":[{"enum":["all"],"type":"string"},{"enum":["failure_only"],"type":"string"}]}}},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"filterConfig":{"nullable":true,"type":"object","properties":{"pathFilters":{"type":"array","items":{"type":"string"}},"aiFeatureGate":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}}}}}},"/api/services/{serviceId}/workflows/{workflowId}/runs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"path","name":"workflowId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listWorkflowRuns","summary":"List runs for an automation workflow","description":"Lists the most recent runs of an automation workflow identified by `workflowId`. Requires scope `read:workflows`.","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runs"],"properties":{"runs":{"type":"array","items":{"title":"WorkflowRun","type":"object","required":["id","workflowId","status","triggerData","organizationId","serviceId","deploymentId","jobId","webhookDeliveryId","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"triggerData":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"deploymentId":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"webhookDeliveryId":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agent-workflow/":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAgentWorkflows","summary":"List agent workflows for a service","description":"Lists agent workflows defined on a service, each with its enabled cron schedule projected when the trigger type is cron. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflows"],"properties":{"workflows":{"type":"array","items":{"title":"AgentWorkflowSummary","type":"object","required":["id","organizationId","serviceId","name","enabled","triggerType","triggerConfig","notificationChannelIds","version","deletedAt","createdAt","updatedAt","schedule"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"deletedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"schedule":{"nullable":true,"type":"object","required":["id","expression","timezone","nextRunAt","lastOccurrenceAt","lastStatus","lastStatusReason"],"properties":{"id":{"type":"string"},"expression":{"type":"string"},"timezone":{"type":"string"},"nextRunAt":{"nullable":true,"type":"string","format":"date-time"},"lastOccurrenceAt":{"nullable":true,"type":"string","format":"date-time"},"lastStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["dispatched"],"type":"string"},{"enum":["skipped"],"type":"string"},{"enum":["failed"],"type":"string"}]},"lastStatusReason":{"nullable":true,"type":"string"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAgentWorkflow","summary":"Create an agent workflow","description":"Creates an agent workflow on a service with a single parallel step group and, for a cron trigger, its schedule. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"AgentWorkflow","type":"object","required":["id","organizationId","serviceId","name","enabled","triggerType","triggerConfig","notificationChannelIds","version","deletedAt","createdAt","updatedAt","steps","schedule"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"deletedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"AgentWorkflowStep","type":"object","required":["id","workflowId","customAgentId","position","enabled","config","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"type":"number"},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize","deliveries"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"}}},{"type":"object","required":["type","headBranch","baseBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"},"prTitle":{"type":"string"},"prBody":{"type":"string"}}}]},"deliveries":{"type":"array","items":{"title":"AgentWorkflowDelivery","description":"Webhook secrets are never returned, only `hasSecret`.","type":"object","required":["index","type","config"],"properties":{"index":{"type":"number"},"type":{"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"config":{"anyOf":[{"type":"object","required":["url","hasSecret"],"properties":{"url":{"type":"string"},"hasSecret":{"type":"boolean"}}},{"type":"object","required":["channelIds"],"properties":{"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"schedule":{"nullable":true,"title":"AgentWorkflowSchedule","type":"object","required":["id","expression","timezone","nextRunAt","lastOccurrenceAt","lastStatus","lastStatusReason","contextMarkdown"],"properties":{"id":{"type":"string"},"expression":{"type":"string"},"timezone":{"type":"string"},"nextRunAt":{"nullable":true,"type":"string","format":"date-time"},"lastOccurrenceAt":{"nullable":true,"type":"string","format":"date-time"},"lastStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["dispatched"],"type":"string"},{"enum":["skipped"],"type":"string"},{"enum":["failed"],"type":"string"}]},"lastStatusReason":{"nullable":true,"type":"string"},"contextMarkdown":{"nullable":true,"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["serviceId","name","triggerType","steps"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}},"multipart/form-data":{"schema":{"type":"object","required":["serviceId","name","triggerType","steps"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}},"text/plain":{"schema":{"type":"object","required":["serviceId","name","triggerType","steps"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}}}}}},"/api/agent-workflow/callable":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"projectId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listCallableAgentWorkflows","summary":"List callable agent workflows in a project","description":"Lists the enabled agent workflows in a project that another agent can hand off to via the trigger_workflow tool. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflows"],"properties":{"workflows":{"type":"array","items":{"type":"object","required":["id","name","serviceId"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"serviceId":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agent-workflow/runs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"serviceId","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAgentWorkflowRunsByService","summary":"List agent workflow runs for a service","description":"Lists agent workflow runs for a service, offset-paginated. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runs","limit","offset"],"properties":{"runs":{"type":"array","items":{"title":"AgentWorkflowRunSummary","type":"object","required":["id","workflowId","organizationId","serviceId","status","triggerKey","planVersion","triggeredBy","parentWorkflowRunId","cancelReason","completedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"triggerKey":{"type":"string"},"planVersion":{"type":"number"},"triggeredBy":{"nullable":true,"type":"string"},"parentWorkflowRunId":{"nullable":true,"type":"string"},"cancelReason":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agent-workflow/runs/{runId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"runId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentWorkflowRun","summary":"Get an agent workflow run","description":"Returns one agent workflow run identified by `runId`, with its step runs and delivery intents. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["run"],"properties":{"run":{"title":"AgentWorkflowRun","type":"object","required":["id","workflowId","organizationId","serviceId","status","triggerKey","planVersion","triggeredBy","parentWorkflowRunId","cancelReason","completedAt","createdAt","updatedAt","triggerContext","stepRuns"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"triggerKey":{"type":"string"},"planVersion":{"type":"number"},"triggeredBy":{"nullable":true,"type":"string"},"parentWorkflowRunId":{"nullable":true,"type":"string"},"cancelReason":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"triggerContext":{"additionalProperties":true,"type":"object","properties":{}},"stepRuns":{"type":"array","items":{"title":"AgentWorkflowStepRun","type":"object","required":["id","runId","sourceStepId","position","status","jobId","error","cancelReason","customAgentId","agentSnapshot","finalize","deliveryIntents","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"runId":{"type":"string"},"sourceStepId":{"type":"string"},"position":{"type":"number"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"jobId":{"nullable":true,"type":"string"},"error":{"nullable":true,"type":"string"},"cancelReason":{"nullable":true,"type":"string"},"customAgentId":{"type":"string"},"agentSnapshot":{"type":"object","required":["systemPrompt","allowedTools","repoCheckout","name","configHash"],"properties":{"systemPrompt":{"type":"string"},"allowedTools":{"type":"array","items":{"type":"string"}},"repoCheckout":{"type":"boolean"},"name":{"type":"string"},"aiProviderModelId":{"nullable":true,"type":"string"},"configHash":{"type":"string"}}},"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"}}},{"type":"object","required":["type","headBranch","baseBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"},"prTitle":{"type":"string"},"prBody":{"type":"string"}}}]},"deliveryIntents":{"type":"array","items":{"title":"AgentWorkflowDelivery","description":"Webhook secrets are never returned, only `hasSecret`.","type":"object","required":["index","type","config"],"properties":{"index":{"type":"number"},"type":{"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"config":{"anyOf":[{"type":"object","required":["url","hasSecret"],"properties":{"url":{"type":"string"},"hasSecret":{"type":"boolean"}}},{"type":"object","required":["channelIds"],"properties":{"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agent-workflow/from-template/changelog":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAgentWorkflowFromChangelogTemplate","summary":"Install the changelog agent workflow template","description":"Creates the changelog custom agent and a pull-request-triggered agent workflow that runs it on a service, from the built-in changelog template. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"AgentWorkflow","type":"object","required":["id","organizationId","serviceId","name","enabled","triggerType","triggerConfig","notificationChannelIds","version","deletedAt","createdAt","updatedAt","steps","schedule"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"deletedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"AgentWorkflowStep","type":"object","required":["id","workflowId","customAgentId","position","enabled","config","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"type":"number"},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize","deliveries"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"}}},{"type":"object","required":["type","headBranch","baseBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"},"prTitle":{"type":"string"},"prBody":{"type":"string"}}}]},"deliveries":{"type":"array","items":{"title":"AgentWorkflowDelivery","description":"Webhook secrets are never returned, only `hasSecret`.","type":"object","required":["index","type","config"],"properties":{"index":{"type":"number"},"type":{"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"config":{"anyOf":[{"type":"object","required":["url","hasSecret"],"properties":{"url":{"type":"string"},"hasSecret":{"type":"boolean"}}},{"type":"object","required":["channelIds"],"properties":{"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"schedule":{"nullable":true,"title":"AgentWorkflowSchedule","type":"object","required":["id","expression","timezone","nextRunAt","lastOccurrenceAt","lastStatus","lastStatusReason","contextMarkdown"],"properties":{"id":{"type":"string"},"expression":{"type":"string"},"timezone":{"type":"string"},"nextRunAt":{"nullable":true,"type":"string","format":"date-time"},"lastOccurrenceAt":{"nullable":true,"type":"string","format":"date-time"},"lastStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["dispatched"],"type":"string"},{"enum":["skipped"],"type":"string"},{"enum":["failed"],"type":"string"}]},"lastStatusReason":{"nullable":true,"type":"string"},"contextMarkdown":{"nullable":true,"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["serviceId"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","required":["serviceId"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","required":["serviceId"],"properties":{"serviceId":{"type":"string"},"name":{"minLength":1,"maxLength":255,"type":"string"},"enabled":{"type":"boolean"}}}}}}}},"/api/agent-workflow/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentWorkflow","summary":"Get an agent workflow","description":"Returns one agent workflow identified by `id`, with its projected steps and, for a cron trigger, its schedule. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"title":"AgentWorkflow","type":"object","required":["id","organizationId","serviceId","name","enabled","triggerType","triggerConfig","notificationChannelIds","version","deletedAt","createdAt","updatedAt","steps","schedule"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"deletedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"AgentWorkflowStep","type":"object","required":["id","workflowId","customAgentId","position","enabled","config","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"type":"number"},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize","deliveries"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"}}},{"type":"object","required":["type","headBranch","baseBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"},"prTitle":{"type":"string"},"prBody":{"type":"string"}}}]},"deliveries":{"type":"array","items":{"title":"AgentWorkflowDelivery","description":"Webhook secrets are never returned, only `hasSecret`.","type":"object","required":["index","type","config"],"properties":{"index":{"type":"number"},"type":{"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"config":{"anyOf":[{"type":"object","required":["url","hasSecret"],"properties":{"url":{"type":"string"},"hasSecret":{"type":"boolean"}}},{"type":"object","required":["channelIds"],"properties":{"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"schedule":{"nullable":true,"title":"AgentWorkflowSchedule","type":"object","required":["id","expression","timezone","nextRunAt","lastOccurrenceAt","lastStatus","lastStatusReason","contextMarkdown"],"properties":{"id":{"type":"string"},"expression":{"type":"string"},"timezone":{"type":"string"},"nextRunAt":{"nullable":true,"type":"string","format":"date-time"},"lastOccurrenceAt":{"nullable":true,"type":"string","format":"date-time"},"lastStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["dispatched"],"type":"string"},{"enum":["skipped"],"type":"string"},{"enum":["failed"],"type":"string"}]},"lastStatusReason":{"nullable":true,"type":"string"},"contextMarkdown":{"nullable":true,"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateAgentWorkflow","summary":"Update an agent workflow","description":"Edits an agent workflow identified by `id` with optimistic concurrency via `expectedVersion`. Returns 409 with `code: version_conflict` on a stale version. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"nullable":true,"title":"AgentWorkflow","type":"object","required":["id","organizationId","serviceId","name","enabled","triggerType","triggerConfig","notificationChannelIds","version","deletedAt","createdAt","updatedAt","steps","schedule"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"triggerType":{"anyOf":[{"enum":["push"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"},{"enum":["manual"],"type":"string"},{"enum":["rollback"],"type":"string"},{"enum":["cron"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"deletedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"title":"AgentWorkflowStep","type":"object","required":["id","workflowId","customAgentId","position","enabled","config","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"type":"number"},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize","deliveries"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"}}},{"type":"object","required":["type","headBranch","baseBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"type":"string"},"prTitle":{"type":"string"},"prBody":{"type":"string"}}}]},"deliveries":{"type":"array","items":{"title":"AgentWorkflowDelivery","description":"Webhook secrets are never returned, only `hasSecret`.","type":"object","required":["index","type","config"],"properties":{"index":{"type":"number"},"type":{"anyOf":[{"enum":["webhook"],"type":"string"},{"enum":["notify"],"type":"string"}]},"config":{"anyOf":[{"type":"object","required":["url","hasSecret"],"properties":{"url":{"type":"string"},"hasSecret":{"type":"boolean"}}},{"type":"object","required":["channelIds"],"properties":{"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"schedule":{"nullable":true,"title":"AgentWorkflowSchedule","type":"object","required":["id","expression","timezone","nextRunAt","lastOccurrenceAt","lastStatus","lastStatusReason","contextMarkdown"],"properties":{"id":{"type":"string"},"expression":{"type":"string"},"timezone":{"type":"string"},"nextRunAt":{"nullable":true,"type":"string","format":"date-time"},"lastOccurrenceAt":{"nullable":true,"type":"string","format":"date-time"},"lastStatus":{"nullable":true,"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["dispatched"],"type":"string"},{"enum":["skipped"],"type":"string"},{"enum":["failed"],"type":"string"}]},"lastStatusReason":{"nullable":true,"type":"string"},"contextMarkdown":{"nullable":true,"type":"string"}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"name":{"minLength":1,"maxLength":255,"type":"string"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"stepId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}},"multipart/form-data":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"name":{"minLength":1,"maxLength":255,"type":"string"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"stepId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}},"text/plain":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]},"name":{"minLength":1,"maxLength":255,"type":"string"},"triggerType":{"anyOf":[{"enum":["manual"],"type":"string"},{"enum":["cron"],"type":"string"},{"enum":["pull_request"],"type":"string"},{"enum":["push"],"type":"string"},{"enum":["deployment_success"],"type":"string"},{"enum":["deployment_failed"],"type":"string"},{"enum":["build_success"],"type":"string"},{"enum":["build_failed"],"type":"string"}]},"triggerConfig":{"type":"object","properties":{"branch":{"type":"string"},"branchPattern":{"type":"string"},"tagPattern":{"type":"string"},"actions":{"type":"array","items":{"anyOf":[{"enum":["opened"],"type":"string"},{"enum":["synchronize"],"type":"string"},{"enum":["closed"],"type":"string"}]}},"sourceBranchPattern":{"type":"string"},"targetBranch":{"type":"string"},"environmentType":{"anyOf":[{"enum":["stable"],"type":"string"},{"enum":["preview"],"type":"string"}]}}},"schedule":{"type":"object","required":["expression","timezone"],"properties":{"expression":{"minLength":1,"maxLength":255,"type":"string"},"timezone":{"minLength":1,"maxLength":255,"type":"string"},"contextMarkdown":{"maxLength":65536,"type":"string"}}},"notificationChannelIds":{"type":"array","items":{"type":"string"}},"steps":{"minItems":1,"type":"array","items":{"type":"object","required":["customAgentId","config"],"properties":{"stepId":{"type":"string"},"customAgentId":{"type":"string"},"position":{"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]},"enabled":{"type":"boolean"},"config":{"type":"object","required":["finalize"],"properties":{"finalize":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"enum":["none"],"type":"string"}}},{"type":"object","required":["type","targetBranch","commitPaths"],"properties":{"type":{"enum":["commit"],"type":"string"},"targetBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"}}},{"type":"object","required":["type","headBranch","commitPaths"],"properties":{"type":{"enum":["branch-pr"],"type":"string"},"headBranch":{"type":"string"},"baseBranch":{"type":"string"},"commitPaths":{"type":"array","items":{"type":"string"}},"commitMessage":{"maxLength":2000,"type":"string"},"prTitle":{"maxLength":256,"type":"string"},"prBody":{"maxLength":60000,"type":"string"}}}]},"deliveries":{"type":"array","items":{"anyOf":[{"type":"object","required":["type","url"],"properties":{"type":{"enum":["webhook"],"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},{"type":"object","required":["type","channelIds"],"properties":{"type":{"enum":["notify"],"type":"string"},"channelIds":{"type":"array","items":{"type":"string"}}}}]}}}}}}}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deleteAgentWorkflow","summary":"Delete an agent workflow","description":"Soft-deletes an agent workflow identified by `id` with optimistic concurrency via `expectedVersion`. Returns 409 with `code: version_conflict` on a stale version. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["expectedVersion"],"properties":{"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}}}}}},"/api/agent-workflow/{id}/toggle":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"toggleAgentWorkflow","summary":"Enable or disable an agent workflow","description":"Sets the enabled flag on an agent workflow identified by `id` with optimistic concurrency via `expectedVersion`. Returns 409 with `code: version_conflict` on a stale version. Requires scopes `read:workflows` and `write:workflows` and organization write access.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled","expectedVersion"],"properties":{"enabled":{"type":"boolean"},"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["enabled","expectedVersion"],"properties":{"enabled":{"type":"boolean"},"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","required":["enabled","expectedVersion"],"properties":{"enabled":{"type":"boolean"},"expectedVersion":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}}}}}},"/api/agent-workflow/{id}/run":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"runAgentWorkflow","summary":"Manually run an agent workflow","description":"Admits a manual run of the agent workflow identified by `id`, optionally scoped to an open pull request via `prNumber`. Requires scopes `read:workflows` and `write:workflows` for bearer callers and canWriteResources for session callers.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runId"],"properties":{"runId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prNumber":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"prNumber":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}},"text/plain":{"schema":{"type":"object","properties":{"prNumber":{"minimum":1,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":1,"type":"integer"}]}}}}}}}},"/api/agent-workflow/{id}/runs":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAgentWorkflowRunsByWorkflow","summary":"List runs for an agent workflow","description":"Lists runs of the agent workflow identified by `id`, offset-paginated. Requires scope `read:workflows`.","tags":["Agent workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runs","limit","offset"],"properties":{"runs":{"type":"array","items":{"title":"AgentWorkflowRunSummary","type":"object","required":["id","workflowId","organizationId","serviceId","status","triggerKey","planVersion","triggeredBy","parentWorkflowRunId","cancelReason","completedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"organizationId":{"type":"string"},"serviceId":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["failed"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"triggerKey":{"type":"string"},"planVersion":{"type":"number"},"triggeredBy":{"nullable":true,"type":"string"},"parentWorkflowRunId":{"nullable":true,"type":"string"},"cancelReason":{"nullable":true,"type":"string"},"completedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/blueprints":{"get":{"operationId":"listBlueprints","security":[],"summary":"List published blueprints","description":"Returns the published blueprint catalog cards. No authentication required.","tags":["Blueprints"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BlueprintCatalog","type":"object","required":["blueprints"],"properties":{"blueprints":{"type":"array","items":{"title":"BlueprintCatalogCard","type":"object","required":["slug","name","shortDescription","icon","technologies","choices","inputs","needsAiGateway"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"shortDescription":{"nullable":true,"type":"string"},"icon":{"nullable":true,"type":"string"},"technologies":{"type":"array","items":{"type":"string"}},"choices":{"type":"array","items":{"title":"BlueprintChoice","type":"object","required":["id","label","options","default"],"properties":{"id":{"type":"string"},"label":{"type":"string"},"options":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}},"default":{"type":"string"}}}},"inputs":{"type":"array","items":{"title":"BlueprintInput","type":"object","required":["id","label"],"properties":{"id":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"placeholder":{"type":"string"},"default":{"type":"string"},"secret":{"type":"boolean"},"when":{"type":"object","required":["choice","is"],"properties":{"choice":{"type":"string"},"is":{"type":"string"}}}}}},"needsAiGateway":{"type":"boolean"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/blueprints/{slug}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBlueprint","security":[],"summary":"Get a published blueprint","description":"Returns the detail record of a published blueprint identified by `slug`. No authentication required.","tags":["Blueprints"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BlueprintDetail","type":"object","required":["blueprint"],"properties":{"blueprint":{"title":"Blueprint","type":"object","required":["id","slug","name","shortDescription","longDescription","icon","previewImage","notes","manifest","technologies","version","status","updatedAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"shortDescription":{"nullable":true,"type":"string"},"longDescription":{"nullable":true,"type":"string"},"icon":{"nullable":true,"type":"string"},"previewImage":{"nullable":true,"type":"string"},"notes":{"nullable":true,"type":"string"},"manifest":{"title":"BlueprintManifest","type":"object","required":["manifestSchemaVersion","slots"],"properties":{"manifestSchemaVersion":{"enum":[1],"type":"number"},"slots":{"type":"array","items":{"title":"BlueprintSlot","anyOf":[{"type":"object","required":["id","kind","template","port","env"],"properties":{"id":{"type":"string"},"kind":{"enum":["code"],"type":"string"},"template":{"type":"object","required":["owner","repo"],"properties":{"owner":{"type":"string"},"repo":{"type":"string"},"branch":{"type":"string"}}},"port":{"type":"number"},"dockerfileLocation":{"type":"string"},"useDockerfileDirAsContext":{"type":"boolean"},"healthEndpoint":{"type":"string"},"env":{"type":"array","items":{"title":"BlueprintEnvVar","type":"object","required":["key","source"],"properties":{"key":{"type":"string"},"stage":{"anyOf":[{"enum":["runtime"],"type":"string"},{"enum":["build"],"type":"string"}]},"source":{"anyOf":[{"type":"object","required":["type","value"],"properties":{"type":{"enum":["literal"],"type":"string"},"value":{"type":"string"}}},{"type":"object","required":["type","slot","output"],"properties":{"type":{"enum":["service"],"type":"string"},"slot":{"type":"string"},"output":{"type":"string"}}},{"type":"object","required":["type","kind"],"properties":{"type":{"enum":["generated"],"type":"string"},"kind":{"anyOf":[{"enum":["hex"],"type":"string"},{"enum":["base64"],"type":"string"},{"enum":["uuid"],"type":"string"},{"enum":["password"],"type":"string"}]},"length":{"type":"number"},"ref":{"type":"string"}}},{"type":"object","required":["type","input"],"properties":{"type":{"enum":["input"],"type":"string"},"input":{"type":"string"}}},{"type":"object","required":["type","output"],"properties":{"type":{"enum":["ai-gateway"],"type":"string"},"output":{"anyOf":[{"enum":["apiKey"],"type":"string"},{"enum":["baseUrl"],"type":"string"}]}}}]}}}},"resources":{"title":"BlueprintSlotResources","type":"object","required":["cpuMillis","memoryMib"],"properties":{"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"}}}}},{"type":"object","required":["id","kind","dbType"],"properties":{"id":{"type":"string"},"kind":{"enum":["database"],"type":"string"},"dbType":{"anyOf":[{"enum":["postgres"],"type":"string"},{"enum":["dragonfly"],"type":"string"}]},"resources":{"title":"BlueprintSlotResources","type":"object","required":["cpuMillis","memoryMib"],"properties":{"cpuMillis":{"type":"number"},"memoryMib":{"type":"number"}}}}},{"type":"object","required":["id","kind"],"properties":{"id":{"type":"string"},"kind":{"enum":["storage"],"type":"string"},"storage":{"type":"string"},"public":{"type":"boolean"}}}]}},"choices":{"type":"array","items":{"title":"BlueprintChoice","type":"object","required":["id","label","options","default"],"properties":{"id":{"type":"string"},"label":{"type":"string"},"options":{"type":"array","items":{"type":"object","required":["value","label"],"properties":{"value":{"type":"string"},"label":{"type":"string"}}}},"default":{"type":"string"}}}},"inputs":{"type":"array","items":{"title":"BlueprintInput","type":"object","required":["id","label"],"properties":{"id":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"placeholder":{"type":"string"},"default":{"type":"string"},"secret":{"type":"boolean"},"when":{"type":"object","required":["choice","is"],"properties":{"choice":{"type":"string"},"is":{"type":"string"}}}}}},"aiGateway":{"type":"object","required":["models"],"properties":{"models":{"type":"array","items":{"type":"string"}}}}}},"technologies":{"type":"array","items":{"type":"string"}},"version":{"type":"number"},"status":{"anyOf":[{"enum":["draft"],"type":"string"},{"enum":["published"],"type":"string"}]},"updatedAt":{"format":"date-time","type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/blueprints/{slug}/badge.svg":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBlueprintBadge","security":[],"summary":"Get a blueprint deploy badge","description":"Returns an SVG \"deploy on rock8cloud\" badge for a published blueprint identified by `slug`, for embedding in a README. No authentication required.","tags":["Blueprints"],"responses":{"200":{"description":"SVG badge image, cached for five minutes.","content":{"image/svg+xml":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/blueprints/{slug}/capacity":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getBlueprintCapacity","summary":"Preview pod capacity for a blueprint deploy","description":"Compares the resource needs of a published blueprint identified by `slug` against the organization pod pool budget and current usage, to warn upfront when a deploy will not all fit. Deploy still succeeds on overflow. Requires scope `read:blueprints`.","tags":["Blueprints"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BlueprintCapacity","type":"object","required":["needs","used","pool","fits"],"properties":{"needs":{"type":"object","required":["cpuMillis","memMib"],"properties":{"cpuMillis":{"type":"number"},"memMib":{"type":"number"}}},"used":{"type":"object","required":["cpuMillis","memMib"],"properties":{"cpuMillis":{"type":"number"},"memMib":{"type":"number"}}},"pool":{"type":"object","required":["cpuMillis","memMib"],"properties":{"cpuMillis":{"nullable":true,"type":"number"},"memMib":{"nullable":true,"type":"number"}}},"fits":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/blueprints/{slug}/check-names":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"checkBlueprintNames","summary":"Check blueprint repo name availability","description":"Checks whether the GitHub repo names a blueprint deploy would create under `githubOwner`, derived from `projectName`, are already taken. Requires scopes `read:blueprints` and `write:blueprints`.","tags":["Blueprints"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BlueprintNameCheck","type":"object","required":["plannedNames","checks","conflicts"],"properties":{"plannedNames":{"type":"array","items":{"type":"string"}},"checks":{"type":"array","items":{"type":"object","required":["name","exists"],"properties":{"name":{"type":"string"},"exists":{"type":"boolean"}}}},"conflicts":{"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"}}}}}}}},"/api/blueprints/{slug}/deploy":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"deployBlueprint","summary":"Deploy a blueprint","description":"Deploys a published blueprint identified by `slug` into a new project: creates the GitHub repos from its code slots and provisions its other slots. For a blueprint that needs an AI provider, `ai` picks the Rock8Router AI Gateway (a key is issued per service, which also requires `write:ai-gateway` and a verified e-mail) or the caller own key and URL. Returns 400 when `ai` picks the Rock8Router AI Gateway while it is not enabled on the instance, 502 with `partialState` when GitHub repo creation partially fails, leaving orphan repos to clean up. Requires scopes `read:blueprints` and `write:blueprints`.","tags":["Blueprints"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BlueprintDeployResult","type":"object","required":["projectId","services","notes"],"properties":{"projectId":{"type":"string"},"services":{"type":"array","items":{"type":"object","required":["slotId","serviceId","kind"],"properties":{"slotId":{"type":"string"},"serviceId":{"type":"string"},"kind":{"anyOf":[{"enum":["code"],"type":"string"},{"enum":["database"],"type":"string"},{"enum":["s3"],"type":"string"}]},"githubRepo":{"type":"string"},"storageConfig":{"type":"object","properties":{"storage":{"type":"string"},"public":{"type":"boolean"}}}}}},"notes":{"nullable":true,"type":"string"},"bootstrapFailures":{"type":"array","items":{"type":"object","required":["slotId","serviceId","kind","reason"],"properties":{"slotId":{"type":"string"},"serviceId":{"type":"string"},"kind":{"anyOf":[{"enum":["code"],"type":"string"},{"enum":["database"],"type":"string"},{"enum":["s3"],"type":"string"}]},"reason":{"type":"string"}}}},"aiGatewaySkippedModels":{"type":"array","items":{"type":"string"}},"partialState":{"type":"object","required":["createdRepos","error"],"properties":{"createdRepos":{"type":"array","items":{"type":"object","required":["owner","repo","htmlUrl"],"properties":{"owner":{"type":"string"},"repo":{"type":"string"},"htmlUrl":{"type":"string"}}}},"error":{"type":"string"}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"},"inputs":{"type":"object","additionalProperties":{"maxLength":4096,"type":"string"}},"choices":{"type":"object","additionalProperties":{"maxLength":64,"type":"string"}},"ai":{"anyOf":[{"type":"object","required":["provider","rock8routerOrganizationId","limitEurCents"],"properties":{"provider":{"enum":["rock8router"],"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}},{"type":"object","required":["provider","apiKey","baseUrl"],"properties":{"provider":{"enum":["own"],"type":"string"},"apiKey":{"maxLength":4096,"type":"string"},"baseUrl":{"maxLength":2048,"type":"string"}}}]}}}},"multipart/form-data":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"},"inputs":{"type":"object","additionalProperties":{"maxLength":4096,"type":"string"}},"choices":{"type":"object","additionalProperties":{"maxLength":64,"type":"string"}},"ai":{"anyOf":[{"type":"object","required":["provider","rock8routerOrganizationId","limitEurCents"],"properties":{"provider":{"enum":["rock8router"],"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}},{"type":"object","required":["provider","apiKey","baseUrl"],"properties":{"provider":{"enum":["own"],"type":"string"},"apiKey":{"maxLength":4096,"type":"string"},"baseUrl":{"maxLength":2048,"type":"string"}}}]}}}},"text/plain":{"schema":{"type":"object","required":["projectName","githubOwner"],"properties":{"projectName":{"minLength":1,"maxLength":50,"type":"string"},"githubOwner":{"minLength":1,"maxLength":100,"type":"string"},"inputs":{"type":"object","additionalProperties":{"maxLength":4096,"type":"string"}},"choices":{"type":"object","additionalProperties":{"maxLength":64,"type":"string"}},"ai":{"anyOf":[{"type":"object","required":["provider","rock8routerOrganizationId","limitEurCents"],"properties":{"provider":{"enum":["rock8router"],"type":"string"},"rock8routerOrganizationId":{"minLength":1,"type":"string"},"limitEurCents":{"nullable":true,"minimum":0,"anyOf":[{"format":"integer","default":0,"type":"string"},{"minimum":0,"type":"integer"}]}}},{"type":"object","required":["provider","apiKey","baseUrl"],"properties":{"provider":{"enum":["own"],"type":"string"},"apiKey":{"maxLength":4096,"type":"string"},"baseUrl":{"maxLength":2048,"type":"string"}}}]}}}}}}}},"/api/agents/active-runs-count":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"serviceId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentActiveRunsCount","summary":"Count active agent runs for a service","description":"Returns the number of currently active agent-session-run jobs for a service, used to gate starting a new run from the UI. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["count"],"properties":{"count":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/models":{"get":{"operationId":"listAgentModels","summary":"List selectable AI models for agents","description":"Returns the AI catalog offerings selectable for agent sessions and custom agents in the active organization, with a coarse price tier instead of raw rates. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["models","defaultOfferingId"],"properties":{"models":{"type":"array","items":{"title":"AgentModel","type":"object","required":["id","displayName","modelId","contextWindow","priceTier"],"properties":{"id":{"type":"string"},"displayName":{"type":"string"},"modelId":{"type":"string"},"contextWindow":{"nullable":true,"type":"number"},"priceTier":{"nullable":true,"anyOf":[{"enum":[1],"type":"number"},{"enum":[2],"type":"number"},{"enum":[3],"type":"number"}]}}}},"defaultOfferingId":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/agents/configurations":{"get":{"operationId":"listAgentConfigurations","summary":"List agent session configurations","description":"Returns the selectable session configurations and the tools each one grants the agent, for the new-session picker. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["configurations"],"properties":{"configurations":{"type":"array","items":{"title":"AgentConfiguration","type":"object","required":["id","label","tools"],"properties":{"id":{"anyOf":[{"enum":["analyze"],"type":"string"},{"enum":["code-autonomous"],"type":"string"},{"enum":["code-collab"],"type":"string"},{"enum":["dockerfile"],"type":"string"}]},"label":{"type":"string"},"tools":{"title":"AgentSessionToolset","type":"object","required":["workspace","platform"],"properties":{"workspace":{"type":"array","items":{"type":"object","required":["name","label","description"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}}}},"platform":{"type":"array","items":{"type":"object","required":["name","label","description"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}}}}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/agents/sessions":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAgentSession","summary":"Create an agent session","description":"Creates a lazy agent session anchored to a repo-backed service, provisioning a sandbox only once the first run is submitted. Legacy agent types `coder`, `research`, and `collab` are accepted and stored as canonical configuration ids. Platform-only agent types such as `dockerfile` are excluded. With `initialPrompt` it also enqueues that first run. Requires scopes `read:agents` and `write:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["sessionId","status"],"properties":{"sessionId":{"type":"string"},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"runId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agentType","serviceId"],"properties":{"agentType":{"type":"string"},"serviceId":{"type":"string"},"coderBranch":{"type":"string"},"baseBranch":{"type":"string"},"initialPrompt":{"type":"string"},"aiProviderModelId":{"format":"uuid","type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["agentType","serviceId"],"properties":{"agentType":{"type":"string"},"serviceId":{"type":"string"},"coderBranch":{"type":"string"},"baseBranch":{"type":"string"},"initialPrompt":{"type":"string"},"aiProviderModelId":{"format":"uuid","type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["agentType","serviceId"],"properties":{"agentType":{"type":"string"},"serviceId":{"type":"string"},"coderBranch":{"type":"string"},"baseBranch":{"type":"string"},"initialPrompt":{"type":"string"},"aiProviderModelId":{"format":"uuid","type":"string"}}}}}}},"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"serviceId","required":false},{"schema":{"type":"string"},"in":"query","name":"agentType","required":false},{"schema":{"type":"string"},"in":"query","name":"openOnly","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"offset","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAgentSessions","summary":"List agent sessions","description":"Lists agent sessions for the active organization, offset-paginated and optionally filtered by service, agent type, or open-only status. Agent-type filters match both canonical configuration ids and their legacy aliases. Returned agent types retain their stored names. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["sessions","limit","offset"],"properties":{"sessions":{"type":"array","items":{"title":"AgentSession","type":"object","required":["id","organizationId","projectId","serviceId","agentType","mode","status","repoUrl","baseBranch","coderBranch","baseCommitSha","latestCommitSha","pullRequestNumber","pullRequestUrl","pullRequestId","sandboxName","snapshotPrefix","podUrl","piSessionId","latestHandoff","pendingQuestion","parentSessionId","aiProviderModelId","aiExecutionConfigId","jobId","createdBy","errorMessage","createdAt","lastActivityAt","suspendedAt","closedAt","title"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"agentType":{"type":"string"},"mode":{"anyOf":[{"enum":["mutating"],"type":"string"},{"enum":["report"],"type":"string"}]},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"repoUrl":{"type":"string"},"baseBranch":{"type":"string"},"coderBranch":{"nullable":true,"type":"string"},"baseCommitSha":{"nullable":true,"type":"string"},"latestCommitSha":{"nullable":true,"type":"string"},"candidateCommitSha":{"nullable":true,"type":"string"},"gitState":{"anyOf":[{"enum":["synced"],"type":"string"},{"enum":["remote-advanced"],"type":"string"},{"enum":["rebase-in-progress"],"type":"string"},{"enum":["merge-in-progress"],"type":"string"}]},"gitBackend":{"anyOf":[{"enum":["legacy-pod"],"type":"string"},{"enum":["external-broker"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestUrl":{"nullable":true,"type":"string"},"pullRequestId":{"nullable":true,"type":"string"},"sandboxName":{"nullable":true,"type":"string"},"snapshotPrefix":{"nullable":true,"type":"string"},"podUrl":{"nullable":true,"type":"string"},"piSessionId":{"nullable":true,"type":"string"},"latestHandoff":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"initialHandoff":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"pendingQuestion":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"parentSessionId":{"nullable":true,"type":"string"},"successorSessionId":{"nullable":true,"type":"string"},"aiProviderModelId":{"nullable":true,"type":"string"},"aiExecutionConfigId":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"createdBy":{"type":"string"},"errorMessage":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"},"suspendedAt":{"nullable":true,"type":"string","format":"date-time"},"closedAt":{"nullable":true,"type":"string","format":"date-time"},"title":{"nullable":true,"type":"string"}}}},"limit":{"type":"number"},"offset":{"type":"number"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentSession","summary":"Get an agent session","description":"Returns one agent session identified by `id`, with its AI usage totals and resolved tool set. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AgentSessionDetail","type":"object","required":["id","organizationId","projectId","serviceId","agentType","mode","status","repoUrl","baseBranch","coderBranch","baseCommitSha","latestCommitSha","pullRequestNumber","pullRequestUrl","pullRequestId","sandboxName","snapshotPrefix","podUrl","piSessionId","latestHandoff","pendingQuestion","parentSessionId","aiProviderModelId","aiExecutionConfigId","jobId","createdBy","errorMessage","createdAt","lastActivityAt","suspendedAt","closedAt","title","usage","tools"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"nullable":true,"type":"string"},"serviceId":{"type":"string"},"agentType":{"type":"string"},"mode":{"anyOf":[{"enum":["mutating"],"type":"string"},{"enum":["report"],"type":"string"}]},"status":{"anyOf":[{"enum":["provisioning"],"type":"string"},{"enum":["active"],"type":"string"},{"enum":["suspended"],"type":"string"},{"enum":["closed"],"type":"string"},{"enum":["error"],"type":"string"}]},"repoUrl":{"type":"string"},"baseBranch":{"type":"string"},"coderBranch":{"nullable":true,"type":"string"},"baseCommitSha":{"nullable":true,"type":"string"},"latestCommitSha":{"nullable":true,"type":"string"},"candidateCommitSha":{"nullable":true,"type":"string"},"gitState":{"anyOf":[{"enum":["synced"],"type":"string"},{"enum":["remote-advanced"],"type":"string"},{"enum":["rebase-in-progress"],"type":"string"},{"enum":["merge-in-progress"],"type":"string"}]},"gitBackend":{"anyOf":[{"enum":["legacy-pod"],"type":"string"},{"enum":["external-broker"],"type":"string"}]},"pullRequestNumber":{"nullable":true,"type":"number"},"pullRequestUrl":{"nullable":true,"type":"string"},"pullRequestId":{"nullable":true,"type":"string"},"sandboxName":{"nullable":true,"type":"string"},"snapshotPrefix":{"nullable":true,"type":"string"},"podUrl":{"nullable":true,"type":"string"},"piSessionId":{"nullable":true,"type":"string"},"latestHandoff":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"initialHandoff":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"pendingQuestion":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"parentSessionId":{"nullable":true,"type":"string"},"successorSessionId":{"nullable":true,"type":"string"},"aiProviderModelId":{"nullable":true,"type":"string"},"aiExecutionConfigId":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"createdBy":{"type":"string"},"errorMessage":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"},"suspendedAt":{"nullable":true,"type":"string","format":"date-time"},"closedAt":{"nullable":true,"type":"string","format":"date-time"},"title":{"nullable":true,"type":"string"},"usage":{"title":"AgentSessionUsage","type":"object","required":["runs","inputTokens","outputTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","sandboxMs","spendMicroEur","vendorCostMicroUsd","markupMicroEur","totalTokens","models"],"properties":{"runs":{"type":"number"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"reasoningTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"sandboxMs":{"type":"number"},"spendMicroEur":{"type":"number"},"vendorCostMicroUsd":{"type":"number"},"markupMicroEur":{"type":"number"},"totalTokens":{"type":"number"},"models":{"type":"array","items":{"type":"string"}}}},"tools":{"title":"AgentSessionToolset","type":"object","required":["workspace","platform"],"properties":{"workspace":{"type":"array","items":{"type":"object","required":["name","label","description"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}}}},"platform":{"type":"array","items":{"type":"object","required":["name","label","description"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"closeAgentSession","summary":"Close an agent session","description":"Closes the agent session identified by `id`. The reconciler tears down its pod and volume on its next pass. Returns 409 with `code: UNPUBLISHED_WORK` when the session holds an unresolved git conflict or unpublished commit, unless `discardUnpublished` is set. Requires scopes `read:agents` and `write:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"discardUnpublished":{"type":"boolean"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"discardUnpublished":{"type":"boolean"}}}},"text/plain":{"schema":{"type":"object","properties":{"discardUnpublished":{"type":"boolean"}}}}}}}},"/api/agents/sessions/{id}/messages":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"anyOf":[{"format":"numeric","default":0,"type":"string"},{"type":"number"}]},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listAgentSessionMessages","summary":"List an agent session conversation","description":"Returns the user, assistant and system messages for an agent session identified by `id`, including handoff briefs and message authors. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","items":{"title":"AgentSessionMessage","type":"object","required":["id","sessionId","role","content","handoff","structuredOutput","filesChanged","metadata","commitSha","jobId","createdBy","createdAt","author"],"properties":{"id":{"type":"string"},"sessionId":{"type":"string"},"role":{"anyOf":[{"enum":["user"],"type":"string"},{"enum":["assistant"],"type":"string"},{"enum":["system"],"type":"string"}]},"content":{"type":"string"},"handoff":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"structuredOutput":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"filesChanged":{"nullable":true,"type":"array","items":{"type":"string"}},"metadata":{"nullable":true,"additionalProperties":true,"type":"object","properties":{}},"commitSha":{"nullable":true,"type":"string"},"jobId":{"nullable":true,"type":"string"},"createdBy":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time"},"author":{"nullable":true,"type":"object","required":["name","image"],"properties":{"name":{"type":"string"},"image":{"nullable":true,"type":"string"}}}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/runs":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createAgentRun","summary":"Submit a turn to an agent session","description":"Enqueues a serialized run for the agent session identified by `id` and returns the run id to poll. A closed session is replaced by a fresh successor that inherits its branch, PR and handoff. Requires scopes `read:agents` and `write:agents`. Returns 400 when AI is disabled or the configured model is unavailable.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["runId","sessionId","replacedClosedSession","message"],"properties":{"runId":{"type":"string"},"sessionId":{"type":"string"},"replacedClosedSession":{"type":"boolean"},"message":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userPrompt"],"properties":{"userPrompt":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","required":["userPrompt"],"properties":{"userPrompt":{"type":"string"}}}},"text/plain":{"schema":{"type":"object","required":["userPrompt"],"properties":{"userPrompt":{"type":"string"}}}}}}}},"/api/agents/sessions/{id}/continue":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"continueAgentSession","summary":"Continue a closed agent session","description":"Creates a fresh successor session for the closed agent session identified by `id`, inheriting its branch, pull request and handoff without enqueuing a run. Requires scopes `read:agents` and `write:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["sessionId"],"properties":{"sessionId":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}},"multipart/form-data":{"schema":{"type":"object","properties":{}}},"text/plain":{"schema":{"type":"object","properties":{}}}}}}},"/api/agents/sessions/{id}/runs/{runId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"runId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentRun","summary":"Poll an agent run","description":"Returns the status, result and error of an agent run identified by `runId` within session `id`. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"AgentRun","type":"object","required":["runId","status","result","error"],"properties":{"runId":{"type":"string"},"status":{"anyOf":[{"enum":["waiting"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["successful"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"result":{"description":"Turn result payload, null until the run has finished. Its shape is not part of the stable API."},"error":{"nullable":true,"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/events":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"streamAgentSessionEvents","summary":"Stream live events for an agent session","description":"Server-sent event stream that proxies the in-pod event feed for the agent session identified by `id` while its pod is up, otherwise sends a comment that the session is not active. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"Server-sent event stream.","content":{"text/event-stream":{"schema":{"type":"string"}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/files":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"query","name":"q","required":false},{"schema":{"type":"string"},"in":"query","name":"limit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"searchAgentSessionFiles","summary":"Fuzzy search files in a session workspace","description":"Searches file paths in the sandbox workspace of the agent session identified by `id`, for composer @-mentions. Returns an empty list whenever the pod is unreachable. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["files"],"properties":{"files":{"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/diff":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"query","name":"commit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentSessionDiff","summary":"Get changed files for an agent session","description":"Returns the changed files in the sandbox workspace of the agent session identified by `id`: cumulative by default, or scoped to one turn commit with `commit`. Reports unavailable whenever the pod is gone. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["available","files"],"properties":{"available":{"type":"boolean"},"files":{"type":"array","items":{"type":"object","required":["path","change"],"properties":{"path":{"type":"string"},"change":{"anyOf":[{"enum":["added"],"type":"string"},{"enum":["modified"],"type":"string"},{"enum":["deleted"],"type":"string"},{"enum":["renamed"],"type":"string"}]},"previousPath":{"type":"string"}}}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/diff/file":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"query","name":"path","required":true},{"schema":{"type":"string"},"in":"query","name":"commit","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"getAgentSessionDiffFile","summary":"Get a single file patch for an agent session","description":"Returns the patch for one file at `path` in the sandbox workspace of the agent session identified by `id`, fetched on demand as the diff sheet selects files. Requires scope `read:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"patch":{"type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/agents/sessions/{id}/cancel":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"cancelAgentRun","summary":"Cancel the in-flight turn on an agent session","description":"Stops the turn currently executing on the pod for the agent session identified by `id`. The pod stays alive and the session accepts new messages. Queued runs are untouched. Requires scopes `read:agents` and `write:agents`.","tags":["Agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["cancelled"],"properties":{"cancelled":{"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/api-keys/":{"get":{"operationId":"listApiKeys","summary":"List API keys","description":"Lists the API keys of the active organization. Members without `canManageAllApiKeys` see only their own keys. Requires scope `read:organization`.","tags":["API keys"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"ApiKey","type":"object","required":["id","userId","name","hint","scopes","allowedScopes","lastUsedAt","createdAt"],"properties":{"id":{"type":"string"},"userId":{"nullable":true,"type":"string"},"name":{"type":"string"},"hint":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]},"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createApiKey","summary":"Create an API key","description":"Creates a scoped API key for the active organization, bounded by the caller's credential ceiling. Requires scopes `read:organization` and `write:organization` and the `canCreateApiKeys` role capability.","tags":["API keys"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CreatedApiKey","type":"object","required":["id","name","scopes","token"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"token":{"description":"Plaintext API key. Shown once, only its hash is stored.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"minLength":1,"type":"string"},"scopes":{"minItems":1,"type":"array","items":{"type":"string"}}}}},"multipart/form-data":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"minLength":1,"type":"string"},"scopes":{"minItems":1,"type":"array","items":{"type":"string"}}}}},"text/plain":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"minLength":1,"type":"string"},"scopes":{"minItems":1,"type":"array","items":{"type":"string"}}}}}}}}},"/api/api-keys/{id}":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"updateApiKey","summary":"Update an API key","description":"Renames an API key or changes its scopes, bounded by the key owner's credential ceiling. Requires scopes `read:organization` and `write:organization` and permission to manage the target key.","tags":["API keys"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"UpdatedApiKey","type":"object","required":["id","name","scopes"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"minLength":1,"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"minLength":1,"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}},"text/plain":{"schema":{"type":"object","properties":{"name":{"minLength":1,"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}}}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Revokes an API key belonging to the active organization. Requires scopes `read:organization` and `write:organization` and permission to manage the target key.","tags":["API keys"],"responses":{"204":{"description":"API key revoked. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/api-keys/oauth-clients":{"get":{"operationId":"listOAuthClientConsents","summary":"List OAuth client consents","description":"Lists the OAuth clients (e.g. MCP servers) the current user has authorized. Requires scope `read:organization`.","tags":["API keys"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"title":"OAuthClientConsent","type":"object","required":["consentId","clientId","scopes","consentCreatedAt","clientName","clientUri"],"properties":{"consentId":{"type":"string"},"clientId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"consentCreatedAt":{"type":"string","format":"date-time"},"clientName":{"nullable":true,"type":"string"},"clientUri":{"nullable":true,"type":"string"}}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}},"/api/api-keys/oauth-clients/{consentId}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"consentId","required":true},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"revokeOAuthClientConsent","summary":"Revoke an OAuth client consent","description":"Revokes a previously granted OAuth consent for the current user, invalidating tokens issued to that client. Requires scopes `read:organization` and `write:organization`.","tags":["API keys"],"responses":{"204":{"description":"Consent revoked. Empty body.","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/mcp":{"post":{"operationId":"postMcp","summary":"MCP Streamable HTTP endpoint","description":"Handles MCP JSON-RPC 2.0 requests over Streamable HTTP. Requires an OAuth 2.0 bearer token. An unauthenticated request gets a 401 with an RFC 9728 WWW-Authenticate challenge. Stateless - no session IDs.","tags":["MCP"],"security":[{"oauth2":[]}],"responses":{"200":{"description":"JSON-RPC 2.0 response.","content":{"application/json":{"schema":{"title":"McpJsonRpcResponse","type":"object","required":["jsonrpc"],"properties":{"jsonrpc":{"description":"Always `2.0`.","type":"string"},"id":{"anyOf":[{"type":"string"},{"type":"number"}]},"result":{"additionalProperties":true,"type":"object","properties":{}},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"number"},"message":{"type":"string"},"data":{}}}}}}}},"202":{"description":"JSON-RPC notification accepted. Empty body."}}},"get":{"operationId":"getMcpNotAllowed","summary":"MCP endpoint does not support GET","description":"Always returns 405 without authentication. This stateless deployment has no SSE stream to resume, so GET is not supported.","tags":["MCP"],"security":[],"responses":{"405":{"description":"Method not allowed. Only POST is supported (see the `Allow` header).","content":{"application/json":{"schema":{"title":"McpMethodNotAllowed","type":"object","required":["error","code","hint"],"properties":{"error":{"type":"string"},"code":{"type":"string"},"hint":{"type":"string"}}}}}}}},"delete":{"operationId":"deleteMcpNotAllowed","summary":"MCP endpoint does not support DELETE","description":"Always returns 405 without authentication. This stateless deployment has no session to terminate, so DELETE is not supported.","tags":["MCP"],"security":[],"responses":{"405":{"description":"Method not allowed. Only POST is supported (see the `Allow` header).","content":{"application/json":{"schema":{"title":"McpMethodNotAllowed","type":"object","required":["error","code","hint"],"properties":{"error":{"type":"string"},"code":{"type":"string"},"hint":{"type":"string"}}}}}}}}},"/api/code-review/by-branch":{"get":{"parameters":[{"schema":{"type":"string","minLength":1},"in":"query","name":"branch","required":true},{"schema":{"type":"string","minLength":1},"in":"query","name":"repoUrl","required":false},{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"listCodeReviewsByBranch","summary":"List code reviews for a branch","description":"Returns the latest completed AI code review, in-progress status and total review count for every preview environment matching `branch` in the active organization, optionally scoped to a `repoUrl`. Requires scope `read:code-reviews`.","tags":["Code review"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"CodeReviewsByBranch","type":"object","required":["results","repoHostedInOrg"],"properties":{"results":{"type":"array","items":{"title":"BranchCodeReviewResult","type":"object","required":["organizationId","service","environment","codeReview","hasInProgressReview","totalReviewCount"],"properties":{"organizationId":{"type":"string"},"service":{"type":"object","required":["id","name","projectId"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"}}},"environment":{"type":"object","required":["id","branch","pullRequestNumber"],"properties":{"id":{"type":"string"},"branch":{"nullable":true,"type":"string"},"pullRequestNumber":{"nullable":true,"type":"number"}}},"codeReview":{"nullable":true,"title":"BranchCodeReview","type":"object","required":["id","status","commitSha","summary","criticalCount","warningCount","suggestionCount","filesAnalyzed","findings","hasVisualDoc","completedAt"],"properties":{"id":{"type":"string"},"status":{"anyOf":[{"enum":["pending"],"type":"string"},{"enum":["running"],"type":"string"},{"enum":["completed"],"type":"string"},{"enum":["error"],"type":"string"},{"enum":["cancelled"],"type":"string"}]},"commitSha":{"type":"string"},"summary":{"nullable":true,"type":"string"},"criticalCount":{"type":"number"},"warningCount":{"type":"number"},"suggestionCount":{"type":"number"},"filesAnalyzed":{"nullable":true,"type":"number"},"findings":{"type":"array","items":{"title":"CodeReviewFinding","type":"object","required":["id","severity","category","bestPractice","title","description"],"properties":{"id":{"type":"string"},"severity":{"anyOf":[{"enum":["critical"],"type":"string"},{"enum":["warning"],"type":"string"},{"enum":["suggestion"],"type":"string"}]},"category":{"type":"string"},"bestPractice":{"type":"string"},"file":{"type":"string"},"line":{"type":"number"},"title":{"type":"string"},"description":{"type":"string"},"suggestion":{"type":"string"},"fixPrompt":{"type":"string"}}}},"hasVisualDoc":{"type":"boolean"},"completedAt":{"nullable":true,"type":"string","format":"date-time"}}},"hasInProgressReview":{"type":"boolean"},"totalReviewCount":{"type":"number"}}}},"repoHostedInOrg":{"nullable":true,"type":"boolean"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/bug-reports":{"post":{"parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"operationId":"createBugReport","summary":"File a bug report or idea","description":"Forwards a bug report or idea, with its screenshot and debug data, to the configured bug tracker and files a ticket labeled for the bug bounty leaderboard. Requires a signed-in session via authPlugin with an email address, since an anonymous reporter cannot be scored or answered. Returns 400 if the caller has no email and 502 if the tracker rejects the report, or logs the report and returns ok with no ticket id if bug tracking is not configured.","tags":["Bug reports"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"title":"BugReportResult","type":"object","required":["ok","ticketId"],"properties":{"ok":{"enum":[true],"type":"boolean"},"ticketId":{"nullable":true,"description":"Null when bug tracking is not configured.","type":"string"}}}}},"headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["description","metadata"],"properties":{"description":{"minLength":1,"maxLength":10000,"type":"string"},"kind":{"anyOf":[{"enum":["bug"],"type":"string"},{"enum":["idea"],"type":"string"}]},"sentryEventId":{"maxLength":64,"type":"string"},"metadata":{"type":"object","required":["url","route","userAgent","viewport","release","environment","reportedAt","activeOrg","replayUrl"],"properties":{"url":{"type":"string"},"route":{"nullable":true,"type":"string"},"userAgent":{"type":"string"},"viewport":{"type":"object","required":["width","height"],"properties":{"width":{"type":"number"},"height":{"type":"number"}}},"release":{"nullable":true,"type":"string"},"environment":{"type":"string"},"reportedAt":{"type":"string"},"activeOrg":{"nullable":true,"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}}},"replayUrl":{"nullable":true,"type":"string"}}},"optOutOfLeaderboard":{"anyOf":[{"type":"boolean"},{"format":"boolean","default":false,"type":"string"}]},"debugData":{"default":"File","maxSize":"10m","type":"string","format":"binary"},"screenshot":{"default":"File","maxSize":"5m","type":"string","extension":"image/*","format":"binary"}}}},"multipart/form-data":{"schema":{"type":"object","required":["description","metadata"],"properties":{"description":{"minLength":1,"maxLength":10000,"type":"string"},"kind":{"anyOf":[{"enum":["bug"],"type":"string"},{"enum":["idea"],"type":"string"}]},"sentryEventId":{"maxLength":64,"type":"string"},"metadata":{"type":"object","required":["url","route","userAgent","viewport","release","environment","reportedAt","activeOrg","replayUrl"],"properties":{"url":{"type":"string"},"route":{"nullable":true,"type":"string"},"userAgent":{"type":"string"},"viewport":{"type":"object","required":["width","height"],"properties":{"width":{"type":"number"},"height":{"type":"number"}}},"release":{"nullable":true,"type":"string"},"environment":{"type":"string"},"reportedAt":{"type":"string"},"activeOrg":{"nullable":true,"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}}},"replayUrl":{"nullable":true,"type":"string"}}},"optOutOfLeaderboard":{"anyOf":[{"type":"boolean"},{"format":"boolean","default":false,"type":"string"}]},"debugData":{"default":"File","maxSize":"10m","type":"string","format":"binary"},"screenshot":{"default":"File","maxSize":"5m","type":"string","extension":"image/*","format":"binary"}}}},"text/plain":{"schema":{"type":"object","required":["description","metadata"],"properties":{"description":{"minLength":1,"maxLength":10000,"type":"string"},"kind":{"anyOf":[{"enum":["bug"],"type":"string"},{"enum":["idea"],"type":"string"}]},"sentryEventId":{"maxLength":64,"type":"string"},"metadata":{"type":"object","required":["url","route","userAgent","viewport","release","environment","reportedAt","activeOrg","replayUrl"],"properties":{"url":{"type":"string"},"route":{"nullable":true,"type":"string"},"userAgent":{"type":"string"},"viewport":{"type":"object","required":["width","height"],"properties":{"width":{"type":"number"},"height":{"type":"number"}}},"release":{"nullable":true,"type":"string"},"environment":{"type":"string"},"reportedAt":{"type":"string"},"activeOrg":{"nullable":true,"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}}},"replayUrl":{"nullable":true,"type":"string"}}},"optOutOfLeaderboard":{"anyOf":[{"type":"boolean"},{"format":"boolean","default":false,"type":"string"}]},"debugData":{"default":"File","maxSize":"10m","type":"string","format":"binary"},"screenshot":{"default":"File","maxSize":"5m","type":"string","extension":"image/*","format":"binary"}}}}}}}},"/api/bug-bounty/leaderboard":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","required":["email","displayName","avatarUrl","points","bugs","titles"],"properties":{"email":{"type":"string"},"displayName":{"nullable":true,"type":"string"},"avatarUrl":{"nullable":true,"type":"string"},"points":{"type":"number"},"bugs":{"type":"object","required":["urgent","high","normal","duplicate"],"properties":{"urgent":{"type":"number"},"high":{"type":"number"},"normal":{"type":"number"},"duplicate":{"type":"number"}}},"titles":{"type":"array","items":{"type":"object","required":["title","bucket","status","resolution","publicComment","wontDo"],"properties":{"title":{"type":"string"},"bucket":{"anyOf":[{"enum":["urgent"],"type":"string"},{"enum":["high"],"type":"string"},{"enum":["normal"],"type":"string"},{"enum":["duplicate"],"type":"string"}]},"status":{"nullable":true,"type":"string"},"resolution":{"anyOf":[{"enum":["open"],"type":"string"},{"enum":["fixed"],"type":"string"},{"enum":["duplicate"],"type":"string"},{"enum":["not_a_bug"],"type":"string"},{"enum":["wont_do"],"type":"string"},{"enum":["backlog"],"type":"string"}]},"publicComment":{"nullable":true,"type":"string"},"wontDo":{"type":"boolean"}}}}}}},"refreshedAt":{"type":"string"},"seasonEndsAt":{"nullable":true,"type":"string"},"environment":{"type":"string"},"serverVersion":{"nullable":true,"type":"string"},"prizes":{"type":"array","items":{"type":"object","required":["rankFrom","rankTo","label"],"properties":{"rankFrom":{"type":"number"},"rankTo":{"type":"number"},"label":{"type":"string"}}}}},"required":["entries","refreshedAt","seasonEndsAt","environment","serverVersion","prizes"]}},"multipart/form-data":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","required":["email","displayName","avatarUrl","points","bugs","titles"],"properties":{"email":{"type":"string"},"displayName":{"nullable":true,"type":"string"},"avatarUrl":{"nullable":true,"type":"string"},"points":{"type":"number"},"bugs":{"type":"object","required":["urgent","high","normal","duplicate"],"properties":{"urgent":{"type":"number"},"high":{"type":"number"},"normal":{"type":"number"},"duplicate":{"type":"number"}}},"titles":{"type":"array","items":{"type":"object","required":["title","bucket","status","resolution","publicComment","wontDo"],"properties":{"title":{"type":"string"},"bucket":{"anyOf":[{"enum":["urgent"],"type":"string"},{"enum":["high"],"type":"string"},{"enum":["normal"],"type":"string"},{"enum":["duplicate"],"type":"string"}]},"status":{"nullable":true,"type":"string"},"resolution":{"anyOf":[{"enum":["open"],"type":"string"},{"enum":["fixed"],"type":"string"},{"enum":["duplicate"],"type":"string"},{"enum":["not_a_bug"],"type":"string"},{"enum":["wont_do"],"type":"string"},{"enum":["backlog"],"type":"string"}]},"publicComment":{"nullable":true,"type":"string"},"wontDo":{"type":"boolean"}}}}}}},"refreshedAt":{"type":"string"},"seasonEndsAt":{"nullable":true,"type":"string"},"environment":{"type":"string"},"serverVersion":{"nullable":true,"type":"string"},"prizes":{"type":"array","items":{"type":"object","required":["rankFrom","rankTo","label"],"properties":{"rankFrom":{"type":"number"},"rankTo":{"type":"number"},"label":{"type":"string"}}}}},"required":["entries","refreshedAt","seasonEndsAt","environment","serverVersion","prizes"]}},"text/plain":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","required":["email","displayName","avatarUrl","points","bugs","titles"],"properties":{"email":{"type":"string"},"displayName":{"nullable":true,"type":"string"},"avatarUrl":{"nullable":true,"type":"string"},"points":{"type":"number"},"bugs":{"type":"object","required":["urgent","high","normal","duplicate"],"properties":{"urgent":{"type":"number"},"high":{"type":"number"},"normal":{"type":"number"},"duplicate":{"type":"number"}}},"titles":{"type":"array","items":{"type":"object","required":["title","bucket","status","resolution","publicComment","wontDo"],"properties":{"title":{"type":"string"},"bucket":{"anyOf":[{"enum":["urgent"],"type":"string"},{"enum":["high"],"type":"string"},{"enum":["normal"],"type":"string"},{"enum":["duplicate"],"type":"string"}]},"status":{"nullable":true,"type":"string"},"resolution":{"anyOf":[{"enum":["open"],"type":"string"},{"enum":["fixed"],"type":"string"},{"enum":["duplicate"],"type":"string"},{"enum":["not_a_bug"],"type":"string"},{"enum":["wont_do"],"type":"string"},{"enum":["backlog"],"type":"string"}]},"publicComment":{"nullable":true,"type":"string"},"wontDo":{"type":"boolean"}}}}}}},"refreshedAt":{"type":"string"},"seasonEndsAt":{"nullable":true,"type":"string"},"environment":{"type":"string"},"serverVersion":{"nullable":true,"type":"string"},"prizes":{"type":"array","items":{"type":"object","required":["rankFrom","rankTo","label"],"properties":{"rankFrom":{"type":"number"},"rankTo":{"type":"number"},"label":{"type":"string"}}}}},"required":["entries","refreshedAt","seasonEndsAt","environment","serverVersion","prizes"]}}},"description":"OK","headers":{"Rock8cloud-Version":{"$ref":"#/components/headers/ApiVersion"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"}},"operationId":"getBugBountyLeaderboard","summary":"Get the bug bounty leaderboard","description":"Returns the current bug bounty leaderboard: point totals and ticket titles aggregated by reporter email, read through a short Redis cache. Requires a signed-in session via authPlugin. Serves a cached or empty payload rather than failing if the bug tracker cannot be reached.","tags":["Bug reports"],"parameters":[{"$ref":"#/components/parameters/ApiVersion"}]}}}}