{"openapi":"3.1.0","info":{"title":"Eurobase API","version":"0.2.0","description":"Eurobase deployment control-plane API."},"servers":[{"url":"https://api.eurobase.dev"}],"paths":{"/health":{"get":{"summary":"Health check","responses":{"200":{"description":"API ready"},"503":{"description":"Hosted platform readiness is incomplete"}}}},"/internal/maintenance/readiness":{"get":{"summary":"Internal interactive database readiness","description":"Authenticates the maintenance caller, then checks out a DB client and runs SELECT 1 within the configured server-side deadline.","x-internal":true,"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Interactive database path is ready"},"401":{"description":"Internal maintenance authentication failed"},"503":{"description":"Interactive database path is saturated or unavailable"}}}},"/openapi.json":{"get":{"summary":"OpenAPI spec","responses":{"200":{"description":"Spec JSON"}}}},"/platform/info":{"get":{"summary":"Platform mode and readiness","description":"Public readiness booleans only; readiness warnings are not exposed.","responses":{"200":{"description":"Platform info"}}}},"/auth/register":{"post":{"summary":"Register local owner account","description":"Admits only normalized permanent email addresses with a usable mail domain before creating an identity. Known permanent providers skip DNS; custom domains need MX or the RFC 5321 implicit A/AAAA route. Creates a PostgreSQL-clocked 35-day browser session and returns the authenticated identity. Browser session state is established by Set-Cookie, not a JSON bearer token.","parameters":[{"in":"header","name":"idempotency-key","required":false,"schema":{"type":"string"},"description":"One logical action; retain through transport retries and challenge resubmission. Different guesses cannot reuse its receipt."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthCredentialsRequest"}}}},"responses":{"201":{"description":"Registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Malformed, temporary or unroutable email, or a password outside the policy (16 to 64 characters after NFKC normalization)","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InvalidEmailError"},{"$ref":"#/components/schemas/EmailDomainRejectedError"},{"$ref":"#/components/schemas/PasswordPolicyError"}]}}}},"409":{"description":"Signup admission changed across the UTC window; explicit retry required (auth-signup-admission-changed)"},"429":{"description":"Auth step-up (ADR 0088): past the per-client signup threshold a password signup must carry a solved challenge (auth-challenge-required); retain idempotency-key and resubmit the same body with authChallenge. Past the signup ceiling it is refused (rate-limit-exceeded, scope auth.step_up, with a Retry-After header); retained per-email delivery limits apply separately","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthStepUpError"}}}},"503":{"description":"Password hashing capacity is busy, for everyone or for this client address (Retry-After: 2), or email-domain DNS verification is temporarily unavailable, or the client address could not be proven: in hosted mode password signup is accepted only through the Web (ADR 0086); retry without losing entered input","headers":{"Retry-After":{"schema":{"type":"integer","enum":[2]},"description":"Seconds before retry when password hashing or email-domain verification is busy"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PasswordHashingBusyError"},{"$ref":"#/components/schemas/EmailDomainUnavailableError"},{"$ref":"#/components/schemas/ClientIpUnavailableError"}]}}}}}}},"/auth/login":{"post":{"summary":"Login local owner account","description":"Creates a PostgreSQL-clocked 35-day browser session and returns the authenticated identity. Browser session state is established by Set-Cookie, not a JSON bearer token.","parameters":[{"in":"header","name":"idempotency-key","required":false,"schema":{"type":"string"},"description":"One logical action; retain through transport retries and challenge resubmission. Different guesses cannot reuse its receipt."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthCredentialsRequest"}}}},"responses":{"200":{"description":"Logged in","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Malformed email rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidEmailError"}}}},"409":{"description":"The account still holds a retired pre-v2 password hash (ADR 0092). The password is not verified; the API has emailed a password reset link under the per-email reset limit, and no session is created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequiredError"}}}},"429":{"description":"Auth step-up (ADR 0088, amended 2026-10-18): when the client or the account from this client is past its failed-attempt threshold, every login, correct password or not, must carry a solved challenge before the password is checked (auth-challenge-required); past the ceiling the challenge is the hardest one and a login is never refused. Retain idempotency-key and resubmit the same body with authChallenge","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthStepUpError"}}}},"503":{"description":"Password hashing capacity is busy, for everyone or for this client address (Retry-After: 2), or the client address could not be proven: in hosted mode password login is accepted only through the Web (ADR 0086); retry without losing entered input","headers":{"Retry-After":{"schema":{"type":"integer","enum":[2]},"description":"Seconds before retry when password hashing capacity is busy"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PasswordHashingBusyError"},{"$ref":"#/components/schemas/ClientIpUnavailableError"}]}}}}}}},"/auth/email-verification/resend":{"post":{"summary":"Resend mailbox verification email for the current session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthChallengeRequest"}}}},"responses":{"200":{"description":"Verification email sent or account already verified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"403":{"description":"Account status blocks resend"},"429":{"description":"Persistent per-email verification delivery limit exceeded; no password-failure step-up applies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthStepUpError"}}}},"503":{"description":"Email sender not configured, or the client address could not be proven (ADR 0086)","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}}},{"$ref":"#/components/schemas/ClientIpUnavailableError"}]}}}}}}},"/auth/email-verification/confirm":{"post":{"summary":"Complete mailbox verification with registration authority or mailbox takeover","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["token"],"properties":{"token":{"type":"string"},"action":{"const":"session"}},"additionalProperties":false},{"type":"object","required":["token","action","email","password"],"properties":{"token":{"type":"string"},"action":{"const":"login"},"email":{"type":"string"},"password":{"type":"string"},"authChallenge":{"$ref":"#/components/schemas/AuthChallengeSolution"}},"additionalProperties":false},{"type":"object","required":["token","action","password"],"properties":{"token":{"type":"string"},"action":{"const":"takeover"},"password":{"type":"string","description":"Existing 16–64-character NFKC password policy"}},"additionalProperties":false}]}}}},"responses":{"200":{"description":"Verified, or login_required without consumption. Login/takeover sets the browser session cookie; no identity or raw token is returned.","headers":{"Set-Cookie":{"description":"Host-only browser session and CSRF cookies after login or takeover","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailVerificationConfirmationResponse"}}}},"400":{"description":"Unusable verification token, invalid action/email or password policy violation"},"401":{"description":"Invalid login credentials"},"429":{"description":"Persistent confirmation limit or canonical failed-password step-up: retry the same login action with authChallenge when required; correct passwords never enter step-up."},"503":{"description":"Verification or bounded password hashing unavailable; no successful change is reported"}}}},"/auth/password-reset/request":{"post":{"summary":"Request a one-time password reset link","description":"Every well-formed address gets the same 202 answer; the link, valid 30 minutes, is emailed after the response and only to an active account (ADR 0085).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}}},"responses":{"202":{"description":"Accepted, whether or not the address has an account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequestResponse"}}}},"400":{"description":"Malformed email rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidEmailError"}}}},"429":{"description":"Persistent per-email request limit exceeded (same answer for every address); no password-failure step-up applies","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PasswordResetRateLimitError"}]}}}},"503":{"description":"Password reset email sender not configured (same answer for every address), or the client address could not be proven (ADR 0086)","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PasswordResetUnavailableError"},{"$ref":"#/components/schemas/ClientIpUnavailableError"}]}}}}}}},"/auth/password-reset/confirm":{"post":{"summary":"Set a new password from a reset link","description":"Replaces the password, marks the email verified, and revokes every session, linked provider identity, unused provider login handoff and CLI credential of the account. Does not sign in.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmation"}}}},"responses":{"200":{"description":"Password replaced","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmationResponse"}}}},"400":{"description":"The link cannot be used, or the new password is outside the policy","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PasswordResetLinkError"},{"$ref":"#/components/schemas/PasswordPolicyError"}]}}}},"429":{"description":"Persistent per-link confirmation limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRateLimitError"}}}},"503":{"description":"Password hashing capacity is busy; retry without losing entered input","headers":{"Retry-After":{"schema":{"type":"integer","enum":[2]},"description":"Seconds before retry"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordHashingBusyError"}}}}}}},"/auth/google/start":{"get":{"summary":"Issue a single-use Google nonce bound to this browser","description":"Sets or refreshes __Host-eurobase_login_binding. Send the returned nonce to Google Identity Services and to /auth/google/verify.","parameters":[{"in":"query","name":"returnTo","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Google nonce issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleNonceResponse"}}}},"409":{"description":"Google client configuration is missing"}}}},"/auth/google/verify":{"post":{"summary":"Verify Google identity and create a one-time auth handoff","description":"Provider-verified emails on new identities must be syntactically valid and permanent; no DNS check. Existing linked identities keep working. New accounts count toward the shared per-client UTC signup ceiling; provider flows are never challenged. Requires the server-issued nonce from /auth/google/start and its browser binding cookie; always verifies the signed token nonce and consumes the issued nonce once. Only that browser can exchange the handoff; verify never issues a binding cookie.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleVerifyRequest"}}}},"responses":{"200":{"description":"Provider handoff created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthProviderHandoffResponse"}}}},"400":{"description":"New identity email is malformed or disposable","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InvalidEmailError"},{"$ref":"#/components/schemas/EmailDomainRejectedError"}]}}}},"401":{"description":"Nonce missing, expired, replayed or mismatched, or browser binding mismatch"},"429":{"description":"Per-client UTC signup ceiling reached; existing provider accounts still sign in","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}},"503":{"description":"The client address could not be proven (ADR 0086); a counted auth request is never admitted uncounted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientIpUnavailableError"}}}}}}},"/auth/github/start":{"get":{"summary":"Redirect to GitHub login OAuth","description":"S256 PKCE binds the authorization code to the encrypted per-state verifier. The login state is bound to this browser: the redirect sets __Host-eurobase_login_binding (reusing a value the browser already holds), and the callback accepts the state only from that browser.","parameters":[{"in":"query","name":"returnTo","required":false,"schema":{"type":"string"},"description":"Sanitized relative /app/* route to restore after auth."}],"responses":{"302":{"description":"Redirect to GitHub OAuth, or to /auth/callback with status=error and reason github-operator-config-required or client-ip-unavailable"}}}},"/auth/github/callback":{"get":{"summary":"Complete GitHub login OAuth and redirect to /auth/callback","responses":{"302":{"description":"Redirect to auth callback handoff or error state (auth-provider-browser-mismatch when the browser did not start this login; email-domain-disposable or invalid-email for a refused new identity). Existing linked identities keep working."}}}},"/auth/provider-handoffs/exchange":{"post":{"summary":"Consume a one-time auth handoff and mint a Eurobase session","description":"Creates or links a PostgreSQL-clocked 35-day browser session and returns the authenticated identity. Browser session state is established by Set-Cookie, not a JSON bearer token. A login handoff is accepted only with the __Host-eurobase_login_binding cookie of the browser that started the login.","responses":{"200":{"description":"Eurobase session minted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthProviderExchangeResponse"}}}},"400":{"description":"New linked identity email is malformed, disposable or unroutable (unverified provider mail requires DNS)","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InvalidEmailError"},{"$ref":"#/components/schemas/EmailDomainRejectedError"}]}}}},"401":{"description":"Handoff invalid, expired or reused (auth-provider-handoff-invalid), login started in another browser (auth-provider-browser-mismatch), or link finished outside its initiating session (auth-provider-handoff-session-mismatch); no cookie is set"},"415":{"description":"Request body is not application/json"},"503":{"description":"Unverified new linked email DNS is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDomainUnavailableError"}}}}}}},"/auth/logout":{"post":{"summary":"Logout current session","responses":{"200":{"description":"Logged out"}}}},"/auth/account":{"delete":{"summary":"Cancel billing and request account deletion after explicit email confirmation","description":"Shared projects owned or billed by this user must first be transferred to another member or explicitly deleted. Stripe subscriptions cancel immediately without refund; only accrued usage can be invoiced. Identity and projects remain until cancellation is confirmed. The existing pending-delete reconciler retries interrupted billing cancellation.","responses":{"202":{"description":"Billing cancellation confirmed; sessions revoked and account cleanup accepted"},"409":{"description":"account-delete-shared-projects: transfer ownership and billing or delete the listed projects"},"503":{"description":"account-delete-billing-pending: account preserved while Stripe cancellation retries; user may retry the same request"}}}},"/auth/session":{"get":{"summary":"Get current session identity","description":"Returns the authenticated user, session capabilities, and normalized clientIp only. Active PostgreSQL sessions renew when 30 days or less remain, to 35 days, at most once per five days. Only the successful cookie-authenticated response that renewed the session reissues the same session cookie and already-present CSRF cookie with the renewed PostgreSQL expiry, without rotating either value; a request carrying `x-eurobase-session-renewal: defer` never renews. Bearer callers and failed responses receive no browser cookies. Infrastructure, database, network, or process failures are request failures only; they are not logout semantics and do not clear browser auth cookies.","responses":{"200":{"description":"Session user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}}}}},"/auth/bootstrap":{"get":{"summary":"Get authenticated shell bootstrap data","description":"Returns cached workspace and notification data plus the current tenant-scoped GitHub account and installation summary from DB. It reissues the same session and already-present CSRF cookies only when this response renewed the session. The GitHub summary is read-only, uses no provider request, and does not repair or rewrite the user shell row. Read failures are request failures only; they are not logout semantics and do not clear browser auth cookies. The console's first hydration may also embed the first project list page and one project Dashboard, read concurrently with the bootstrap; each embedded part carries the status and body its own route (GET /projects, GET /projects/{id}/dashboard) would return, and its failure never fails the bootstrap.","parameters":[{"in":"query","name":"includeProjectList","required":false,"schema":{"type":"string","enum":["1"]},"description":"Embed projectList, the first page GET /projects would return."},{"in":"query","name":"includeProjectDashboard","required":false,"schema":{"type":"string","enum":["1"]},"description":"Embed projectDashboard for projectId, else the workspace default project; null when there is none."},{"in":"query","name":"projectId","required":false,"schema":{"type":"string"},"description":"Project whose Dashboard is embedded. Authorized exactly as GET /projects/{id}/dashboard."},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]},"description":"Time range of the embedded Dashboard."}],"responses":{"200":{"description":"Shell bootstrap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthBootstrapResponse"}}}},"403":{"description":"Admission denied. Email-verification-required includes the same auth-only identity as SessionResponse and no workspace, GitHub, or notification data; beta admission retains its typed denial."}}}},"/auth/identities":{"get":{"summary":"List linked auth providers for the authenticated user","responses":{"200":{"description":"Linked auth providers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthIdentitiesResponse"}}}}}}},"/auth/identities/google/link/start":{"get":{"summary":"Issue a Google nonce bound to this browser and initiating session","responses":{"200":{"description":"Google link nonce issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleNonceResponse"}}}},"401":{"description":"A valid session is required"}}}},"/auth/identities/google/link":{"post":{"summary":"Link Google identity to the authenticated user","description":"Requires the server-issued nonce from /auth/identities/google/link/start, the same browser/session, and a signed Google token carrying that nonce. Email admission occurs before persistence at handoff exchange. Verified provider mail skips DNS; unverified mail uses the full signup DNS policy. A link without mail introduces no email identity.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleVerifyRequest"}}}},"responses":{"200":{"description":"Provider handoff created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthProviderHandoffResponse"}}}},"401":{"description":"Nonce, browser or initiating session invalid"}}}},"/auth/identities/github/link/start":{"get":{"summary":"Create GitHub login OAuth start URL for authenticated account linking","parameters":[{"in":"query","name":"returnTo","required":false,"schema":{"type":"string"},"description":"Sanitized relative /app/* route to restore after linking."}],"responses":{"200":{"description":"GitHub OAuth start URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubConnectResponse"}}}}}}},"/auth/identities/{provider}":{"delete":{"summary":"Unlink one auth provider from the authenticated user","parameters":[{"in":"path","name":"provider","required":true,"schema":{"type":"string","enum":["google","github"]}}],"responses":{"200":{"description":"Provider unlinked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthIdentityDeleteResponse"}}}}}}},"/organizations":{"get":{"summary":"List organizations available to the authenticated user","responses":{"200":{"description":"Organization list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationsResponse"}}}}}},"post":{"summary":"Create a new organization for the authenticated user","responses":{"201":{"description":"Organization created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}}}}},"/organizations/{id}":{"get":{"summary":"Get one accessible organization","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}}}},"patch":{"summary":"Rename an organization; billing owner only","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":64}}}}}},"responses":{"200":{"description":"Organization renamed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"400":{"description":"Name is empty, longer than 64 characters, or contains control characters"},"403":{"description":"Only the billing owner can rename the organization"}}}},"/abuse-notices":{"post":{"summary":"Notify Eurobase of illegal content (DSA Art. 16)","description":"Public. The notice is emailed to the operator inbox before the answer; a confirmation of receipt goes to the notifier email when one is given. Name and email are optional only for child sexual abuse material.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["category","urls","explanation","goodFaith"],"properties":{"category":{"type":"string","enum":["child_sexual_abuse","terrorist_content","phishing_malware_fraud","intellectual_property","privacy","other_illegal"]},"urls":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"string","format":"uri","maxLength":2048}},"explanation":{"type":"string","minLength":30,"maxLength":5000},"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email","maxLength":254},"goodFaith":{"type":"boolean","enum":[true]}}}}}},"responses":{"202":{"description":"Notice delivered to the operator inbox","content":{"application/json":{"schema":{"type":"object","required":["ok","reference","receipt"],"properties":{"ok":{"type":"boolean","enum":[true]},"reference":{"type":"string"},"receipt":{"type":"string","enum":["sent","failed","not_requested"]}}}}}},"422":{"description":"A required element of the notice is missing or invalid"},"429":{"description":"Too many notices from this address or for this notifier email"},"503":{"description":"Email delivery unavailable or failed, or the client address could not be proven; the body carries supportEmail"}}}},"/feedback":{"post":{"summary":"Submit authenticated product feedback with optional page screenshot","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackSubmitRequest"}}}},"responses":{"201":{"description":"Feedback recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackSubmitResponse"}}}},"401":{"description":"Authenticated session required"},"403":{"description":"Verified email or project access required"},"413":{"description":"Message or screenshot too large"},"415":{"description":"Screenshot content type rejected"}}}},"/internal/feedback":{"get":{"summary":"List owner-operator feedback submissions","x-internal":true,"parameters":[{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["new","reviewed","archived"]}},{"in":"query","name":"kind","required":false,"schema":{"type":"string","enum":["bug","suggestion"]}},{"in":"query","name":"projectId","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Feedback worklist","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalFeedbackListResponse"}}}},"403":{"description":"Owner operator lock required"}}}},"/internal/feedback/{id}":{"get":{"summary":"Get one owner-operator feedback submission","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Feedback detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalFeedbackDetailResponse"}}}},"403":{"description":"Owner operator lock required"},"404":{"description":"Feedback not found"}}},"patch":{"summary":"Update one owner-operator feedback status","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalFeedbackUpdateRequest"}}}},"responses":{"200":{"description":"Feedback updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalFeedbackDetailResponse"}}}},"403":{"description":"Owner operator lock required"},"404":{"description":"Feedback not found"}}}},"/internal/feedback/{id}/screenshot":{"get":{"summary":"Get one owner-operator feedback screenshot","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Private raster screenshot","content":{"image/webp":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"Owner operator lock required"},"404":{"description":"Screenshot not found"}}}},"/internal/admin/tables":{"get":{"summary":"List curated owner-operator-readable tables","x-internal":true,"responses":{"200":{"description":"Allowed table list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalAdminTablesResponse"}}}}}}},"/internal/admin/tables/{table}/rows":{"get":{"summary":"List curated owner-operator-readable rows for one table","x-internal":true,"parameters":[{"in":"path","name":"table","required":true,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"in":"query","name":"offset","required":false,"schema":{"type":"integer","minimum":0}},{"in":"query","name":"sort","required":false,"schema":{"type":"string"}},{"in":"query","name":"direction","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"in":"query","name":"rowId","required":false,"schema":{"type":"string"}},{"in":"query","name":"filterColumn","required":false,"schema":{"type":"string"}},{"in":"query","name":"filterValue","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Redacted row list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalAdminRowsResponse"}}}}}}},"/internal/admin/tables/{table}/rows/{id}":{"get":{"summary":"Get one curated owner-operator-readable row","x-internal":true,"parameters":[{"in":"path","name":"table","required":true,"schema":{"type":"string"}},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Redacted row detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalAdminRowResponse"}}}}}}},"/internal/operator/overview":{"get":{"summary":"Get owner-locked operator cockpit overview","x-internal":true,"responses":{"200":{"description":"Read-only fleet overview","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalOperatorOverviewResponse"}}}},"403":{"description":"Owner operator lock required"}}}},"/internal/operator/signups":{"get":{"summary":"List owner-operator signups with their progress, newest first","x-internal":true,"parameters":[{"in":"query","name":"period","required":false,"description":"Signup window in days, or all","schema":{"type":"string","enum":["7","30","90","all"],"default":"30"}},{"in":"query","name":"q","required":false,"description":"Email contains","schema":{"type":"string","maxLength":200}},{"in":"query","name":"stage","required":false,"description":"Furthest step reached","schema":{"type":"string","enum":["signed_up","email_verified","github_connected","project_created","deployed","live"]}},{"in":"query","name":"method","required":false,"schema":{"type":"string","enum":["email","github","google"]}},{"in":"query","name":"problems","required":false,"description":"1 lists only signups with an open problem","schema":{"type":"string","enum":["1"]}},{"in":"query","name":"page","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"One page of signups in the window, plus the window funnel","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalSignupListResponse"}}}},"400":{"description":"Invalid period, stage, sign-in method, problems or page"},"403":{"description":"Owner operator lock required"}}}},"/internal/operator/signups/{id}":{"get":{"summary":"Get one owner-operator signup with projects and deployments","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Signup detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalSignupDetailResponse"}}}},"403":{"description":"Owner operator lock required"},"404":{"description":"Signup not found"}}}},"/internal/operator/signups/{id}/actions":{"post":{"summary":"Change one signup’s own-plan quota with an append-only audit","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupQuotaActionRequest"}}}},"responses":{"200":{"description":"Committed action or the original result of an identical replay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupQuotaActionResponse"}}}},"400":{"description":"Invalid action, reason, clientRequestId or email confirmation"},"403":{"description":"Owner operator required"},"404":{"description":"Signup not found"},"409":{"description":"Request ID reused with a different target, operator or payload; own plan or active grant missing; plan changed or unavailable"},"429":{"description":"Operator action rate limit reached"},"503":{"description":"Quota state unavailable; no action committed"}}}},"/internal/operator/project-enforcement":{"get":{"summary":"Get one project's abuse enforcement state and evidence history (ADR 0080)","x-internal":true,"parameters":[{"in":"query","name":"projectId","required":false,"schema":{"type":"string"}},{"in":"query","name":"target","required":false,"schema":{"type":"string"},"description":"Project id, served host or URL."}],"responses":{"200":{"description":"Project, current enforcement state and append-only actions with evidence","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalProjectEnforcementResponse"}}}},"403":{"description":"Owner operator lock required"},"404":{"description":"No project serves that id, host or URL"},"409":{"description":"enforcement-target-ambiguous: the host resolves to more than one project"}}}},"/internal/operator/projects/{id}/enforcement-actions":{"post":{"summary":"Suspend or unsuspend one project's public serving with captured evidence (ADR 0080)","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalProjectEnforcementActionRequest"}}}},"responses":{"200":{"description":"The appended, replayed or unchanged action and, after a suspension, whether a Gateway served it","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalProjectEnforcementActionResponse"}}}},"403":{"description":"Owner operator lock required, or the project serves a Eurobase platform host"},"404":{"description":"Project not found"},"409":{"description":"enforcement-client-request-reused: clientRequestId was already used for a different action; enforcement-state-changed: the project state changed while the action was decided (retry with the same clientRequestId)"},"422":{"description":"Invalid action, reason, evidence URL or request id"},"429":{"description":"Operator enforcement rate limit reached"}}}},"/internal/operator/projects/{id}/diagnostics":{"get":{"summary":"Get owner-operator project diagnostic evidence","x-internal":true,"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Operator project diagnostics","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]},"description":"Always no-store."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalOperatorProjectDiagnosticsResponse"}}}},"403":{"description":"Owner operator lock required"}}}},"/internal/metering/ingest":{"post":{"summary":"Settle shared metering rows or independent immutable gateway WAL sources","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/MeteringIngestRequest"},{"$ref":"#/components/schemas/GatewayMeteringSourceEnvelopeRequest"}]}}}},"responses":{"200":{"description":"Stored shared acknowledgement or independent gateway source outcomes","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/MeteringIngestResponse"},{"$ref":"#/components/schemas/GatewayMeteringSourceEnvelopeResponse"}]}}}},"401":{"description":"Internal metering ingest token required"},"403":{"description":"Metering ingest token scope mismatch"},"409":{"description":"V2 batch or DB-owned row identity was already claimed with different canonical content (metering-source-idempotency-conflict), or historical equality proof is unavailable (metering-idempotency-proof-unavailable)"},"413":{"description":"Batch row count or total V2 source-contribution proof exceeds the bounded ingest contract"},"422":{"description":"Schema, source, or row identity is invalid"},"503":{"description":"Stored V2 idempotency proof is incomplete, or gateway metering settlement is temporarily unavailable","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GatewayMeteringTransientDbError"},{"$ref":"#/components/schemas/GatewayMeteringOperationTimeoutError"},{"$ref":"#/components/schemas/MeteringIdempotencyProofError"}]}}}}}}},"/internal/app-host/binary-change":{"post":{"summary":"Fence or settle a deliberate app host binary-set switch","description":"Host producer bearer scope app-host-binary-change. Begin checks live releases under the host row lock; pending source and target restrict promotion until applied or restored. No expiry. Retrying the exact id and sets is idempotent.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["action","id","source","target"],"properties":{"action":{"type":"string","enum":["begin","applied","restored"]},"id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"source":{"type":"array","maxItems":8,"items":{"$ref":"#/components/schemas/AppHostBinary"}},"target":{"type":"array","minItems":1,"maxItems":8,"items":{"$ref":"#/components/schemas/AppHostBinary"}}}}}}},"responses":{"200":{"description":"Exact transition fenced or settled","content":{"application/json":{"schema":{"type":"object","required":["id","state"],"properties":{"id":{"type":"string"},"state":{"type":"string","enum":["pending","applied","restored"]}}}}}},"401":{"description":"Wrong host producer bearer or scope"},"403":{"description":"Host is not a member"},"409":{"description":"Live release incompatible, source mismatch, unresolved transition or missing boot facts"},"422":{"description":"Invalid transition or binary set"},"503":{"description":"Host producer authorization unavailable"}}}},"/internal/app-host/routes/reconcile":{"post":{"summary":"Reconcile revoked Worker routes after launcher stops","x-internal":true,"description":"Existing app-host-facts producer authorization; current single host and boot only. stoppedAt uses the producer clock, bounded to 60 seconds from receipt. A reply carries generation while the API observes every committed project and resource change; a request without stops whose generation is still current is answered with no revocations and no database read.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["routeIds","stoppedRouteIds"],"properties":{"routeIds":{"type":"array","maxItems":500,"items":{"type":"string","pattern":"^prs_[0-9a-f]{12}$"}},"stoppedRouteIds":{"type":"array","maxItems":500,"items":{"type":"string","pattern":"^prs_[0-9a-f]{12}$"}},"stoppedAt":{"type":"string","format":"date-time","description":"Required with a nonempty stoppedRouteIds."},"generation":{"type":"string","maxLength":64,"description":"The generation of the last reply that revoked nothing, sent only while routeIds is a subset of that request."}}}}}},"responses":{"200":{"description":"Revoked routes","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["revokedRouteIds"],"properties":{"revokedRouteIds":{"type":"array","maxItems":500,"items":{"type":"string","pattern":"^prs_[0-9a-f]{12}$"}},"generation":{"type":"string","maxLength":64}}}}}},"400":{"description":"Invalid route inventory or stop boundary"},"401":{"description":"Wrong host producer bearer or scope"},"403":{"description":"Host boot is not current"},"503":{"description":"Host producer authorization or single-host binding unavailable"}}}},"/internal/app-host/retirement/settle":{"post":{"summary":"Acknowledge permanent host retirement after quiescence and usage delivery","description":"Host producer bearer with app-host-facts scope. Host and boot come only from verified claims. Requires the current provisioning/draining boot, no pending binary change and final SQL usage for every known invocation. Idempotent for that exact boot. The installed activator must permanently fence serving before calling this endpoint.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["schemaVersion"],"properties":{"schemaVersion":{"type":"string","enum":["app-host-retirement.v1"]}}}}}},"responses":{"200":{"description":"Durable exact host/boot settlement receipt"},"400":{"description":"Invalid retirement contract"},"401":{"description":"Missing, forged, expired or wrong-scope host bearer"},"409":{"description":"Wrong current boot, serving membership or unsettled usage/binary change"}}}},"/internal/app-host/facts":{"post":{"summary":"Store the facts of one app host boot (ADR 0076 contract §5)","description":"Bearer: an app host producer token, scope app-host-facts, signed with the key derived for its producerId from APP_HOST_METERING_SECRET. The token is verified before the body is read. Accepted from a provisioning, active or draining member. vcpuCount is fixed at the first report of a boot; app_hosts mirrors the newest boot.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostFactsV1"}}}},"responses":{"200":{"description":"Stored for its boot, unchanged (identical replay) or stale (an older report of a known boot)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostFactsResult"}}}},"400":{"description":"Facts break a contract rule (app-host-facts-invalid, with the rule)"},"401":{"description":"Producer token invalid (app-host-producer-token-invalid)"},"403":{"description":"Facts name another host or boot than the token (app-host-producer-scope-mismatch), or the host is not a member (app-host-not-member)"},"409":{"description":"The boot already reported another vCPU count, or other facts at the same reportedAt (boot-facts-conflict)"},"503":{"description":"APP_HOST_METERING_SECRET is not configured (app-host-ingest-unconfigured); retry after Retry-After"}}}},"/internal/app-host/usage/ingest":{"post":{"summary":"Ingest app host CPU and egress counters (ADR 0076 contract §5)","description":"Bearer: an app-host-usage producer token verified before the body is read. Active or draining members may submit up to 500 records. Exact replays are acknowledged once; different values for a stored key are quarantined. The host retains WAL records until a 200 disposition.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostUsageBatchV1"}}}},"responses":{"200":{"description":"Per-record accepted, duplicate or rejected dispositions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostUsageResults"}}}},"400":{"description":"Invalid batch envelope (app-host-usage-batch-invalid)"},"401":{"description":"Producer token invalid (app-host-producer-token-invalid)"},"403":{"description":"Batch names another host or boot (app-host-producer-scope-mismatch), or the host is not an active or draining member (app-host-not-member)"},"503":{"description":"Ingest secret is not configured (app-host-ingest-unconfigured), or boot facts have not arrived (boot-facts-unknown); retry after Retry-After"}}}},"/internal/app-host/logs/ingest":{"post":{"summary":"Ingest Worker output and instance events of one app host boot (ADR 0076 contract §5a)","description":"Bearer: an app-host-logs producer token verified before the body is read. Active or draining members may submit up to 64 streams and 500 records. Each stream is bound through the live or retained app route binding; rows are stored in the Workers project logs through the shared write sanitizer and are idempotent per host, boot and seq. The host drops, never retries, a refused batch.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostLogsBatchV1"}}}},"responses":{"200":{"description":"Per-stream accepted or rejected dispositions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostLogsResults"}}}},"400":{"description":"Invalid batch envelope (app-host-logs-batch-invalid)"},"401":{"description":"Producer token invalid (app-host-producer-token-invalid)"},"403":{"description":"Batch names another host or boot (app-host-producer-scope-mismatch), or the host is not an active or draining member (app-host-not-member)"},"503":{"description":"Ingest secret is not configured (app-host-ingest-unconfigured)"}}}},"/internal/app-hosts/{hostId}":{"get":{"summary":"Read one app host membership and latest boot facts (operator)","description":"Bearer: the internal maintenance token. Returns host null when absent.","x-internal":true,"parameters":[{"in":"path","name":"hostId","required":true,"schema":{"type":"string","pattern":"^aph_[0-9a-f]{12}$"}}],"responses":{"200":{"description":"Current membership and latest acknowledged boot facts, or null when absent"},"401":{"description":"Internal maintenance token required"}}},"put":{"summary":"Register or move one app host membership (operator)","description":"Bearer: the internal maintenance token. A host is born provisioning; provisioning -> active | retired, active -> draining, draining -> active | retired. Retired is terminal. Address, port, instance and zone never change.","x-internal":true,"parameters":[{"in":"path","name":"hostId","required":true,"schema":{"type":"string","pattern":"^aph_[0-9a-f]{12}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostMembershipRequest"}}}},"responses":{"200":{"description":"Membership after the write; changed is false when the host already had this state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHostMembershipResponse"}}}},"401":{"description":"Internal maintenance token required"},"409":{"description":"app-host-transition-invalid, app-host-retired, app-host-identity-mismatch, app-host-facts-missing or app-host-address-in-use"},"422":{"description":"Invalid membership (app-host-membership-invalid)"}}}},"/account/usage":{"get":{"summary":"Read account usage and plan screen model","description":"Returns one coherent monthly snapshot containing account meters, resource contributors, projection freshness, and a separate UTC-day action-quota projection. When organizationId is supplied, plan resolution is organization-exclusive and never falls back to the requesting user subscription.","security":[{"bearerAuth":[]}],"parameters":[{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Reads the usage and plan screen for an organization the user belongs to."},{"in":"query","name":"billingMonth","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}(-\\d{2})?$"},"description":"Reads a closed billing month when supplied; omitted reads the current month."}],"responses":{"200":{"description":"Account usage summary with recorded values and projection status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUsageResponse"}}}}}}},"/account/usage/resource-contributors":{"get":{"summary":"Read account usage top resource contributors","security":[{"bearerAuth":[]}],"parameters":[{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Reads visible resource contributors for an organization the user belongs to."},{"in":"query","name":"billingMonth","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}(-\\d{2})?$"},"description":"Reads a closed billing month when supplied; omitted reads the current month."}],"responses":{"200":{"description":"Account usage top resource contributors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUsageResourceContributorsResponse"}}}}}}},"/account/billing":{"get":{"summary":"Read account billing screen model","security":[{"bearerAuth":[]}],"parameters":[{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Reads the billing state for an organization the user belongs to. When omitted, the only organization of the user is read; a user without any project reads their Free plan with a null scope."}],"responses":{"200":{"description":"Account billing summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountBillingResponse"}}}},"400":{"description":"Organization is required"},"404":{"description":"Organization not found"}}}},"/account/usage/timeseries":{"get":{"summary":"Read account usage time-series buckets for visible meters","security":[{"bearerAuth":[]}],"parameters":[{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Reads visible project usage buckets for an organization the user belongs to."},{"in":"query","name":"metricCodes","required":true,"schema":{"type":"string"},"description":"Comma-separated, distinct usage metric codes to aggregate from usage_counters in one read; series are returned in this order. runtime_average_latency_ms is API-derived from runtime_latency_ms_sum divided by runtime_requests."},{"in":"query","name":"range","required":false,"schema":{"type":"string","enum":["24h","7d","30d","90d"],"default":"30d"}},{"in":"query","name":"bucket","required":false,"schema":{"type":"string","enum":["1h","1d"],"default":"1d"}}],"responses":{"200":{"description":"Account usage time-series buckets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUsageTimeSeriesResponse"}}}},"400":{"description":"Invalid or duplicate metric, range, or bucket"},"404":{"description":"Organization not found"}}}},"/billing/checkout-session":{"post":{"summary":"Create a Stripe Checkout session for an organization plan upgrade","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["planCode"],"properties":{"organizationId":{"type":"string","description":"When omitted, the only organization of the user is used; for a user without any project, checkout creates the default billing scope."},"planCode":{"type":"string","enum":["starter","pro"]}}}}}},"responses":{"201":{"description":"Stripe Checkout redirect URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCheckoutSessionResponse"}}}},"409":{"description":"Billing subscription is already active for this organization"}}}},"/billing/subscription-plan":{"post":{"summary":"Change an active subscription between Starter and Pro","description":"Updates the existing Stripe subscription item price. An upgrade charges the prorated difference now and applies only once paid; a downgrade applies now and credits unused time on the next invoice. Paid limits change only after the signed Stripe subscription webhook.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId","planCode"],"properties":{"organizationId":{"type":"string"},"planCode":{"type":"string","enum":["starter","pro"]}}}}}},"responses":{"200":{"description":"Stripe accepted the plan change; entitlement follows the signed webhook","content":{"application/json":{"schema":{"type":"object","required":["planCode"],"properties":{"planCode":{"type":"string","enum":["starter","pro"]}}}}}},"402":{"description":"Payment for the upgrade failed; the plan is unchanged"},"403":{"description":"Billing owner required"},"409":{"description":"No active subscription to change, the plan is already active, or Stripe holds an unconfirmed change"}}}},"/billing/ownership":{"post":{"summary":"Transfer billing responsibility to an existing member of every project sharing the plan","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId","email","confirmation"],"properties":{"organizationId":{"type":"string"},"email":{"type":"string"},"confirmation":{"type":"string"}}}}}},"responses":{"200":{"description":"Billing responsibility transferred; project roles unchanged"},"400":{"description":"Confirmation does not match the current billing owner email"},"403":{"description":"Current billing owner required"},"409":{"description":"Recipient must be an active member of every project sharing the plan"}}}},"/billing/portal-session":{"post":{"summary":"Create a Stripe Customer Portal session for an organization","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string"},"flow":{"type":"string","enum":["cancel"],"description":"Open the portal on the cancellation step for the organization subscription"}}}}}},"responses":{"201":{"description":"Stripe Customer Portal redirect URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPortalSessionResponse"}}}},"400":{"description":"Unknown portal flow"},"409":{"description":"No Stripe customer exists for this organization, or no subscription can be canceled"}}}},"/stripe/webhook":{"post":{"summary":"Receive Stripe webhook events","description":"Public Stripe callback. The API verifies the Stripe-Signature header against the raw request body before processing.","responses":{"200":{"description":"Webhook accepted","content":{"application/json":{"schema":{"type":"object","required":["received"],"properties":{"received":{"type":"boolean"},"skipped":{"type":"boolean"}}}}}},"401":{"description":"Invalid Stripe signature"}}}},"/notifications":{"get":{"summary":"List durable user notifications for the notification center","parameters":[{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":50},"description":"Maximum notifications to return. Defaults to 20."},{"in":"query","name":"view","required":false,"schema":{"type":"string","enum":["inbox","unread","archived"]}},{"in":"query","name":"category","required":false,"schema":{"type":"string","enum":["deployment","runtime","github","usage","account"]}},{"in":"query","name":"severity","required":false,"schema":{"type":"string","enum":["info","warning","critical"]}},{"in":"query","name":"projectId","required":false,"schema":{"type":"string"}},{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"}},{"in":"query","name":"q","required":false,"schema":{"type":"string"},"description":"Bounded text search across title, message, and resource label."},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"},"description":"Opaque cursor returned by the previous notification list response."},{"in":"query","name":"includeFilterCounts","required":false,"schema":{"type":"boolean"},"description":"Opt-in aggregate counts for filter chips. Defaults to false to keep row fetches bounded."}],"responses":{"200":{"description":"Notification list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsResponse"}}}}}}},"/notifications/{notificationId}":{"get":{"summary":"Read API-owned notification detail and bounded thread events","parameters":[{"in":"path","name":"notificationId","required":true,"schema":{"type":"string"}},{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Optional workspace scope for the selected notification."}],"responses":{"200":{"description":"Notification detail projection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationDetailResponse"}}}},"404":{"description":"Notification not found in the active user scope"}}}},"/notifications/summary":{"get":{"summary":"Read the bounded notification badge summary","parameters":[{"in":"query","name":"organizationId","required":false,"schema":{"type":"string"},"description":"Optional workspace scope for the notification badge summary."}],"responses":{"200":{"description":"Notification summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsSummaryResponse"}}}}}}},"/notifications/read":{"post":{"summary":"Mark one notification, selected notifications, or the active unread scope as read","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsReadRequest"}}}},"responses":{"200":{"description":"Notifications marked read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsReadResponse"}}}}}}},"/notifications/archive":{"post":{"summary":"Archive one notification, selected notifications, or the active notification scope","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsArchiveRequest"}}}},"responses":{"200":{"description":"Notifications archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsReadResponse"}}}}}}},"/notifications/unarchive":{"post":{"summary":"Restore one archived notification or selected archived notifications","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsArchiveRequest"}}}},"responses":{"200":{"description":"Notification restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsReadResponse"}}}}}}},"/github/connect-url":{"get":{"summary":"Get next GitHub connect URL","description":"Returns from DB-backed account/install snapshot truth. This endpoint must not refresh live GitHub installations or repositories on the click path.","parameters":[{"in":"query","name":"returnTo","required":false,"schema":{"type":"string","format":"uri"},"description":"Optional loopback or configured web-app base URL to restore after the GitHub callback."},{"in":"query","name":"returnPath","required":false,"schema":{"type":"string"},"description":"Optional app-relative GitHub return route. Only /app/github with a project deployments next path is accepted."}],"responses":{"200":{"description":"Connect URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubConnectResponse"}}}},"409":{"description":"GitHub connect blocked by operator-side control-plane configuration"}}}},"/github/access-target/{token}":{"get":{"summary":"Resolve an opaque GitHub access target","description":"Validates a short-lived server-stored access-target token and redirects to the corresponding GitHub App installation settings page. Expired, replayed, or stale-version tokens redirect back to in-app GitHub review.","parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string","pattern":"^hat_[A-Za-z0-9_-]+$"}}],"responses":{"302":{"description":"Redirects to GitHub installation settings or in-app review recovery"}}}},"/github/access-target/installation/{target}":{"get":{"summary":"Resolve an opaque GitHub installation access target","description":"Validates the session and an API-owned browser installation id from the saved DB snapshot, then redirects to the matching GitHub App installation settings page. Invalid or stale targets redirect back to in-app GitHub review.","parameters":[{"in":"path","name":"target","required":true,"schema":{"type":"string","pattern":"^github-installation:[0-9a-f]{16}$"}}],"responses":{"302":{"description":"Redirects to GitHub installation settings or in-app review recovery"}}}},"/github/refresh":{"post":{"summary":"Refresh GitHub repository visibility","description":"Explicit rate-limited provider refresh. The API claims a per-user refresh lease, performs bounded provider reads, and commits only if the DB snapshot version has not changed while the provider read was in flight.","responses":{"200":{"description":"Refreshed GitHub snapshot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubReposResponse"}}}},"409":{"description":"GitHub refresh already in progress"}}}},"/github/disconnect":{"post":{"summary":"Remove user-owned GitHub provider access and clear cached visibility","responses":{"200":{"description":"Final revoked GitHub snapshot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubReposResponse"}}}},"502":{"description":"GitHub provider access could not be removed"}}}},"/github/oauth/start":{"get":{"summary":"Start GitHub OAuth flow","responses":{"302":{"description":"Redirects to GitHub"}}}},"/github/oauth/callback":{"get":{"summary":"GitHub OAuth callback","description":"Completes GitHub OAuth, persists verified account truth, and may continue directly into GitHub App installation when the next safe action is unambiguous. An identity already linked to another Eurobase user remains unchanged and redirects with github-account-linked-to-another-user, regardless of OAuth status or token validity. A user already linked to a different immutable GitHub identity remains unchanged and redirects with github-account-mismatch.","responses":{"302":{"description":"Redirect to GitHub App installation, callback success, or a bounded callback error state"}}}},"/github/install/start":{"get":{"summary":"Start GitHub App installation flow","responses":{"302":{"description":"Redirects to GitHub"}}}},"/github/callback":{"get":{"summary":"GitHub App callback","responses":{"200":{"description":"Callback HTML"}}}},"/github/install/callback":{"get":{"summary":"GitHub App installation callback","description":"Completes GitHub App installation callback and returns control to the web shell with DB-backed installation and repository truth.","responses":{"200":{"description":"Callback HTML"}}}},"/github/repos":{"get":{"summary":"List cached installation repos and snapshot metadata","description":"Reads the stored GitHub account/install/repository snapshot only. The cached repo set is the selected/allowed repo snapshot persisted by callbacks and webhooks, and normal navigation must not trigger live GitHub sync. Repository rows are a bounded browser view model and do not expose clone URLs or installation ids.","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Case-insensitive repository name filter applied to the cached snapshot."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":50},"description":"Maximum repository rows returned from the cached snapshot."}],"responses":{"200":{"description":"Repo list snapshot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubReposResponse"}}}}}}},"/github/stream":{"get":{"summary":"Stream GitHub snapshot invalidation events","description":"Authenticated server-sent events stream for DB-backed GitHub snapshot version changes. The stream only signals snapshot invalidation; clients must refetch /github/repos for actual data.","responses":{"200":{"description":"SSE stream"}}}},"/github/webhook":{"post":{"summary":"GitHub webhook receiver","description":"Receives GitHub App webhook deliveries after signature verification. Delivery idempotency is DB-owned: completed duplicates return safe accepted responses, in-flight duplicates return a bounded retryable conflict, and handler failures leave the delivery retryable. Push events also persist per-project commit intent so API maintenance can retry deploy enqueue without relying on GitHub redelivery.","parameters":[{"in":"header","name":"x-github-event","required":true,"schema":{"type":"string"}},{"in":"header","name":"x-github-delivery","required":true,"schema":{"type":"string"}},{"in":"header","name":"x-hub-signature-256","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Webhook accepted or completed duplicate safely replayed"},"400":{"description":"Required webhook headers or JSON payload are invalid"},"401":{"description":"GitHub webhook signature verification failed"},"409":{"description":"Same delivery is already processing and should be retried later"},"503":{"description":"Handler failed after delivery claim; delivery remains retryable"}}}},"/projects/{id}/members":{"get":{"summary":"List project members","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectMembersResponse"}}}}}}},"/account/domains":{"get":{"summary":"List the custom domains of a workspace","description":"The workspace owner sees every domain of the workspace; a project member sees the domains linked to their projects. Each domain names the project it serves, if any, lists the two DNS records to add where the domain DNS lives, and shows what public DNS reports.","parameters":[{"in":"query","name":"organizationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Workspace domains","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDomainsResponse"}}}},"400":{"description":"organizationId missing (organization-id-required)"},"404":{"description":"Not a member of this workspace (workspace-not-found)"}}},"post":{"summary":"Connect a custom domain to a workspace","description":"Workspace owner only, within the workspace plan limit. With projectId the domain serves that project once its _acme-challenge CNAME is verified and its certificate is issued; without it the domain waits in the workspace and serves nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDomainRequest"}}}},"responses":{"201":{"description":"Domain connected, waiting for its DNS records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponse"}}}},"400":{"description":"organizationId missing (organization-id-required), not a public domain name (project-domain-invalid), a Eurobase address (project-domain-platform-zone) or an invalid projectId (project-domain-target-invalid)"},"403":{"description":"Only the workspace owner can manage its domains (workspace-domain-owner-required)"},"409":{"description":"Already in the workspace (project-domain-exists), domain limit reached (project-domain-limit-reached) or a project outside the workspace (project-domain-workspace-mismatch)"},"429":{"description":"Too many domains connected by this user today"},"503":{"description":"Custom domains are not available (project-domains-not-configured)"}}}},"/account/domains/{domainId}":{"patch":{"summary":"Link a custom domain to a project, move it, or unlink it","description":"Workspace owner only. projectId names a project of the workspace, or null to unlink. DNS records and the certificate stay valid; an active domain serves the linked project production deployment at once, and serves nothing while unlinked.","parameters":[{"in":"path","name":"domainId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId"],"properties":{"projectId":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Domain linked, moved or unlinked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponse"}}}},"400":{"description":"projectId missing (project-domain-target-required) or invalid (project-domain-target-invalid)"},"403":{"description":"Only the workspace owner can manage its domains (workspace-domain-owner-required)"},"404":{"description":"Domain not found (project-domain-not-found)"},"409":{"description":"A project outside the workspace (project-domain-workspace-mismatch)"},"429":{"description":"Too many changes by this user this hour"}}},"delete":{"summary":"Remove a custom domain from the workspace","parameters":[{"in":"path","name":"domainId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain removed; it stops serving immediately","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}},"403":{"description":"Only the workspace owner can manage its domains (workspace-domain-owner-required)"},"404":{"description":"Domain not found (project-domain-not-found)"}}}},"/projects/{id}/invitations":{"post":{"summary":"Invite a person to the project by email","description":"Owner or admin. Saves or renews a 7-day invitation and emails it. The answer is the same whether or not the email has a Eurobase account; the person joins only by accepting.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInvitationRequest"}}}},"responses":{"201":{"description":"Invitation saved; emailDelivery reports whether the email went out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInvitationResponse"}}}},"409":{"description":"Already a member (project-member-exists) or member limit reached (project-member-limit-reached)"},"429":{"description":"Invitation rate limit reached"}}}},"/projects/{id}/invitations/{invitationId}":{"delete":{"summary":"Revoke a pending project invitation","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"invitationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation revoked"},"404":{"description":"Invitation not found"}}}},"/invitations":{"get":{"summary":"List pending project invitations for the signed-in, verified email","responses":{"200":{"description":"Pending invitations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyProjectInvitationsResponse"}}}},"403":{"description":"Email not verified (project-invitation-email-unverified)"}}}},"/invitations/{invitationId}/accept":{"post":{"summary":"Accept a project invitation sent to the signed-in, verified email","parameters":[{"in":"path","name":"invitationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Joined the project"},"403":{"description":"Email not verified or account cannot accept"},"404":{"description":"Invitation not found or expired"},"409":{"description":"Invitation no longer valid (project-invitation-stale) or member limit reached"}}}},"/invitations/{invitationId}":{"delete":{"summary":"Decline a project invitation sent to the signed-in, verified email","parameters":[{"in":"path","name":"invitationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation declined"},"404":{"description":"Invitation not found"}}}},"/projects/{id}/members/{membershipId}":{"patch":{"summary":"Update a project member role","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"membershipId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectMemberUpsertRequest"}}}},"responses":{"200":{"description":"Project member updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectMemberResponse"}}}}}},"delete":{"summary":"Remove a project member","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"membershipId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project member removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectMemberResponse"}}}}}}},"/internal/runner/jobs/{jobId}/context":{"get":{"summary":"Internal runner fetches deployment context for a dispatched job attempt","x-internal":true,"parameters":[{"name":"publication","in":"query","required":false,"description":"Request the scoped Registry publication lease after source image capture.","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"Deployment context"}}}},"/internal/runner/jobs/{jobId}/source-execution":{"get":{"summary":"Observe the source worker owned by this build attempt","x-internal":true,"responses":{"200":{"description":"Provider observation and scoped output read grant after success"}}},"post":{"summary":"Start the source worker once ({}) or publish the uploaded source archive to it ({ sourceSha256 })","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"sourceSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}}}}}},"responses":{"200":{"description":"Durable source execution observation"}}}},"/internal/runner/jobs/{jobId}/build-cache":{"post":{"summary":"Get exact-object cache grants for this project build or publish its completed cache","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"required":["action","inputDigest"],"properties":{"action":{"const":"prepare"},"inputDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"}}},{"type":"object","additionalProperties":false,"required":["action"],"properties":{"action":{"const":"complete"}}}]}}}},"responses":{"200":{"description":"Optional cache grants or publication result; unavailable cache permits a clean build"}}}},"/internal/runner/jobs/{jobId}/workers-detection":{"post":{"summary":"Report the Workers build controller's runtime detection before any user code runs (ADR 0076 D10)","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"required":["record","lock","devDependencies"],"properties":{"record":{"type":"object","description":"eurobase-workers-detection-v2 record"},"lock":{"type":"string","description":"Base64 of the exact toolchain lock bytes the record names"},"devDependencies":{"type":"array","maxItems":16,"items":{"type":"string"}}}},{"type":"object","additionalProperties":false,"required":["refusal"],"properties":{"refusal":{"const":"app-source-detection-cap-exceeded"}}}]}}}},"responses":{"200":{"description":"decision build (with workersDetectionSha256), reroute (the deployment builds on Paketo in a new attempt) or refused (the build failed with its typed reason)"},"403":{"description":"The attempt is not this build's current one, or it was already settled"},"409":{"description":"This build does not report Workers detection, or the record conflicts with the accepted one"},"422":{"description":"Invalid report: schema, lock, adapter pin or devDependency names"}}}},"/internal/runner/jobs/{jobId}/token-exchange":{"post":{"summary":"Internal runner exchanges its scoped provider authority for a job token","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["bootstrapSecret","runnerId","jobAttempt"],"properties":{"bootstrapSecret":{"type":"string"},"runnerId":{"type":"string"},"jobAttempt":{"type":"string"}}},{"type":"object","required":["deploymentToken","providerRunId"],"additionalProperties":false,"properties":{"deploymentToken":{"type":"string"},"providerRunId":{"type":"string"}}}]}}}},"responses":{"200":{"description":"Scoped runner token issued for the current dispatched attempt"}}}},"/internal/runner/jobs/{jobId}/preview-session":{"post":{"summary":"Issue a scoped capture credential directly to the authenticated preview job","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["captureDeadlineAt"],"additionalProperties":false,"properties":{"captureDeadlineAt":{"type":"string","format":"date-time"}}}}}},"x-internal":true,"responses":{"200":{"description":"Preview session issued or skipped","content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["skip","reason"],"properties":{"skip":{"type":"boolean","enum":[true]},"reason":{"type":"string"}}},{"type":"object","required":["skip","sessionId","protocolVersion","previewCaptureToken","captureHeaderName","captureDeadlineAt","previewTargetUrl","previewHostname"],"properties":{"skip":{"type":"boolean","enum":[false]},"sessionId":{"type":"string"},"protocolVersion":{"type":"integer","enum":[2]},"previewCaptureToken":{"type":"string"},"captureHeaderName":{"type":"string","enum":["X-Eurobase-Preview-Capture-Token-V2"]},"captureDeadlineAt":{"type":"string","format":"date-time"},"previewTargetUrl":{"type":"string"},"previewHostname":{"type":"string"}},"additionalProperties":false}]}}}}}}},"/internal/runner/jobs/{jobId}/gateway-probe-auth":{"post":{"summary":"Internal runner issues a short-lived gateway probe token after provider rollout and candidate route registration","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["host","deploymentId"],"properties":{"host":{"type":"string"},"deploymentId":{"type":"string"},"method":{"type":"string","enum":["GET","HEAD"]},"path":{"type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Gateway probe token issued for the current job host and deployment","content":{"application/json":{"schema":{"type":"object","required":["runtimeAuth","host","deploymentId","method","path","routeId"],"properties":{"runtimeAuth":{"type":"object","required":["runtimeHeaderName","runtimeHeaderValue","gatewayProbeChallenge"],"properties":{"runtimeHeaderName":{"type":"string"},"runtimeHeaderValue":{"type":"string"},"migrationRuntimeHeaderName":{"type":"string"},"migrationRuntimeHeaderValue":{"type":"string"},"gatewayProbeChallenge":{"type":"object","required":["nonce","expiresAt","deploymentId","routeId","host","method","path"],"properties":{"nonce":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"deploymentId":{"type":"string"},"routeId":{"type":"string"},"host":{"type":"string"},"method":{"type":"string","enum":["GET","HEAD"]},"path":{"type":"string"}},"additionalProperties":false}},"additionalProperties":false},"host":{"type":"string"},"deploymentId":{"type":"string"},"method":{"type":"string","enum":["GET","HEAD"]},"path":{"type":"string"},"routeId":{"type":"string"}},"additionalProperties":false}}}},"403":{"description":"Gateway probe token forbidden for job type, host, or deployment mismatch"},"409":{"description":"Gateway probe token unavailable until candidate route and provider rollout proof exist"}}}},"/internal/runner/jobs/{jobId}/preview-consume":{"post":{"summary":"Close a capture session using its authenticated job, including after capture expiry","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sessionId"],"additionalProperties":false,"properties":{"sessionId":{"type":"string"}}}}}},"x-internal":true,"responses":{"200":{"description":"Preview session consumed"}}}},"/internal/runner/jobs/{jobId}/preview-object":{"post":{"summary":"Store the authenticated preview job's WebP capture with API storage credentials","requestBody":{"required":true,"content":{"image/webp":{"schema":{"type":"string","format":"binary","maxLength":2097152}}}},"x-internal":true,"responses":{"200":{"description":"Preview object stored for this job attempt; the READY patch is now accepted"},"400":{"description":"Body is not a WebP image"},"409":{"description":"Capture session is not active for this attempt or its deadline expired"},"413":{"description":"Body exceeds 2 MiB"}}}},"/internal/runner/jobs/{jobId}/events":{"post":{"summary":"Internal runner appends deployment audit events/log messages","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InternalRunnerEvent"},{"type":"object","required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/InternalRunnerEvent"}}}}]}}}},"responses":{"200":{"description":"Event appended"}}}},"/internal/runner/jobs/{jobId}/status":{"patch":{"summary":"Internal runner updates status, health metadata, and upstream-ready route proof for a dispatched job attempt","description":"Accepts scoped runner status patches. Deploy and rollback jobs may include sanitized upstream-ready proof so the API can persist deployment-scoped gateway candidate routes before branded/gateway health proof runs.","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"patch":{"type":"object","properties":{"status":{"type":"string"},"healthy":{"type":"boolean"},"lastError":{"type":["string","null"]},"healthStatusReason":{"type":["string","null"]},"providerMetadata":{"type":"object","description":"Sanitized upstream-ready route proof. The API consumes verified mutationEvidence to persist candidate route truth before branded probing.","properties":{"runtime":{"type":"string"},"containerId":{"type":"string"},"defaultDomain":{"type":"string"},"routeHostname":{"type":"string"},"deployedImageRef":{"type":"string"},"imageDigest":{"type":"string"},"namespaceName":{"type":"string"},"serviceName":{"type":"string"},"publishPrefix":{"type":"string"},"mutationEvidence":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string"},"action":{"type":"string"},"resourceType":{"type":"string"},"providerResourceId":{"type":"string"},"verificationStatus":{"type":"string"},"after":{"type":"object","additionalProperties":true},"error":{"type":"string"}},"additionalProperties":false}}},"additionalProperties":false}},"additionalProperties":false}},"required":["patch"],"additionalProperties":false}}}},"responses":{"200":{"description":"Deployment updated"}}}},"/internal/runner/jobs/{jobId}/activate":{"post":{"summary":"Internal runner activates a proven deployment, transfers it to route convergence, or replays either committed outcome","x-internal":true,"responses":{"200":{"description":"Deployment activated, transferred to route convergence, or an identical completed runner attempt replayed after idempotent reconciliation","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true]},"activationConverging":{"type":"boolean","enum":[true]},"jobFinalized":{"type":"boolean","enum":[true]},"replay":{"type":"boolean","enum":[true]}},"additionalProperties":false}}}},"409":{"description":"Activation precondition unmet; no active release or activation-failure state is committed"}}}},"/internal/runner/jobs/{jobId}/complete":{"post":{"summary":"Internal runner marks a dispatched job attempt complete","x-internal":true,"responses":{"200":{"description":"Job completed"}}}},"/internal/runner/jobs/{jobId}/build-complete":{"post":{"summary":"Internal builder records a validated deploy manifest and queues the follow-up deploy job","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["deployManifest","sourceBuildRegistryCredentialReceipt"],"properties":{"deployManifest":{"allOf":[{"$ref":"#/components/schemas/BuildDeployManifest"},{"type":"object","required":["schemaVersion"],"properties":{"schemaVersion":{"const":"app-deploy-manifest-paketo-v1"}}}]},"apiBaseUrl":{"type":["string","null"]},"sourceBuildRegistryCredentialReceipt":{"$ref":"#/components/schemas/SourceBuildRegistryCredentialReceipt"}},"additionalProperties":false},{"type":"object","required":["deployManifest"],"properties":{"deployManifest":{"allOf":[{"$ref":"#/components/schemas/BuildDeployManifest"},{"type":"object","required":["schemaVersion"],"properties":{"schemaVersion":{"const":"app-deploy-manifest-v1"}}}]},"apiBaseUrl":{"type":["string","null"]},"sourceBuildRegistryCredentialReceipt":{"type":"null"}},"additionalProperties":false},{"type":"object","description":"workers-v1 build handoff: the identity of the build attempt's verified ready app release. Accepting the verified handoff queues an activation-only deploy job. Dispatch requires compatible app-host capacity; candidate render and route verification must succeed before activation. A failed candidate does not replace the previous live release.","required":["deployManifest"],"properties":{"deployManifest":{"type":"object","required":["schemaVersion","deploymentId","outputKind","source","appRelease"],"properties":{"schemaVersion":{"const":"app-deploy-manifest-workers-v1"},"deploymentId":{"type":"string"},"outputKind":{"const":"app_release"},"source":{"type":"object","required":["commitSha"],"properties":{"commitSha":{"type":"string"}},"additionalProperties":false},"appRelease":{"type":"object","required":["releaseId","manifestSha256","manifestBytes"],"properties":{"releaseId":{"type":"string","pattern":"^apr_[0-9a-f]{12}$"},"manifestSha256":{"type":"string","pattern":"^[0-9a-f]{64}$"},"manifestBytes":{"type":"integer","minimum":1}},"additionalProperties":false}},"additionalProperties":false}},"additionalProperties":false}]}}}},"responses":{"200":{"description":"Build handoff completed"}}}},"/internal/runner/jobs/{jobId}/app-release":{"post":{"summary":"Internal workers-v1 build job app release actions: begin, reserve blobs, create the release, renew its manifest grant, and continue bounded verification until ready","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["action"],"properties":{"action":{"const":"begin"}},"additionalProperties":false},{"type":"object","required":["action","releaseId","blobs"],"properties":{"action":{"const":"reserve"},"releaseId":{"type":"string"},"blobs":{"type":"array","minItems":1,"maxItems":128,"items":{"type":"object","required":["kind","sha256","byteSize"],"properties":{"kind":{"enum":["asset","bundle"]},"sha256":{"type":"string"},"byteSize":{"type":"integer"}},"additionalProperties":false}}},"additionalProperties":false},{"type":"object","required":["action","releaseId","manifestSha256","manifestBytes","bundleSha256","compatibilityDate","minWorkerdVersion","assetFileCount","distinctAssetCount"],"properties":{"action":{"const":"create"},"releaseId":{"type":"string"},"manifestSha256":{"type":"string"},"manifestBytes":{"type":"integer"},"bundleSha256":{"type":["string","null"]},"compatibilityDate":{"type":"string"},"minWorkerdVersion":{"type":"string"},"assetFileCount":{"type":"integer"},"distinctAssetCount":{"type":"integer"}},"additionalProperties":false},{"type":"object","required":["action","releaseId"],"properties":{"action":{"const":"manifest-grant"},"releaseId":{"type":"string"}},"additionalProperties":false},{"type":"object","required":["action","releaseId"],"properties":{"action":{"const":"complete"},"releaseId":{"type":"string"}},"additionalProperties":false}]}}}},"responses":{"200":{"description":"Action result. reserve returns present or upload per blob, and only upload carries an exact-key write-once PUT grant (URL and required headers, at most 300 s); create and manifest-grant return one manifest PUT grant; complete returns either staged verification progress (repeat complete) or the ready release. No storage credential is returned."},"409":{"description":"Typed conflict: intent expired or not open, stale attempt, changed candidate, blob limit, cleanup in progress (retry), object not uploaded yet (retry) or integrity failure"},"422":{"description":"Invalid action body"},"503":{"description":"app-release-signer-unavailable when the API holds no release signer, or retryable storage unavailability"}}}},"/internal/runner/jobs/{jobId}/fail":{"post":{"summary":"Internal runner marks a dispatched job attempt failed and may persist sanitized unhealthy rollout evidence","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["errorMessage"],"properties":{"errorMessage":{"type":"string"},"sourceBuildPhaseTimingsMs":{"oneOf":[{"type":"object","additionalProperties":{"type":"integer","minimum":0}},{"type":"null"}]},"sourceBuildRegistryCredentialReceipt":{"oneOf":[{"$ref":"#/components/schemas/SourceBuildRegistryCredentialReceipt"},{"type":"null"}]},"deploymentPatch":{"type":"object"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Job failed"}}}},"/internal/maintenance/reconcile":{"post":{"summary":"Internal platform scheduler runs API-owned maintenance reconciliation","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MaintenanceReconcileRequest"}}}},"responses":{"200":{"description":"Maintenance reconcile completed"}}}},"/internal/deployment/routes/reconcile":{"post":{"summary":"Recover only deployments awaiting public route activation","x-internal":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phases":{"type":"array","items":{"type":"string","enum":["route_sync"]},"minItems":1,"maxItems":1,"description":"CronJob ownership marker; execution is fixed to route_sync"},"routeLimit":{"type":"integer","minimum":1,"maximum":100},"routeDeadlineMs":{"type":"integer","minimum":5000,"maximum":50000}},"additionalProperties":false}}}},"responses":{"200":{"description":"Deployment route activation recovery completed"},"401":{"description":"Internal maintenance authority required"}}}},"/internal/functions/quota-projection/activate":{"post":{"summary":"Activate organization Function quota projection after exact compatible fleet proof","x-internal":true,"responses":{"200":{"description":"Projection activation committed or replayed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionQuotaProjectionActivationResponse"}}}},"401":{"description":"Internal maintenance authority required"},"409":{"description":"Current four-member capability proof is incomplete or stale"}}}},"/projects":{"get":{"summary":"List one bounded page of member-safe project cards","parameters":[{"name":"includeUsageSummary","in":"query","required":false,"schema":{"type":"string","enum":["0","false","1","true"]},"deprecated":true,"description":"Compatibility-only during rollback. The project list never reads Usage and usageSummary is always null."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1},"description":"Opaque cursor returned by the preceding bounded project-card page."},{"name":"search","in":"query","required":false,"schema":{"type":"string"},"description":"Literal case-insensitive substring across visible name, repository, branch, root directory, run command and hostname. Trims surrounding whitespace; repository matches are hidden for contributors. Keep the same search with each continuation cursor."}],"responses":{"200":{"description":"Project list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectsResponse"}}}}}},"post":{"summary":"Create project first with API-derived first workspace and do not auto-deploy by default","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreateRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectResponse"}}}},"400":{"description":"Project name is not a valid Eurobase hostname label","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreateInvalidResponse"}}}},"409":{"description":"Workspace selection is missing, project cleanup is still blocking reuse, the normalized project label is platform-reserved, the normalized slug or hostname is already reserved, or quota blocks creation","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProjectCreateConflictResponse"},{"$ref":"#/components/schemas/QuotaBlockResponse"}]}}}},"503":{"description":"The workspace is creating another project and its lock wait exceeded 3 s; retry after Retry-After","content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["project-create-busy"]}}}}}}}}},"/projects/{id}":{"get":{"summary":"Get project","responses":{"200":{"description":"Project details"}}},"delete":{"summary":"Delete project after explicit slug confirmation and write pending-delete; provider cleanup runs on the pending-delete reconciler after the response","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDeleteRequest"}}}},"responses":{"202":{"description":"Project deletion accepted and hidden from project reads; the pending-delete reconciler, woken by this request, tears down provider resources and hard-deletes the project. Retrying an already pending deletion is accepted again."},"409":{"description":"Project deletion blocked by in-flight deployment work"}}}},"/projects/{id}/status":{"get":{"summary":"Get project status","responses":{"200":{"description":"Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectStatusResponse"}}}}}}},"/projects/{id}/dashboard":{"get":{"summary":"Read the Dashboard in one project-scoped snapshot","description":"Returns the resource map and telemetry overview from one authorized database read.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]}}],"responses":{"200":{"description":"Dashboard snapshot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDashboardResponse"}}}},"404":{"description":"Project not found or not visible to the caller"}}}},"/projects/{id}/resource-map":{"get":{"summary":"Get dashboard resource map","description":"Returns the member-safe resource topology for the dashboard canvas. Provider ids, provider bucket names, and provider default domains are not exposed.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dashboard resource map","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResourceMapResponse"}}}},"404":{"description":"Project not found or not visible to the caller"}}}},"/projects/{id}/diagnostics":{"get":{"summary":"Get tenant-safe project diagnostics","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project diagnostics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDiagnosticsResponse"}}}},"404":{"description":"Project not found or not visible to the caller"}}}},"/projects/{id}/settings":{"get":{"summary":"Read project Settings above-the-fold state","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project Settings screen model","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSettingsResponse"}}}}}}},"/projects/{id}/access-policy":{"get":{"summary":"Read project access policy","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project access policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAccessPolicyResponse"}}}}}},"patch":{"summary":"Update project access policy","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAccessPolicyRequest"}}}},"responses":{"200":{"description":"Updated project access policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAccessPolicyResponse"}}}},"400":{"description":"Invalid IP allowlist policy"},"403":{"description":"Owner or admin required"}}}},"/projects/{id}/app-source/folders":{"post":{"summary":"List repository folders for app source root selection","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceFoldersRequest"}}}},"responses":{"200":{"description":"Repository folder inventory","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceFoldersResponse"}}}},"400":{"description":"Invalid folder inventory request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"409":{"description":"Repository folder inventory unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}}}}},"/projects/{id}/app-source/detect":{"post":{"summary":"Discover bounded app Roots and the API-owned build route","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceDetectRequest"}}}},"responses":{"200":{"description":"Detected app source profile candidate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceResponse"}}}},"400":{"description":"Invalid app source detection request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}}}}},"/projects/{id}/app-source":{"post":{"summary":"Save the accepted app source profile","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceSaveRequest"}}}},"responses":{"200":{"description":"Saved app source profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceResponse"}}}},"400":{"description":"Invalid app source save request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"409":{"description":"App source detection or runtime policy blocks save, or the project source is locked (project-source-locked). runtime-detection-changed means the commit needs a runtime other than the stored one; resend with sourceBuildEngineChange {from: stored, to: detected} to switch. A direct-static-* reason is the stored runtime blocker when the detected runtime cannot deploy the commit either.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"422":{"description":"App source validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"503":{"description":"Workers builds are temporarily unavailable: the live Source Builder supply cannot yet detect the Workers runtime in the build Job (reason workers-detection-unavailable); nothing is saved","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableSourceBuildBlockerResponse"}}}}}}},"/projects/{id}/source-lock":{"put":{"summary":"Lock or unlock the project source (owner, panel session only)","description":"While locked, every change of the repository, branch, root directory or deployment mode is refused with 409 project-source-locked. Every lock, unlock and source change, applied or refused, is recorded as an immutable project source event and shown in project Activity.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSourceLockRequest"}}}},"responses":{"200":{"description":"Current source lock state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSourceLockResponse"}}}},"400":{"description":"locked is not a boolean (reason project-source-lock-invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSourceLockErrorResponse"}}}},"403":{"description":"The caller is not the project owner (reason project-source-lock-owner-required) or did not use a panel session (reason project-source-lock-panel-required); the attempt is recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSourceLockErrorResponse"}}}}}}},"/projects/{id}/app-repo":{"get":{"summary":"Get attached app repository and deploy defaults","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attached app repository","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoResponse"}}}}}},"post":{"summary":"Attach or replace the app repository and supplied deploy defaults","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoRequest"}}}},"responses":{"200":{"description":"Attached app repository","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoResponse"}}}},"400":{"description":"Invalid attach request, including a missing or unavailable repository, invalid deploy defaults, or deploymentMode (reason deployment-mode-not-settable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoInvalidResponse"}}}},"409":{"description":"Repository access is missing, the requested app repository branch is already attached to another active project, or the project source is locked (reason project-source-locked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoConflictResponse"}}}}}},"delete":{"summary":"Detach the app repository from the project","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Detached app repository","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppRepoResponse"}}}}}}},"/projects/{id}/incident":{"get":{"summary":"Get project incident visibility derived from deployment state and sanitized events","responses":{"200":{"description":"Incident summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectIncidentResponse"}}}}}}},"/projects/{id}/functions/{functionId}/secrets":{"get":{"summary":"List bound function secret names without reading values","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"functionId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Authorized function secret metadata","content":{"application/json":{"schema":{"type":"object","required":["projectId","functionId","secrets"],"properties":{"projectId":{"type":"string"},"functionId":{"type":"string"},"secrets":{"type":"array","items":{"type":"object","required":["id","key"],"properties":{"id":{"type":"string"},"key":{"type":"string"}}}}}}}}},"404":{"description":"Function not found or not accessible in this project"}}}},"/projects/{id}/env":{"put":{"summary":"Upsert resource-bound project secrets","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvUpsertRequest"}}}},"responses":{"200":{"description":"Updated env list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvResponse"}}}},"400":{"description":"Secret binding or restart decision is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"404":{"description":"Project or secret binding target not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"409":{"description":"Container restart cannot be queued while the target is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}}}},"get":{"summary":"List masked env vars","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Env list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvResponse"}}}}}}},"/projects/{id}/env/container-restarts":{"post":{"summary":"Queue no-build restarts for containers with stale secret startup env","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvContainerRestartRequest"}}}},"responses":{"200":{"description":"Container secret restarts queued or already current","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvContainerRestartResponse"}}}},"400":{"description":"Container ids are required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"404":{"description":"Container not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"409":{"description":"Container restart cannot be queued while the target is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}}}}},"/projects/{id}/env/{key}":{"delete":{"summary":"Delete one resource-bound project secret","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"key","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvDeleteRequest"}}}},"responses":{"200":{"description":"Updated env list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvResponse"}}}},"400":{"description":"Secret delete restart decision is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"404":{"description":"Project or secret not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}},"409":{"description":"Container restart cannot be queued while the target is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"}}}}}}},"/projects/{id}/containers":{"get":{"summary":"List project containers","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project container list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainersResponse"}}}}}},"post":{"summary":"Create a project container","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerRequest"}}}},"responses":{"201":{"description":"Created project container","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerResponse"}}}},"400":{"description":"Container runtime tier and hardware fields are server-owned and not configurable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerConfigErrorResponse"}}}},"409":{"description":"Quota blocks container creation before a resource row is created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaBlockResponse"}}}}}}},"/projects/{id}/containers/source/detect":{"post":{"summary":"Detect container source fields from the selected Git repository","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceDetectRequest"}}}},"responses":{"200":{"description":"Detected container source candidate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerSourceDetectionResponse"}}}},"400":{"description":"Invalid container source detection request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"409":{"description":"Repository access unavailable for container source detection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}}}}},"/projects/{id}/containers/{containerId}/metrics":{"get":{"summary":"Read one project container metrics model","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"],"default":"24h"}}],"responses":{"200":{"description":"Project container traffic, runtime usage, and latest signals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerMetricsResponse"}}}},"404":{"description":"Project or container not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerMetricsErrorResponse"}}}}}}},"/projects/{id}/containers/{containerId}":{"get":{"summary":"Read one project container","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project container detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerResponse"}}}}}},"patch":{"summary":"Update one project container","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerRequest"}}}},"responses":{"200":{"description":"Updated project container","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerResponse"}}}},"400":{"description":"Container runtime tier and hardware fields are server-owned and not configurable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerConfigErrorResponse"}}}},"409":{"description":"Existing unmanaged container cannot be edited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerDeployConflictResponse"}}}}}},"delete":{"summary":"Delete one project container","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Remaining project containers after delete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainersResponse"}}}},"409":{"description":"Container delete is blocked by an in-flight deploy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerDeleteConflictResponse"}}}},"502":{"description":"Provider cleanup did not complete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerDeleteConflictResponse"}}}}}}},"/projects/{id}/containers/{containerId}/stop":{"post":{"summary":"Stop serving one project container; its configuration, revision and hostname stay","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Container serving state (ADR 0104); changed is false when it already had this state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerServingResponse"}}}},"404":{"description":"Project container not found (reason container-not-found)"},"409":{"description":"Container is being deleted (container-delete-in-flight) or was never deployed (container-not-deployed)"}}}},"/projects/{id}/containers/{containerId}/start":{"post":{"summary":"Serve one stopped project container again with the same revision and hostname","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Container serving state (ADR 0104); changed is false when it already had this state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerServingResponse"}}}},"404":{"description":"Project container not found (reason container-not-found)"},"409":{"description":"Container is being deleted (container-delete-in-flight) or was never deployed (container-not-deployed)"}}}},"/projects/{id}/containers/{containerId}/deploy":{"post":{"summary":"Deploy one project container","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"containerId","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Deployed project container","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContainerDeployResponse"}}}},"409":{"description":"Container deploy is blocked by quota or by a recoverable project or provider state","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerDeployConflictResponse"},{"$ref":"#/components/schemas/QuotaBlockResponse"}]}}}},"503":{"description":"Quota evidence is temporarily unavailable; quota-state-unavailable confirms restoration, while quota-recovery-unavailable means atomic restoration did not commit and internal convergence is still required; no deployment or job is created","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableContainerQuotaBlockerResponse"}}}}}}},"/projects/{id}/storage":{"get":{"summary":"List real project storage buckets","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"},"description":"Opaque page cursor returned as nextCursor."},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Storage object list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectStorageListResponse"}}}}}}},"/projects/{id}/storage/preview-backfill":{"post":{"summary":"Backfill a bounded page of storage previews","description":"Owner/admin-only maintenance action. Processes at most 10 eligible ready objects and 50 MiB of original source bytes sequentially without creating a queue, Job, trigger, or Cron.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Bounded preview backfill result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoragePreviewBackfillResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Owner/admin access required"},"409":{"description":"Project or preview generation is not mutable"}}}},"/projects/{id}/storage/buckets":{"post":{"summary":"Create a real storage bucket for a project","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStorageBucketRequest"}}}},"responses":{"201":{"description":"Created storage bucket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageBucketResponse"}}}},"409":{"description":"A bucket with that name already exists or quota blocks bucket creation before provider provisioning","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/StorageBucketConflictResponse"},{"$ref":"#/components/schemas/QuotaBlockResponse"}]}}}}}}},"/projects/{id}/functions":{"get":{"summary":"List project-owned functions","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":50}}],"responses":{"200":{"description":"Function list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectFunctionsResponse"}}}}}},"post":{"summary":"Create one managed project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionCreateRequest"}}}},"responses":{"201":{"description":"Created function","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionMutationResponse"}}}},"409":{"description":"Quota blocks function creation before a function row is created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaBlockResponse"}}}}}}},"/projects/{id}/functions/{functionId}":{"get":{"summary":"Get one project-scoped function plus deployment history","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"functionId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionResponse"}}}}}}},"/projects/{id}/functions/{functionId}/status":{"get":{"summary":"Get lightweight API-owned function status and route convergence","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"functionId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function status projection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionStatusResponse"}}}},"404":{"description":"Function not found or not visible in the project"}}}},"/projects/{id}/functions/{functionId}/metrics":{"get":{"summary":"Get tenant-safe Function Overview metrics","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"functionId","required":true,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["15m","1h","3h","1d"],"default":"15m"}}],"responses":{"200":{"description":"Function Overview metrics projection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionMetricsResponse"}}}},"404":{"description":"Function not found or not visible in the project"}}}},"/projects/{id}/logs":{"get":{"summary":"List centralized project log rows with recent-history filters","description":"Returns the authoritative bounded row page and DB revision without computing exact retained-window statistics. Each query returns the newest matching rows, newest first. Load older through the stable timestamp-and-ID cursor; there is no total or offset.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"assetType","required":false,"schema":{"type":"string","enum":["app","service","function","deployment","container","runtime","storage","static"]}},{"in":"query","name":"assetId","required":false,"schema":{"type":"string"}},{"in":"query","name":"deploymentId","required":false,"schema":{"type":"string"}},{"in":"query","name":"invocationId","required":false,"schema":{"type":"string"}},{"in":"query","name":"severity","required":false,"schema":{"type":"string","enum":["info","warning","error"]},"description":"Severity filter (`info|warning|error`)."},{"in":"query","name":"statusClass","required":false,"schema":{"type":"string","enum":["2xx","3xx","4xx","5xx"]}},{"in":"query","name":"method","required":false,"schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]}},{"in":"query","name":"statusCode","required":false,"schema":{"type":"integer","minimum":100,"maximum":599}},{"in":"query","name":"pathClass","required":false,"schema":{"type":"string"}},{"in":"query","name":"excludePaths","required":false,"schema":{"type":"string"},"description":"Space-separated exact request paths (each starting with `/`, at most 10) whose rows are hidden."},{"in":"query","name":"hideBlocked","required":false,"schema":{"type":"string","enum":["1"]},"description":"When `1`, hides requests the Mini WAF blocked (`gateway_path_rule_blocked`)."},{"in":"query","name":"requestId","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceNetwork","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceIp","required":false,"schema":{"type":"string"}},{"in":"query","name":"category","required":false,"schema":{"type":"string","enum":["activity","access","runtime","deploy","build","function","storage"]}},{"in":"query","name":"view","required":false,"schema":{"type":"string","enum":["deployments","http","containers","functions","storage"]},"description":"Overlapping product view. Omit for All channels."},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["1h","24h","7d","30d"]}},{"in":"query","name":"from","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"},"description":"Canonical UTC millisecond ISO timestamp, for example `2026-06-11T11:00:00.000Z`."},{"in":"query","name":"to","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"},"description":"Canonical UTC millisecond ISO timestamp, exclusive upper bound."},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"},"description":"Opaque nextCursor from the preceding page with the same filters."},{"in":"query","name":"search","required":false,"schema":{"type":"string","maxLength":240},"description":"Case-insensitive text terms matched server-side before pagination."}],"responses":{"200":{"description":"Project log console entries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectLogsResponse"}}}}}}},"/projects/{id}/logs/assets":{"get":{"summary":"Search the project log asset catalog","description":"Returns at most 50 assets from the DB-owned stable catalog of assets present in the project retention, independent of log filters. The selected asset is resolved separately and always visible. The cursor is bound to the project and the normalized search. Beyond admission the endpoint returns 429 with Retry-After and never 503 from queue exhaustion.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"assetQuery","required":false,"schema":{"type":"string","maxLength":120}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"in":"query","name":"assetType","required":false,"schema":{"type":"string","enum":["app","service","function","deployment","container","runtime","storage","static"]}},{"in":"query","name":"assetId","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Bounded project log asset search page","content":{"application/json":{"schema":{"type":"object","required":["assets","selected","nextCursor","hasMore"],"properties":{"assets":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ProjectLogAsset"}},"selected":{"oneOf":[{"$ref":"#/components/schemas/ProjectLogAsset"},{"type":"null"}]},"nextCursor":{"type":["string","null"]},"hasMore":{"type":"boolean"}}}}}},"400":{"description":"Invalid filter or cursor"},"401":{"description":"Unauthenticated or expired session"},"404":{"description":"Project not found"},"429":{"description":"Project logs admission capacity exceeded"}}}},"/projects/{id}/logs/stream":{"get":{"summary":"Authenticated SSE stream for centralized project log rows","description":"Emits an authoritative project_logs_snapshot with DB revision on open, reconnect, unrecoverable history gaps, model/retention changes, and late arrival. Append revisions emit project_logs_rows deltas; bursts are read in 50-row cursor pages up to the existing stream delivery capacity. The Logs page never requests exact statistics. Authorization renews with a bounded five-minute lease; the stream never polls as a fallback.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"assetType","required":false,"schema":{"type":"string"}},{"in":"query","name":"assetId","required":false,"schema":{"type":"string"}},{"in":"query","name":"deploymentId","required":false,"schema":{"type":"string"}},{"in":"query","name":"invocationId","required":false,"schema":{"type":"string"}},{"in":"query","name":"severity","required":false,"schema":{"type":"string"}},{"in":"query","name":"statusClass","required":false,"schema":{"type":"string"}},{"in":"query","name":"method","required":false,"schema":{"type":"string"}},{"in":"query","name":"pathClass","required":false,"schema":{"type":"string"}},{"in":"query","name":"excludePaths","required":false,"schema":{"type":"string"}},{"in":"query","name":"hideBlocked","required":false,"schema":{"type":"string"}},{"in":"query","name":"requestId","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceNetwork","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceIp","required":false,"schema":{"type":"string"}},{"in":"query","name":"category","required":false,"schema":{"type":"string"}},{"in":"query","name":"view","required":false,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string"}},{"in":"query","name":"from","required":false,"schema":{"type":"string"}},{"in":"query","name":"to","required":false,"schema":{"type":"string"}},{"in":"query","name":"search","required":false,"schema":{"type":"string"}},{"in":"query","name":"statusCode","required":false,"schema":{"type":"integer"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"SSE stream of revisioned row snapshots and bounded deltas"},"401":{"description":"Unauthenticated or expired session"},"403":{"description":"Project access revoked"},"429":{"description":"Per-pod stream capacity exceeded","headers":{"Retry-After":{"schema":{"type":"string","enum":["1"]}}}}}}},"/projects/{id}/logs/summary":{"get":{"summary":"Read recent project log counts for the current filters","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"assetType","required":false,"schema":{"type":"string","enum":["app","service","function","deployment","container","runtime","storage","static"]}},{"in":"query","name":"assetId","required":false,"schema":{"type":"string"}},{"in":"query","name":"deploymentId","required":false,"schema":{"type":"string"}},{"in":"query","name":"invocationId","required":false,"schema":{"type":"string"}},{"in":"query","name":"severity","required":false,"schema":{"type":"string","enum":["info","warning","error"]}},{"in":"query","name":"statusClass","required":false,"schema":{"type":"string","enum":["2xx","3xx","4xx","5xx"]}},{"in":"query","name":"method","required":false,"schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]}},{"in":"query","name":"statusCode","required":false,"schema":{"type":"integer","minimum":100,"maximum":599}},{"in":"query","name":"pathClass","required":false,"schema":{"type":"string"}},{"in":"query","name":"excludePaths","required":false,"schema":{"type":"string"},"description":"Space-separated exact request paths (each starting with `/`, at most 10) whose rows are hidden."},{"in":"query","name":"hideBlocked","required":false,"schema":{"type":"string","enum":["1"]},"description":"When `1`, hides requests the Mini WAF blocked (`gateway_path_rule_blocked`)."},{"in":"query","name":"requestId","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceNetwork","required":false,"schema":{"type":"string"}},{"in":"query","name":"sourceIp","required":false,"schema":{"type":"string"}},{"in":"query","name":"category","required":false,"schema":{"type":"string","enum":["activity","access","runtime","deploy","build","function","storage"]}},{"in":"query","name":"view","required":false,"schema":{"type":"string","enum":["deployments","http","containers","functions","storage"]},"description":"Overlapping product view. Omit for All channels."},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["1h","24h","7d","30d"]}},{"in":"query","name":"from","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"},"description":"Canonical UTC millisecond ISO timestamp, for example `2026-06-11T11:00:00.000Z`."},{"in":"query","name":"to","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"},"description":"Canonical UTC millisecond ISO timestamp, exclusive upper bound."},{"in":"query","name":"revision","required":false,"schema":{"type":"string","pattern":"^\\d+$"},"description":"Optional legacy page revision. Concurrent writes do not invalidate a summary; the response carries its own DB snapshot revision."},{"in":"query","name":"temporalEpoch","required":false,"schema":{"type":"integer","minimum":0},"description":"Shared relative-window epoch returned by the page. Omit for exact from/to windows."}],"responses":{"200":{"description":"Project log summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectLogsSummaryResponse"}}}}}}},"/projects/{id}/usage":{"get":{"summary":"Read project-scoped usage counters","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"billingMonth","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}(-\\d{2})?$"},"description":"Reads a closed billing month when supplied; omitted reads the current month."}],"responses":{"200":{"description":"Project usage summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUsageResponse"}}}}}}},"/projects/{id}/telemetry/overview":{"get":{"summary":"Read project-scoped telemetry overview for the dashboard","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]}}],"responses":{"200":{"description":"Project telemetry overview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectTelemetryOverviewResponse"}}}}}}},"/projects/{id}/telemetry/families/{family}":{"get":{"summary":"Read one project telemetry family detail view","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"family","required":true,"schema":{"type":"string","enum":["deployment_traffic","container_traffic","function_host_traffic","storage_activity"]}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]}}],"responses":{"200":{"description":"Project telemetry family detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectTelemetryFamilyResponse"}}}}}}},"/functions/{id}":{"patch":{"summary":"Update one managed project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionUpdateRequest"}}}},"responses":{"200":{"description":"Updated function","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionMutationResponse"}}}}}},"delete":{"summary":"Delete one project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted function","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionMutationResponse"}}}}}}},"/functions/{id}/logs":{"get":{"summary":"Read centralized logs for one project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"severity","required":false,"schema":{"type":"string","enum":["info","warning","error"]}},{"in":"query","name":"category","required":false,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":50}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function log console entries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionProjectLogsResponse"}}}}}}},"/functions/{id}/invocations":{"get":{"summary":"Read recent invocation records for one project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"timeRange","required":false,"schema":{"type":"string","enum":["30m","6h","24h","7d"]}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Function invocation records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionInvocationsResponse"}}}}}}},"/functions/{id}/deployments":{"get":{"summary":"List deployments for one project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"in":"query","name":"cursor","schema":{"type":"string"}}],"responses":{"200":{"description":"Function deployment list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionDeploymentsResponse"}}}}}},"post":{"summary":"Deploy one managed project function","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Function deployment finished","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionDeploymentResponse"}}}},"409":{"description":"Quota blocks function deployment before deployment or job rows are created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaBlockResponse"}}}},"503":{"description":"Quota evidence is temporarily unavailable; the Function is unchanged and no deployment is created","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableQuotaStateBlockerResponse"}}}}}}},"/functions/{id}/deployments/{deploymentId}/rollback":{"post":{"summary":"Roll back an HTTP Function to its exact previous ESZip artifact","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"202":{"description":"Exact previous artifact accepted as a new immutable deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionDeploymentResponse"}}}},"400":{"description":"Idempotency-Key is missing or invalid"},"409":{"description":"The target is not the exact previous deployment or Function runtime work is in progress"}}}},"/projects/{id}/api-key":{"get":{"summary":"Get one project API key summary","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project API key summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectApiKeyResponse"}}}}}},"post":{"summary":"Create one Eurobase project key and reveal it","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Project API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectApiKeyRevealResponse"}}}}}},"delete":{"summary":"Revoke one project API key","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project API key revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectApiKeyResponse"}}}}}}},"/projects/{id}/api-key/reveal":{"post":{"summary":"Reveal the active Eurobase project key","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project API key revealed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectApiKeyRevealResponse"}}}}}}},"/projects/{id}/api-key/rotate":{"post":{"summary":"Rotate one Eurobase project key and reveal it","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Project API key rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectApiKeyRevealResponse"}}}}}}},"/function-deployments/{id}/logs":{"get":{"summary":"Read recent logs for one function deployment","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function deployment logs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionLogsResponse"}}}}}}},"/internal/gateway/access-evidence/settle":{"post":{"summary":"Settle one page of Gateway Access evidence set-based in one DB transaction (ADR 0087 R4)","description":"The body is passed to the DB unchanged. Every record gets its own ADR 0078 verdict, bound to the SHA-256 of the exact page bytes; settled members are finalized in the same transaction.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAccessEvidencePage"}}}},"responses":{"200":{"description":"One verdict per record, in page order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAccessEvidencePageAnswer"}}}},"401":{"description":"Gateway Access settlement token is invalid"},"422":{"description":"The page is not a gateway-access-evidence.v2 page of the token store, or its bytes cannot settle whole (gateway-access-evidence-page-unsettleable); nothing was settled"},"503":{"description":"Settlement is unavailable or over its deadline; the page stays in the Gateway WAL and is retried"}}}},"/internal/gateway/blocks/settle":{"post":{"summary":"Apply one frozen page of grouped Mini WAF blocks exactly once (ADR 0109)","description":"The body is passed to the DB unchanged. A page holds up to 80 items: up to 70 groups (one blocked path, project and minute with its exact count and up to 50 client IPs) and drop counts. Each item is validated and its route ownership checked; accepted groups become one Logs row each in the blocked retention category. A retried page answers its stored outcome and writes nothing; the same page id with other bytes is a conflict.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["schemaVersion","storeUid","pageId","groups","drops"],"additionalProperties":false,"properties":{"schemaVersion":{"type":"string","enum":["gateway-blocks-page.v1"]},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"pageId":{"type":"string","pattern":"^[0-9a-f]{64}$"},"groups":{"type":"array","maxItems":70,"items":{"type":"object"}},"drops":{"type":"array","maxItems":10,"items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The page outcome: settled with one result per item in page order (replay true for a retried page), or conflict when the page id was already used with other bytes","content":{"application/json":{"schema":{"type":"object","required":["schemaVersion","storeUid","pageId","bodySha256","status"],"properties":{"schemaVersion":{"type":"string","enum":["gateway-blocks-page.v1"]},"storeUid":{"type":"string"},"pageId":{"type":"string"},"bodySha256":{"type":"string"},"status":{"type":"string","enum":["settled","conflict"]},"replay":{"type":"boolean"},"reason":{"type":"string"},"results":{"type":"array","items":{"type":"object","required":["index","kind","outcome"],"properties":{"index":{"type":"integer","minimum":0},"kind":{"type":"string","enum":["group","drop"]},"outcome":{"type":"string","enum":["accepted","rejected","project-deleted"]},"reason":{"type":"string"}}}}}}}}},"401":{"description":"Gateway blocks settlement token is invalid, or the body is not the one it names"},"422":{"description":"The page is not a gateway-blocks-page.v1 page of the token store within its bounds, or of a store the DB did not register (gateway-blocks-page-invalid); nothing was written and the Gateway parks the page"},"503":{"description":"Settlement is unavailable or over its deadline; the page stays in the Gateway WAL and is retried"}}}},"/internal/gateway/evidence-sequences/reserve":{"post":{"summary":"Reserve one immutable DB-owned gateway evidence sequence range","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalGatewayEvidenceSequenceRequest"}}}},"responses":{"200":{"description":"The immutable sequence reservation receipt, including exact retained-row supersessions when authorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalGatewayEvidenceSequenceResponse"}}}},"401":{"description":"Gateway sequence token is invalid or expired"},"403":{"description":"Gateway sequence token does not own the requested reservation"},"409":{"description":"The reservation or authorized retained-row sequence proof conflicts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayEvidenceConflictResponse"}}}},"422":{"description":"Gateway sequence reservation or recovery identity is invalid"}}}},"/storage-buckets/{bucketId}":{"get":{"summary":"List objects in one storage bucket","parameters":[{"in":"path","name":"bucketId","required":true,"schema":{"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Storage bucket object list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectStorageListResponse"}}}}}},"patch":{"summary":"Update one storage bucket","parameters":[{"in":"path","name":"bucketId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStorageBucketRequest"}}}},"responses":{"200":{"description":"Updated storage bucket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageBucketResponse"}}}},"400":{"description":"Storage bucket update payload invalid"},"403":{"description":"Project role cannot update storage bucket"},"404":{"description":"Storage bucket not found"},"409":{"description":"Storage bucket is not ready or project cannot be mutated"}}},"delete":{"summary":"Delete one storage bucket","parameters":[{"in":"path","name":"bucketId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"recursive":{"type":"boolean"},"confirmName":{"type":"string"}}}}}},"responses":{"200":{"description":"Deleted storage bucket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageBucketResponse"}}}},"400":{"description":"Recursive bucket delete payload invalid or confirmation missing or mismatched"},"409":{"description":"Non-empty bucket requires recursive confirmation"},"502":{"description":"Provider bucket cleanup failed"}}}},"/storage-buckets/{bucketId}/upload-batches":{"post":{"summary":"Reserve up to 20 object uploads under one quota admission lock","description":"Each returned short-lived capability writes only its reserved staging object in private Object Storage. Completion separately verifies and publishes each file.","parameters":[{"in":"path","name":"bucketId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectStorageUploadBatchRequest"}}}},"responses":{"201":{"description":"Ordered upload sessions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectStorageUploadBatchResponse"}}}},"400":{"description":"Invalid batch, filename, size, MIME, or checksum"},"409":{"description":"Bucket is unavailable, object key conflicts, or quota blocks admission"},"503":{"description":"Quota evidence or provider upload policy is unavailable"}}}},"/storage-buckets/{bucketId}/uploads/{uploadId}/complete":{"post":{"summary":"Verify an uploaded object and mark it ready","parameters":[{"in":"path","name":"bucketId","required":true,"schema":{"type":"string"}},{"in":"path","name":"uploadId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Completed storage upload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectResponse"}}}},"400":{"description":"Stored object metadata does not match the reserved upload session"},"403":{"description":"Requester no longer has owner/admin access or token scope is invalid"},"404":{"description":"Storage upload not found"},"409":{"description":"Upload session is not pending or bucket is not ready"},"500":{"description":"Upload reservation cleanup failed after provider validation failure"},"502":{"description":"Provider validation failed after reservation cleanup"},"503":{"description":"Quota or storage accounting evidence is temporarily unavailable; no ready upload success is returned","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableStorageBlockerResponse"}}}}}}},"/storage-objects/{id}":{"get":{"summary":"Get one storage object","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Storage object","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectResponse"}}}}}},"delete":{"summary":"Delete one storage object","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted storage object","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectResponse"}}}}}}},"/storage-objects/{id}/read-url":{"post":{"summary":"Create a signed storage object read URL","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Signed storage object read URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStorageObjectReadUrlResponse"}}}},"403":{"description":"Project public serving is suspended (reason project_suspended, ADR 0080)"}}}},"/storage-objects/{id}/preview":{"get":{"summary":"Read the current authenticated storage preview derivative","description":"Rechecks project membership and current preview generation, then returns at most 256 KiB of verified WebP bytes with private no-store caching. It never returns original object bytes or a provider URL.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verified storage preview derivative","headers":{"Cache-Control":{"schema":{"type":"string","enum":["private, no-store, max-age=0"]}}},"content":{"image/webp":{"schema":{"type":"string","format":"binary","maxLength":262144}}}},"401":{"description":"Authentication required"},"404":{"description":"Storage object not found or inaccessible"},"409":{"description":"Current preview generation is not ready"},"503":{"description":"Stored derivative is unavailable or fails verification"}}}},"/storage-objects/{id}/preview-retry":{"post":{"summary":"Retry one failed or missing storage preview","description":"Owner/admin-only retry. Direct uploads requeue the DB-owned preview job; legacy uploads use the bounded private transformer.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Storage preview retry result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Owner/admin access required"},"404":{"description":"Storage object not found"},"409":{"description":"Preview is in progress, deleting, or not eligible"},"502":{"description":"Original source read failed"}}}},"/storage-objects/{id}/content":{"get":{"summary":"Redirect a public object to its canonical filename URL or read a private signed object","description":"Anonymous ready public reads permanently redirect to the canonical filename-bearing URL without bandwidth accounting. A valid signed token returns a private attachment directly.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"token","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Private signed storage object bytes","headers":{"Content-Disposition":{"schema":{"type":"string"},"description":"Attachment disposition carrying the API-owned object-key basename"}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"308":{"description":"Ready public object canonical filename redirect; no object bytes are read or accounted","headers":{"Location":{"schema":{"type":"string","format":"uri"}},"Cache-Control":{"schema":{"type":"string","enum":["public, max-age=300"]}}}},"401":{"description":"Private object read token required (storage-read-token-required), invalid (storage-read-token-invalid), or expired (storage-read-token-expired)"},"403":{"description":"Signed read token rejected, or project public serving is suspended (reason project_suspended, ADR 0080)"},"404":{"description":"Storage object not found"},"409":{"description":"Read bandwidth quota blocks the content fetch before provider bytes are requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaBlockResponse"}}}},"500":{"description":"Ready object metadata cannot produce a valid canonical filename","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectMetadataInvalidResponse"}}}},"503":{"description":"Quota or storage accounting evidence is temporarily unavailable; no response body bytes are returned","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableStorageBlockerResponse"}}}}}}},"/storage-objects/{id}/content/{filename}":{"get":{"summary":"Read public storage object content from its canonical filename URL","description":"Returns ready public raster images and PDFs inline and other public types as attachments. The encoded filename must exactly match the API-owned object-key basename; aliases and tokenized requests are rejected before accounting or provider access.","security":[],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"filename","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Public storage object bytes","headers":{"Content-Disposition":{"schema":{"type":"string"},"description":"Inline or attachment disposition carrying the API-owned object-key basename"}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Object, canonical filename, or anonymous public route not found"},"409":{"description":"Read bandwidth quota blocks the content fetch before provider bytes are requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaBlockResponse"}}}},"500":{"description":"Ready object metadata cannot produce a valid canonical filename","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageObjectMetadataInvalidResponse"}}}},"503":{"description":"Quota or storage accounting evidence is temporarily unavailable; no response body bytes are returned","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryableStorageBlockerResponse"}}}}}}},"/deployments":{"post":{"summary":"Redeploy source and deploy","description":"Queues a source deployment for a project. For the first release, appSource and startupSecrets atomically commit with the deployment and initial job before provider dispatch. When sourceDeploymentId is provided, Eurobase rereads bounded root/direct-static evidence at the resolved lineage deployment immutable commit and freezes a new direct-static-v1 or paketo-v1 route. The deployment action key is persisted on the created deployment row and replayed before source validation, quota, or in-flight checks.","security":[{"bearerAuth":[]},{"sessionCookie":[],"csrfHeader":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"description":"Stable key reused when the action response is uncertain."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentCreateRequest"}}}},"responses":{"201":{"description":"Deployment and initial pending build job persisted before external dispatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentActionResponse"}}}},"400":{"description":"Invalid deploy request, including a runtime change combined with sourceDeploymentId or appSource (reason source-build-engine-change-invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}}}},"404":{"description":"Source deployment not found for this project or caller"},"409":{"description":"Project source is not attached yet, selected source deployment cannot be redeployed, a visible non-terminal deployment is already in progress, the action key was reused for a different selected source, quota blocks deployment, or the commit needs a runtime other than the stored one (runtime-detection-changed, a direct-static-* stored-runtime blocker, workers-v1-admission-disabled or workers-v1-build-unavailable); a runtime refusal creates no deployment or job","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/DeploymentConflictResponse"},{"$ref":"#/components/schemas/QuotaBlockResponse"},{"$ref":"#/components/schemas/ProjectAppSourceErrorResponse"}]}}}},"503":{"description":"Quota evidence or the Jobs source-build release is temporarily unavailable, including a supply whose build Job cannot yet detect the Workers runtime (reason workers-detection-unavailable); no deployment or job is created","headers":{"Cache-Control":{"schema":{"type":"string","enum":["no-store"]}},"Retry-After":{"schema":{"type":"string","enum":["2"]}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RetryableQuotaStateBlockerResponse"},{"$ref":"#/components/schemas/RetryableSourceBuildBlockerResponse"}]}}}}}},"get":{"summary":"List deployments","description":"Returns API-owned deployment projection fields including machine displayStatus, browser statusView, freshness, stale, terminal, visible, lastObservedAt, and statusReason.","responses":{"200":{"description":"Deployment list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentsResponse"}}}}}}},"/deployments/{id}":{"get":{"summary":"Get deployment","description":"Returns one deployment including raw status plus API-owned machine displayStatus, browser statusView, freshness metadata, and an optional sanitized failureSummary derived from deployment events.","responses":{"200":{"description":"Deployment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentResponse"}}}}}}},"/deployments/{id}/preview":{"get":{"summary":"Read an authenticated project-member deployment preview image","responses":{"200":{"description":"Preview image bytes","content":{"image/webp":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing or invalid session"},"403":{"description":"Project role, asset scope, or current-deployment eligibility rejected"},"404":{"description":"Preview missing or not visible to the authenticated user"}}}},"/deployments/{id}/preview-capture":{"post":{"summary":"Queue a same-deployment preview re-capture","responses":{"202":{"description":"Preview capture accepted; provider correlation may still be pending"},"409":{"description":"Preview capture disabled, ineligible, or already in progress"}}}},"/deployments/{id}/logs":{"get":{"summary":"Get deployment logs by channel (API-owned, sanitized)","parameters":[{"name":"logKind","in":"query","required":false,"schema":{"type":"string","enum":["build","deploy","runtime","event"]},"description":"Optional log channel filter. Omit to read the retained deployment log set. Invalid values return 400 invalid-log-kind."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"Maximum retained rows returned per projected log kind (build, deploy, event, runtime) for this bounded deployment activity read; each kind is its newest gap-free window."}],"responses":{"200":{"description":"Deployment log stream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentLogsResponse"}}}},"400":{"description":"Invalid logKind filter or limit"}}}},"/deployments/{id}/logs/stream":{"get":{"summary":"Authenticated SSE stream for persisted deployment log snapshots, live rows, and status","description":"Emits deployment_logs_snapshot events with entries/cursor/streamState, deployment_logs_event events with one sanitized DeploymentLogEntry, and deployment_logs_status events with streamState plus per-kind streamStates. Optional logKind filters snapshots and live rows to one deployment activity channel. Invalid logKind or limit values return 400 before the SSE stream opens. Snapshot events do not include the legacy concatenated logs string.","parameters":[{"name":"logKind","in":"query","required":false,"schema":{"type":"string","enum":["build","deploy","runtime","event"]},"description":"Optional live stream channel filter."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"Maximum persisted snapshot rows per projected log kind sent before live events; each kind is its newest gap-free window."}],"responses":{"200":{"description":"SSE stream of deployment log snapshots, live events, and stream status","content":{"text/event-stream":{"schema":{"oneOf":[{"$ref":"#/components/schemas/DeploymentLogStreamSnapshot"},{"$ref":"#/components/schemas/DeploymentLogStreamEvent"},{"$ref":"#/components/schemas/DeploymentLogStreamStatus"}]}}}},"400":{"description":"Invalid logKind filter"},"401":{"description":"Unauthenticated"},"403":{"description":"Deployment is not visible to the caller"},"404":{"description":"Deployment not found"}}}},"/deployments/{id}/promote":{"post":{"summary":"Deploy the selected terminal deployment output without rebuilding source","security":[{"bearerAuth":[]},{"sessionCookie":[],"csrfHeader":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"description":"Stable key reused when the action response is uncertain."}],"responses":{"201":{"description":"Deployment and deploy job persisted before external dispatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentActionResponse"}}}},"409":{"description":"A visible non-terminal deployment is already in progress for the project, or the action key was reused for a different selected source","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentConflictResponse"}}}}}}},"/deployments/{id}/rollback":{"post":{"summary":"Rollback to selected deployment output","security":[{"bearerAuth":[]},{"sessionCookie":[],"csrfHeader":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"description":"Stable key reused when the action response is uncertain."}],"responses":{"201":{"description":"Deployment and rollback job persisted before external dispatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentActionResponse"}}}},"409":{"description":"A visible non-terminal deployment is already in progress for the project, or the action key was reused for a different selected source","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentConflictResponse"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"sessionCookie":{"type":"apiKey","in":"cookie","name":"__Host-eurobase_session"},"csrfHeader":{"type":"apiKey","in":"header","name":"X-Eurobase-CSRF"}},"schemas":{"DeploymentActionResponse":{"type":"object","required":["deployment","job"],"properties":{"deployment":{"type":"object","required":["id","projectId","status","terminal","statusView"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"status":{"type":"string"},"terminal":{"type":"boolean"},"statusReason":{"type":["string","null"]},"statusView":{"type":"object","required":["primaryLabel","tone"],"properties":{"primaryLabel":{"type":"string"},"secondaryLabel":{"type":["string","null"]},"tone":{"type":"string"}}}}},"job":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"type":{"type":["string","null"]}}}}},"BuildDeployManifest":{"oneOf":[{"type":"object","required":["schemaVersion","deploymentId","outputKind","source","build","runtime","handoff"],"properties":{"schemaVersion":{"const":"app-deploy-manifest-paketo-v1"},"deploymentId":{"type":"string"},"outputKind":{"const":"runtime_image"},"source":{"type":"object","required":["repoFullName","commitSha","rootDir"],"properties":{"repoFullName":{"type":"string"},"commitSha":{"type":"string","pattern":"^[a-f0-9]{40}$"},"rootDir":{"type":"string"},"framework":{"type":"string","enum":["next","astro","svelte-kit","nuxt","react-router","vite","hono","nestjs","fastify","express","django","fastapi","flask","laravel","rails","node","python","php","ruby","go","java","dotnet","static","unknown"]}},"additionalProperties":false},"build":{"type":"object","required":["engine","policyVersion","policyHash","platform","builderImage","lifecycleImage","runImage","bootstrapImage","publisherVersion","publisherSha256","buildpackSetHash","profileHash","overlayHash","phaseTimingsMs"],"properties":{"engine":{"const":"paketo-v1"},"policyVersion":{"type":"string"},"policyHash":{"type":"string"},"platform":{"type":"string"},"builderImage":{"type":"string"},"lifecycleImage":{"type":"string"},"runImage":{"type":"string"},"bootstrapImage":{"type":"string"},"publisherVersion":{"type":"string"},"publisherSha256":{"type":"string"},"buildpackSetHash":{"type":"string"},"profileHash":{"type":"string"},"overlayHash":{"type":"string"},"phaseTimingsMs":{"oneOf":[{"type":"object","required":["supplyVerificationMs","sourceAcquisitionMs","sourceBoundaryMs","isolationStartupMs","planningMs","buildkitSolveAndRuntimeAssemblyMs","egressValidationMs","workerReleaseMs","imageArchiveLoadMs","registryAuthMs","registryPushMs","digestReadbackMs","publicationOverheadMs","cleanupMs","builderOverheadMs","builderTotalMs"],"properties":{"supplyVerificationMs":{"type":"integer","minimum":0},"sourceAcquisitionMs":{"type":"integer","minimum":0},"sourceBoundaryMs":{"type":"integer","minimum":0},"isolationStartupMs":{"type":"integer","minimum":0},"planningMs":{"type":"integer","minimum":0},"buildkitSolveAndRuntimeAssemblyMs":{"type":"integer","minimum":0},"egressValidationMs":{"type":"integer","minimum":0},"workerReleaseMs":{"type":"integer","minimum":0},"imageArchiveLoadMs":{"type":"integer","minimum":0},"registryAuthMs":{"type":"integer","minimum":0},"registryPushMs":{"type":"integer","minimum":0},"digestReadbackMs":{"type":"integer","minimum":0},"publicationOverheadMs":{"type":"integer","minimum":0},"cleanupMs":{"type":"integer","minimum":0},"builderOverheadMs":{"type":"integer","minimum":0},"builderTotalMs":{"type":"integer","minimum":0}},"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"runtime":{"type":"object","required":["imageRef","imageDigest","port","healthPath"],"properties":{"imageRef":{"type":"string"},"imageDigest":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"port":{"type":"integer","minimum":1,"maximum":65535},"healthPath":{"type":"string"}},"additionalProperties":false},"handoff":{"type":"object","required":["dispatchAttemptId","sourceSnapshotSha256"],"properties":{"dispatchAttemptId":{"type":"string"},"sourceSnapshotSha256":{"type":"string","pattern":"^(?:sha256:)?[a-f0-9]{64}$"}},"additionalProperties":false}},"additionalProperties":false},{"type":"object","required":["schemaVersion","deploymentId","outputKind","framework","source","static"],"properties":{"schemaVersion":{"type":"string","enum":["app-deploy-manifest-v1"]},"deploymentId":{"type":"string"},"outputKind":{"type":"string","enum":["static_artifact"]},"framework":{"type":"string"},"source":{"type":"object","required":["repoFullName","commitSha","rootDir"],"properties":{"repoFullName":{"type":"string"},"commitSha":{"type":"string"},"rootDir":{"type":"string"}},"additionalProperties":false},"static":{"type":"object","required":["artifactType","artifactRef","artifactSha256","publishDirectory","fileCount","byteCount","entrypoint","routingMode"],"properties":{"artifactType":{"type":"string","enum":["static_archive"]},"artifactRef":{"type":"string"},"artifactSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"publishDirectory":{"type":"string"},"fileCount":{"type":"integer","minimum":1},"byteCount":{"type":"integer","minimum":1},"entrypoint":{"type":"string"},"routingMode":{"type":"string","enum":["static_default_document","spa_fallback"]}},"additionalProperties":false}},"additionalProperties":false}]},"InternalRunnerEvent":{"type":"object","required":["eventType"],"properties":{"eventType":{"type":"string"},"message":{"type":["string","null"]},"payload":{},"source":{"type":["string","null"],"enum":["builder","runner","gateway","health_checker","health","provider",null]},"severity":{"type":["string","null"],"enum":["debug","info","warn","error",null]},"stream":{"type":["string","null"],"enum":["stdout","stderr","system",null]},"observedAt":{"type":["string","null"],"format":"date-time"},"sequenceNumber":{"type":["integer","null"],"minimum":1},"idempotencyKey":{"type":["string","null"]}}},"ProjectSummary":{"type":"object","required":["id","deploymentMode","projectRoute","releaseUsability","sourceProfile"],"properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"organizationId":{"type":["string","null"]},"projectMembershipId":{"type":["string","null"]},"projectRole":{"type":["string","null"],"enum":["owner","admin","contributor",null]},"projectSlug":{"type":["string","null"]},"projectHostname":{"type":["string","null"]},"primaryHostname":{"type":["string","null"],"description":"Official address of the project: its active custom domain whose DNS points at Eurobase, the one that went live first when several do, otherwise projectHostname. projectHostname stays reserved and keeps serving."},"deploymentMode":{"type":"string","enum":["runtime","static"]},"lifecycleState":{"type":["string","null"]},"deleteRequestedAt":{"type":["string","null"],"format":"date-time"},"projectRoute":{"$ref":"#/components/schemas/ProjectRoute"},"releaseUsability":{"$ref":"#/components/schemas/ReleaseUsability"},"projectSummaryStatus":{"$ref":"#/components/schemas/ProjectSummaryStatus"},"servingSuspension":{"oneOf":[{"$ref":"#/components/schemas/ProjectServingSuspension"},{"type":"null"}]},"sourceProfile":{"oneOf":[{"$ref":"#/components/schemas/ProjectSourceProfileSummary"},{"type":"null"}]},"sourceLock":{"$ref":"#/components/schemas/ProjectSourceLock"}}},"ProjectSourceLock":{"type":"object","description":"ADR 0090: while locked, no caller can change the project repository, branch, root directory or deployment mode.","required":["locked","lockedAt"],"properties":{"locked":{"type":"boolean"},"lockedAt":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false},"ProjectSourceLockRequest":{"type":"object","required":["locked"],"properties":{"locked":{"type":"boolean"}},"additionalProperties":false},"ProjectSourceLockResponse":{"type":"object","required":["project"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"}}},"ProjectSourceLockErrorResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["project-source-lock-invalid","project-source-lock-owner-required","project-source-lock-panel-required"]}}},"ProjectServingSuspension":{"type":"object","description":"An operator suspension of the project's public serving (ADR 0080). Operator notes and evidence are never included.","required":["state","reasonCategory","reasonLabel","since","supportEmail","policyUrl"],"properties":{"state":{"type":"string","enum":["suspended"]},"reasonCategory":{"type":"string","enum":["phishing","malware","shared_domain_abuse","spam","illegal_content","legal_order","other_policy_violation"]},"reasonLabel":{"type":"string"},"since":{"type":["string","null"],"format":"date-time"},"supportEmail":{"type":"string"},"policyUrl":{"type":"string"}},"additionalProperties":false},"ProjectEnforcementAction":{"type":"object","required":["id","sequence","action","reasonCategory","reasonText","operatorUserId","clientRequestId","evidence","createdAt"],"properties":{"id":{"type":"string"},"sequence":{"type":"integer","minimum":1},"action":{"type":"string","enum":["suspend","unsuspend"]},"reasonCategory":{"type":"string","enum":["phishing","malware","shared_domain_abuse","spam","illegal_content","legal_order","other_policy_violation","remediated","false_positive","appeal_granted","legal_order_lifted"]},"reasonText":{"type":"string"},"operatorUserId":{"type":"string"},"operatorEmail":{"type":["string","null"]},"clientRequestId":{"type":"string"},"requestId":{"type":["string","null"]},"evidence":{"type":"object","description":"project-enforcement-evidence.v1 captured at action time; at most 64 KiB."},"createdAt":{"type":"string","format":"date-time"}}},"ProjectEnforcementState":{"type":"object","required":["suspended","reasonCategory","since","sequence"],"properties":{"suspended":{"type":"boolean"},"reasonCategory":{"type":["string","null"]},"since":{"type":["string","null"],"format":"date-time"},"sequence":{"type":"integer","minimum":0}}},"InternalProjectEnforcementResponse":{"type":"object","required":["project","state","actions","reasonCategories"],"properties":{"project":{"type":"object"},"state":{"$ref":"#/components/schemas/ProjectEnforcementState"},"actions":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ProjectEnforcementAction"}},"reasonCategories":{"type":"object","properties":{"suspend":{"type":"array","items":{"type":"string","enum":["phishing","malware","shared_domain_abuse","spam","illegal_content","legal_order","other_policy_violation"]}},"unsuspend":{"type":"array","items":{"type":"string","enum":["remediated","false_positive","appeal_granted","legal_order_lifted"]}}}}}},"InternalProjectEnforcementActionRequest":{"type":"object","required":["action","reasonCategory","reasonText","clientRequestId"],"properties":{"action":{"type":"string","enum":["suspend","unsuspend"]},"reasonCategory":{"type":"string","enum":["phishing","malware","shared_domain_abuse","spam","illegal_content","legal_order","other_policy_violation","remediated","false_positive","appeal_granted","legal_order_lifted"]},"reasonText":{"type":"string","minLength":10,"maxLength":2000},"clientRequestId":{"type":"string","pattern":"^[A-Za-z0-9_-]{16,64}$"},"evidenceUrls":{"type":"array","maxItems":5,"items":{"type":"string","format":"uri"},"description":"Required for suspend: https URLs on hosts this project serves."},"requestIds":{"type":"array","maxItems":10,"items":{"type":"string"}},"reportReference":{"type":["string","null"],"maxLength":200}}},"InternalProjectEnforcementActionResponse":{"type":"object","required":["changed","replayed","action","state","notification","verification"],"properties":{"changed":{"type":"boolean"},"replayed":{"type":"boolean"},"action":{"oneOf":[{"$ref":"#/components/schemas/ProjectEnforcementAction"},{"type":"null"}]},"state":{"$ref":"#/components/schemas/ProjectEnforcementState"},"notification":{"oneOf":[{"type":"object","properties":{"inApp":{"type":"string","enum":["created","failed"]},"email":{"type":"string","enum":["sent","not_configured","no_recipient","failed"]}}},{"type":"null"}]},"verification":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["verified","not_verified","not_attempted"]}}}}},"ProjectCardDeployment":{"type":"object","required":["id","status","displayStatus","healthy","commitSha","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"status":{"type":["string","null"]},"displayStatus":{"type":"string","enum":["queued","waiting_for_builder","building_image","waiting_for_deploy_runner","deploying","healthy","unhealthy","failed","rolled_back","status_check_delayed"]},"buildQueuePosition":{"type":["integer","null"],"minimum":1,"description":"Place in the source build admission queue while the build waits for capacity."},"healthy":{"type":"boolean"},"commitSha":{"type":["string","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false},"ProjectCard":{"type":"object","required":["id","name","organizationId","workspace","projectMembershipId","projectRole","region","deploymentMode","repoFullName","branch","rootDir","runCommand","healthPath","containerPort","projectSlug","projectHostname","primaryHostname","lifecycleState","activeDeploymentId","projectRoute","releaseUsability","projectSummaryStatus","sourceProfile","createdAt","updatedAt","activeDeployment","latestDeployment","latestDeployAt"],"properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"organizationId":{"type":["string","null"]},"workspace":{"type":"object","required":["name","shared","ownerEmail"],"description":"The workspace that owns the project and the email of the person who pays for it; shared is true when it is not the caller's own (ADR 0098).","properties":{"name":{"type":"string"},"shared":{"type":"boolean"},"ownerEmail":{"type":["string","null"]}}},"projectMembershipId":{"type":["string","null"]},"projectRole":{"type":["string","null"],"enum":["owner","admin","contributor",null]},"region":{"type":["string","null"]},"deploymentMode":{"type":"string","enum":["runtime","static"]},"repoFullName":{"type":["string","null"]},"branch":{"type":"string"},"rootDir":{"type":"string"},"runCommand":{"type":["string","null"]},"healthPath":{"type":"string"},"containerPort":{"type":"integer","minimum":1,"maximum":65535},"projectSlug":{"type":["string","null"]},"projectHostname":{"type":["string","null"]},"primaryHostname":{"type":["string","null"],"description":"Official address of the project: its active custom domain whose DNS points at Eurobase, the one that went live first when several do, otherwise projectHostname. projectHostname stays reserved and keeps serving."},"lifecycleState":{"type":["string","null"]},"activeDeploymentId":{"type":["string","null"]},"projectRoute":{"$ref":"#/components/schemas/ProjectRoute"},"releaseUsability":{"$ref":"#/components/schemas/ReleaseUsability"},"projectSummaryStatus":{"$ref":"#/components/schemas/ProjectSummaryStatus"},"servingSuspension":{"oneOf":[{"$ref":"#/components/schemas/ProjectServingSuspension"},{"type":"null"}]},"sourceProfile":{"oneOf":[{"$ref":"#/components/schemas/ProjectSourceProfileSummary"},{"type":"null"}]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"activeDeployment":{"oneOf":[{"$ref":"#/components/schemas/ProjectCardDeployment"},{"type":"null"}]},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/ProjectCardDeployment"},{"type":"null"}]},"latestDeployAt":{"type":["string","null"],"format":"date-time","description":"Most recent deploy across the app, Containers, and Functions; null when nothing was deployed."}},"additionalProperties":false},"ProjectSourceProfileSummary":{"type":"object","required":["framework","frameworkLabel","outputMode"],"properties":{"framework":{"type":"string","enum":["next","astro","svelte-kit","nuxt","react-router","vite","hono","nestjs","fastify","express","django","fastapi","flask","laravel","rails","node","python","php","ruby","go","java","dotnet","static"]},"frameworkLabel":{"type":"string"},"outputMode":{"type":"string","enum":["runtime","static"]}}},"ProjectSummaryStatus":{"type":"object","required":["label","tone","code","detailTitle","detail"],"properties":{"label":{"type":"string"},"tone":{"type":"string","enum":["neutral","problem","error"]},"code":{"type":"string","enum":["setup_required","route_issue","deploy_failed","deploy_unhealthy","live_release_blocked","status_check_delayed","deploy_in_progress","rollback_live","healthy","suspended"]},"detailTitle":{"type":["string","null"]},"detail":{"type":["string","null"]}}},"ProjectRoute":{"type":"object","required":["status","reasonCode","managed","upstream"],"properties":{"status":{"type":"string","enum":["healthy","repairing","degraded","broken","unknown"]},"reasonCode":{"type":"string","enum":["none","dns_record_missing","dns_propagating","domain_binding_missing","tls_pending","missing_project_upstream","upstream_unreachable","ingress_unreachable","unmanaged_custom_domain","scw_mutation_failed"]},"checkedAt":{"type":["string","null"],"format":"date-time"},"lastRepairAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]},"managed":{"type":"boolean"},"convergenceState":{"type":["string","null"],"enum":["recovering","exhausted","ready",null]},"upstream":{"$ref":"#/components/schemas/ProjectUpstreamState"}}},"ProjectUpstreamState":{"type":"object","required":["status","reasonCode"],"properties":{"status":{"type":"string","enum":["healthy","broken","unknown"]},"reasonCode":{"type":"string","enum":["none","missing_project_upstream","upstream_unreachable"]},"checkedAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]}}},"ReleaseUsability":{"type":"object","required":["status","reasonCode","lastLiveDeploymentId"],"properties":{"status":{"type":"string","enum":["reachable","degraded","blocked","unknown"]},"reasonCode":{"type":"string","enum":["none","missing_live_release","access_not_allowed","route_repair_in_progress","route_incident","project_suspended"]},"lastLiveDeploymentId":{"type":["string","null"]}}},"ProjectSourceDeploy":{"type":"object","required":["available","reasonCode"],"properties":{"available":{"type":"boolean"},"reasonCode":{"type":"string","enum":["ready","project_repository_missing","historical_repo_unavailable"]},"title":{"type":["string","null"]},"message":{"type":["string","null"]},"recoveryAction":{"anyOf":[{"$ref":"#/components/schemas/GitHubConnectAction"},{"type":"null"}]}}},"ProjectCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"description":"Project hostname label seed. Exact platform-reserved labels, and labels ending in -functions, -containers, -fn-<8 hex> or -ctr-<8 hex> (runtime host suffixes), return project-name-reserved before generic invalid-name classification.","anyOf":[{"type":"string","enum":["www","app","api","cdn","admin","operator","status","cloud","console","security","s3","soc","sandbox","edge"]},{"type":"string","minLength":8,"maxLength":24,"pattern":"^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$"}]},"organizationId":{"type":["string","null"]}}},"DeploymentCreateRequest":{"type":"object","required":["projectId"],"additionalProperties":false,"properties":{"projectId":{"type":"string"},"blockedPushEventId":{"type":"string","description":"Retry a quota-blocked push through normal deploy admission, using its immutable commit and requiring the project repository and branch to match."},"sourceDeploymentId":{"type":"string","description":"Optional selected deployment id whose source, config, and commit should be replayed."},"commitSha":{"type":"string","description":"Optional explicit commit SHA for a normal project source deployment."},"sourceConfirmation":{"$ref":"#/components/schemas/ProjectSourceConfirmation","description":"Saved source identity returned by app-source detection. Fresh deployments with an explicit commit reject a changed source before admission and again under the project transaction lock."},"sourceBuildEngineChange":{"$ref":"#/components/schemas/SourceBuildEngineChange","description":"Fresh deploy only (no sourceDeploymentId, no appSource): switches the stored runtime and queues the commit in one transaction. With sourceDeploymentId it is refused with 400 source-build-engine-change-invalid."}}},"MaintenanceReconcileRequest":{"type":"object","required":["phases"],"properties":{"phases":{"type":"array","minItems":1,"items":{"type":"string","enum":["stale_jobs","preview_retry","provider_mutations","pending_deletes","container_deletes","project_access","github_webhooks","github_push_events","github_webhook_retention","quota_reservations","quota_state","project_log_usage_intents","source_build_output_candidates","usage_stock_seed","usage_build_seed","telemetry_reconcile","provider_usage_metrics","geoip_update","geoip_backfill","operator_business_metrics","billing_provider_import","billing_reconciliation","scw_runtime_logs","event_retention","log_retention","telemetry_prune","app_storage_cleanup","route_sync"]}},"jobLimit":{"type":"integer","minimum":1,"maximum":500},"settlementDeadlineMs":{"type":"integer","minimum":5000,"maximum":50000},"quotaStateAfterOrganizationId":{"type":"string","description":"Resume quota_state after the cursor returned by its previous maintenance batch."},"routeLimit":{"type":"integer","minimum":1,"maximum":100},"force":{"type":"boolean"},"pendingDeleteUserId":{"type":["string","null"]},"pendingDeleteProjectId":{"type":["string","null"]},"billingMonth":{"type":["string","null"],"pattern":"^\\d{4}-\\d{2}(-\\d{2})?$"},"billingProviderRows":{"type":"array","maxItems":1000,"items":{"type":"object","required":["providerProjectId","skuCode","quantityDecimal","amountDecimal","sourceHash"],"additionalProperties":false,"properties":{"provider":{"type":"string","enum":["scaleway"]},"providerProjectId":{"type":"string"},"billingMonth":{"type":["string","null"]},"skuCode":{"type":"string"},"skuLabel":{"type":["string","null"]},"unit":{"type":["string","null"]},"quantityDecimal":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"amountDecimal":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"sourceHash":{"type":"string"}}}},"platformOverhead":{"type":"array","maxItems":100,"items":{"type":"object","required":["category","amountDecimal"],"additionalProperties":false,"properties":{"category":{"type":"string","enum":["control_plane","gateway_kapsule_shared_runtime","observability_log_shipping","registry_artifact_retention","preview_shared_storage_assets","networking_egress_not_tenant_attributable","operator_protected_demo_resources"]},"amountDecimal":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"operatorSummary":{"type":["string","null"]}}}},"billingImportSource":{"type":["object","null"],"required":["sourceType","sourceHash"],"additionalProperties":false,"properties":{"sourceType":{"type":"string","enum":["scaleway_invoice_export"]},"sourceReference":{"type":["string","null"]},"sourceHash":{"type":"string"}}}},"additionalProperties":false},"FunctionQuotaProjectionActivationResponse":{"type":"object","additionalProperties":false,"required":["activated","activationVersion","activatedAt"],"properties":{"activated":{"type":"boolean"},"activationVersion":{"type":"integer","minimum":1},"activatedAt":{"type":"string","format":"date-time"}}},"ProjectCreateConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["organization-required","project-name-reserved","project-delete-pending","project-slug-conflict","project-hostname-conflict"]},"projectSlug":{"type":["string","null"]},"projectHostname":{"type":["string","null"]}}},"ProjectCreateInvalidResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["project-name-invalid"]}}},"QuotaBlockResponse":{"type":"object","required":["error","reason","quota"],"properties":{"error":{"type":"string","enum":["Conflict"]},"reason":{"type":"string","enum":["quota-blocked"]},"quota":{"type":"object","required":["actionCode","metricCode","used","limit","resetAt","recoveryActions"],"properties":{"actionCode":{"type":"string"},"metricCode":{"type":["string","null"]},"used":{"type":["string","null"],"pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"limit":{"type":["string","null"],"pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"resetAt":{"type":["string","null"],"format":"date-time"},"recoveryActions":{"type":"array","items":{"type":"string"}}}}}},"RetryableStorageBlockerResponse":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["quota-state-unavailable","storage-accounting-unavailable"]},"retryable":{"type":"boolean","enum":[true]}}},"StorageObjectMetadataInvalidResponse":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string","enum":["Storage object metadata is invalid"]},"reason":{"type":"string","enum":["storage-object-metadata-invalid"]}}},"RetryableQuotaStateBlockerResponse":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["quota-state-unavailable"]},"retryable":{"type":"boolean","enum":[true]}}},"RetryableSourceBuildBlockerResponse":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["source-build-jobs-release-unavailable","workers-detection-unavailable"]},"retryable":{"const":true}}},"RetryableContainerQuotaBlockerResponse":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["quota-state-unavailable","quota-recovery-unavailable"]},"retryable":{"type":"boolean","enum":[true]}}},"StorageBucketConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["storage-bucket-conflict"]}}},"ProjectDeleteRequest":{"type":"object","required":["confirmation"],"properties":{"confirmation":{"type":"string","minLength":1,"description":"Exact project name, including case, required for irreversible project deletion."}}},"ProjectAppRepoRequest":{"type":"object","required":["repoId","repoFullName"],"properties":{"repoId":{"type":"string"},"repoFullName":{"type":"string"},"branch":{"type":"string"},"rootDir":{"type":"string"},"runCommand":{"type":"string"},"healthPath":{"type":"string"},"containerPort":{"type":"integer"}}},"ProjectAppRepoConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["project-app-repo-conflict","project-github-installation-missing","project-source-locked"]}}},"ProjectAppRepoInvalidResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["deployment-mode-not-settable"]}}},"AppRuntimeTier":{"type":"object","required":["code","label","minScale","maxScale","configurable"],"properties":{"code":{"type":"string","enum":["euro-small","euro-medium","euro-large","euro-xlarge"]},"label":{"type":"string"},"cpu":{"type":"string"},"memory":{"type":"string"},"limitsKnown":{"type":"boolean"},"cpuMillicores":{"type":["integer","null"]},"memoryMb":{"type":["integer","null"]},"minScale":{"type":["integer","null"]},"maxScale":{"type":["integer","null"]},"burnMultiplier":{"type":["string","null"]},"workloadGuidance":{"type":["string","null"]},"equivalentIncludedRuntimeHours":{"type":["string","null"]},"selectable":{"type":"boolean"},"unavailableReason":{"type":["string","null"]},"recoveryAction":{"type":["string","null"]},"configurable":{"type":"boolean"}}},"AppSourceDetectionEvidence":{"type":"object","required":["path","reason"],"properties":{"path":{"type":"string"},"reason":{"type":"string"}}},"AppSourceDetection":{"type":"object","required":["status","reason","confidence","detectorVersion","evidence","warnings"],"properties":{"status":{"type":"string","enum":["not_requested","pending","detected","needs_review","failed","unavailable"]},"reason":{"type":"string","enum":["none","no_match","ambiguous","cap_exceeded","timeout","rate_limited","repo_access_unavailable","detector_error"]},"confidence":{"type":"string","enum":["high","medium","low","unknown"]},"detectedAt":{"type":["string","null"],"format":"date-time"},"commitSha":{"type":["string","null"]},"treeSha":{"type":["string","null"]},"detectorVersion":{"type":["string","null"]},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/AppSourceDetectionEvidence"}},"warnings":{"type":"array","items":{"type":"string"}}}},"AppSourceProfile":{"type":"object","required":["sourceType","repository","branch","rootDirectory","rootCandidates","rootChoiceRequired","rootChoiceConfirmed","sourceBuildEngine","directStatic","framework","frameworkLabel","outputMode","detection","overrideState","canDeploy"],"properties":{"sourceType":{"type":"string","enum":["git_repo"]},"repository":{"oneOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]},"fullName":{"type":["string","null"]}}},{"type":"null"}]},"branch":{"type":"string"},"rootDirectory":{"type":"string"},"rootCandidates":{"type":"array","maxItems":20,"items":{"type":"string"}},"rootCandidateSetHash":{"type":["string","null"],"pattern":"^[a-f0-9]{64}$"},"rootChoiceRequired":{"type":"boolean"},"rootChoiceConfirmed":{"type":"boolean"},"sourceBuildEngine":{"type":"string","enum":["direct-static-v1","paketo-v1","workers-v1"]},"directStatic":{"type":"boolean"},"framework":{"type":"string","enum":["next","astro","svelte-kit","nuxt","react-router","vite","hono","nestjs","fastify","express","django","fastapi","flask","laravel","rails","node","python","php","ruby","go","java","dotnet","static","unknown"]},"frameworkLabel":{"type":"string"},"outputMode":{"type":"string","enum":["runtime","static"]},"appRuntimeTierId":{"type":["string","null"],"enum":["euro-small","euro-medium","euro-large","euro-xlarge",null]},"port":{"type":["integer","null"]},"healthPath":{"type":["string","null"]},"appRuntimeTier":{"oneOf":[{"$ref":"#/components/schemas/AppRuntimeTier"},{"type":"null"}]},"detection":{"$ref":"#/components/schemas/AppSourceDetection"},"overrideState":{"type":"string","enum":["auto","custom_override","detected_but_unconfirmed"]},"canDeploy":{"type":"boolean"},"blockedReason":{"type":["string","null"]},"blockedMessage":{"type":["string","null"]},"sourceRuntime":{"type":["string","null"],"enum":["ruby","dotnet","go","python","php","java","node",null]},"serviceType":{"type":["string","null"],"enum":["web_service","static_site",null]},"packageManager":{"type":["string","null"],"enum":["npm","yarn",null]},"buildCommand":{"type":["string","null"]},"startCommand":{"type":["string","null"]},"publishDirectory":{"type":["string","null"]},"sourceBuild":{"oneOf":[{"$ref":"#/components/schemas/AppSourceBuildPlan"},{"type":"null"}]},"buildHints":{"oneOf":[{"type":"object","properties":{"runtime":{"type":["string","null"]},"pythonVersion":{"type":["string","null"]},"nodeVersion":{"type":["string","null"]},"nodeLaunchpoint":{"type":["string","null"]}}},{"type":"null"}]}}},"AppSourceBuildPlan":{"type":"object","required":["runtime","packageManager","blockedReason","procfileWeb","scripts","startRequired","buildAvailable","defaults"],"properties":{"runtime":{"type":["string","null"]},"packageManager":{"type":["string","null"]},"blockedReason":{"type":["string","null"]},"procfileWeb":{"type":["string","null"]},"scripts":{"type":"array","maxItems":50,"items":{"type":"string"}},"startRequired":{"type":"boolean"},"buildAvailable":{"type":"boolean"},"startLooksLikeDevServer":{"type":"boolean"},"defaults":{"type":"object","required":["serviceType","buildCommand","startCommand","publishDirectory"],"properties":{"serviceType":{"type":"string","enum":["web_service","static_site"]},"buildCommand":{"type":["string","null"]},"startCommand":{"type":["string","null"]},"publishDirectory":{"type":["string","null"]}}}}},"ProjectAppSourceDetectRequest":{"type":"object","properties":{"repoId":{"type":"string"},"repoFullName":{"type":"string"},"branch":{"type":"string"},"rootDir":{"type":"string"},"rootDirectory":{"type":"string"},"rootCandidateSetHash":{"type":["string","null"],"pattern":"^[a-f0-9]{64}$"},"rootChoiceConfirmed":{"type":"boolean"}}},"ProjectAppSourceFoldersRequest":{"type":"object","properties":{"repoId":{"type":"string"},"repoFullName":{"type":"string"},"branch":{"type":"string"}}},"ProjectAppSourceFolder":{"type":"object","required":["path","label","depth"],"properties":{"path":{"type":"string"},"label":{"type":"string"},"depth":{"type":"integer"}}},"ProjectAppSourceFoldersResponse":{"type":"object","required":["repository","branch","truncated","folders"],"properties":{"repository":{"type":"object","required":["id","fullName"],"properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]},"fullName":{"type":"string"}}},"branch":{"type":"string"},"truncated":{"type":"boolean"},"folders":{"type":"array","items":{"$ref":"#/components/schemas/ProjectAppSourceFolder"}}}},"ProjectAppSourceSaveRequest":{"type":"object","properties":{"repoId":{"type":"string"},"repoFullName":{"type":"string"},"branch":{"type":"string"},"rootDir":{"type":"string"},"rootDirectory":{"type":"string"},"rootCandidates":{"type":"array","maxItems":20,"items":{"type":"string"}},"rootCandidateSetHash":{"type":["string","null"],"pattern":"^[a-f0-9]{64}$"},"rootChoiceRequired":{"type":"boolean"},"rootChoiceConfirmed":{"type":"boolean"},"port":{"type":["integer","null"]},"healthPath":{"type":["string","null"]},"appRuntimeTierId":{"type":["string","null"],"enum":["euro-small","euro-medium","euro-large","euro-xlarge",null]},"serviceType":{"type":"string","enum":["web_service","static_site"]},"buildCommand":{"type":["string","null"],"maxLength":80},"startCommand":{"type":["string","null"],"maxLength":1024},"publishDirectory":{"type":["string","null"],"maxLength":240},"sourceBuildEngineChange":{"$ref":"#/components/schemas/SourceBuildEngineChange"}}},"SourceBuildEngineChange":{"type":"object","description":"Explicit confirmation of a project runtime switch (ADR 0076 D2), applied as compare-and-set under the project row lock: from is the stored engine and to the engine detected for the admitted commit. Refused on redeploys and never read from pushes.","required":["from","to"],"additionalProperties":false,"properties":{"from":{"type":"string","enum":["direct-static-v1","paketo-v1","workers-v1"]},"to":{"type":"string","enum":["direct-static-v1","paketo-v1","workers-v1"]}}},"RuntimeSelection":{"type":"object","description":"The project runtime plan for one commit. detected: no runtime is stored yet and this commit selects it; confirmed: the commit matches the stored runtime; change-required: the commit needs the detected runtime and deploys only after an explicit sourceBuildEngineChange; stored-engine-blocked: this commit cannot deploy, and blocker carries its reason: either the stored runtime cannot admit it, or a build Job already detected it as a Workers app (detectedEngine workers-v1) that cannot run, which is refused with its fix and never built on Paketo. detectedEngine workers-v1 without a stored runtime is the route: the Workers build Job detects the runtime before any user code runs, then builds on Workers, builds the same deployment on Paketo, or refuses it. Warnings (from the last build Job detection for this commit, and client-written-cookies from the plan read) never block the deploy.","required":["storedEngine","detectedEngine","commitSha","state"],"properties":{"storedEngine":{"type":["string","null"],"enum":["direct-static-v1","paketo-v1","workers-v1",null]},"detectedEngine":{"type":["string","null"],"enum":["direct-static-v1","paketo-v1","workers-v1",null]},"commitSha":{"type":["string","null"],"pattern":"^[a-f0-9]{40}$"},"state":{"type":"string","enum":["detected","confirmed","change-required","changed","stored-engine-blocked"]},"detectedBlockedReason":{"type":["string","null"]},"blocker":{"type":"object","required":["reason","message","evidence"],"properties":{"reason":{"type":"string"},"message":{"type":"string","description":"Owner-facing copy; a command inside it is delimited by backticks."},"fixCommand":{"type":["string","null"],"description":"The one command that fixes a Workers refusal in the repository, when one exists."},"evidence":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"reason":{"type":"string"}}}}}},"warnings":{"type":"array","description":"Warnings for a deployable plan; the deploy proceeds. Workers detection warnings, then one `client-written-cookies` warning per distinct fix for the Root dependencies that write a cookie in the browser for the server to read.","items":{"type":"object","required":["code","message","fixCommand"],"properties":{"code":{"type":"string","enum":["adapter-compatibility-unverified","client-written-cookies","framework-version-end-of-life","framework-version-vulnerable","package-manager-version-substituted"]},"message":{"type":"string","description":"Owner-facing copy; a command or code inside it is delimited by backticks."},"fixCommand":{"type":["string","null"]},"docsPath":{"type":"string","description":"Eurobase docs page that explains the warning, as a path on the web app origin."}}}}}},"ProjectSourceConfirmation":{"type":"object","required":["repository","branch","rootDirectory","configurationHash"],"additionalProperties":false,"properties":{"repository":{"type":"string","minLength":1},"branch":{"type":"string","minLength":1},"rootDirectory":{"type":"string","minLength":1},"configurationHash":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"API-owned binding of the saved source defaults, excluding detector caches and unrelated project updates."}}},"ProjectAppSourceResponse":{"type":"object","required":["project","appSourceProfile"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"appRepo":{"oneOf":[{"$ref":"#/components/schemas/AppRepo"},{"type":"null"}]},"appRuntimeTier":{"oneOf":[{"$ref":"#/components/schemas/AppRuntimeTier"},{"type":"null"}]},"appRuntimeTierOptions":{"type":"array","items":{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"}},"defaultAppRuntimeTierCode":{"type":["string","null"],"enum":["euro-small","euro-medium","euro-large","euro-xlarge",null]},"appRuntimeTierPolicyState":{"oneOf":[{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ready","blocked","unavailable"]},"reasonCode":{"type":["string","null"]},"recoveryAction":{"type":["string","null"]}}},{"type":"null"}]},"planRuntimeAllowance":{"oneOf":[{"type":"object","required":["smallEquivalentHours","maxScale"],"properties":{"smallEquivalentHours":{"type":"string"},"maxScale":{"type":"integer"}}},{"type":"null"}]},"appSourceProfile":{"oneOf":[{"$ref":"#/components/schemas/AppSourceProfile"},{"type":"null"}]},"detectedAppSourceProfile":{"oneOf":[{"$ref":"#/components/schemas/AppSourceProfile"},{"type":"null"}]},"sourceConfirmation":{"$ref":"#/components/schemas/ProjectSourceConfirmation","description":"Saved project source identity for an explicit-commit fresh deployment confirmation."},"runtimeSelection":{"description":"Detect only: the same stored-versus-detected comparison admission applies, without a confirmation. Null when the Root is unresolved or detection is unavailable.","oneOf":[{"$ref":"#/components/schemas/RuntimeSelection"},{"type":"null"}]}}},"ProjectAppSourceErrorResponse":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["root-directory-invalid","repository-required","app-source-profile-invalid","external-image-source-not-supported","framework-invalid","output-mode-invalid","build-command-invalid","start-command-invalid","port-invalid","health-path-invalid","publish-directory-invalid","dockerfile-build-plan-required","dockerfile-build-trust-unproven","dockerfile-startup-invalid","dockerfile-startup-missing","app-source-detection-required","app-source-detection-framework-needs-review","app-source-detection-cap-exceeded","app-source-detection-timeout","app-source-detection-rate-limited","app-source-detection-repo-access-unavailable","app-source-detection-unavailable","selected-root-not-found","project-app-repo-conflict","project-github-installation-missing","project-source-locked","runtime-tier-policy-unavailable","app-runtime-tier-unavailable","app-runtime-tier-not-configurable","app-runtime-tier-not-applicable","source-build-engine-change-invalid","runtime-detection-changed","direct-static-build-evidence","direct-static-source-path-unsafe","direct-static-source-link","direct-static-depth-limit","direct-static-source-too-large","direct-static-index-missing","direct-static-empty","workers-v1-admission-disabled","workers-v1-build-unavailable"]},"errors":{"type":"array","items":{"type":"string"}},"evidence":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"reason":{"type":"string"}}}},"runtimeSelection":{"$ref":"#/components/schemas/RuntimeSelection"},"appSourceProfile":{"oneOf":[{"$ref":"#/components/schemas/AppSourceProfile"},{"type":"null"}]}}},"ProjectStatusResponse":{"type":"object","required":["project","projectHealth","activeDeployment","latestDeployment","deployments","blockedPushes","releaseUsability","sourceDeploy","appRepo","appSourceProfile","actionPermissions"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"anyOf":[{"$ref":"#/components/schemas/ProjectHealth"},{"type":"null"}]},"activeDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"deployments":{"type":"array","items":{"$ref":"#/components/schemas/Deployment"}},"releaseUsability":{"$ref":"#/components/schemas/ReleaseUsability"},"blockedPushes":{"type":"array","maxItems":25,"items":{"type":"object","additionalProperties":false,"required":["id","repoFullName","branch","commitSha","reasonCode","blockedAt","message","canRetry","retryBlockedReason"],"properties":{"id":{"type":"string"},"repoFullName":{"type":["string","null"]},"branch":{"type":"string"},"commitSha":{"type":"string"},"reasonCode":{"type":"string"},"blockedAt":{"type":"string","format":"date-time"},"message":{"type":"string"},"canRetry":{"type":"boolean"},"retryBlockedReason":{"type":["string","null"]}}}},"sourceDeploy":{"$ref":"#/components/schemas/ProjectSourceDeploy"},"appRuntimeTier":{"oneOf":[{"$ref":"#/components/schemas/AppRuntimeTier"},{"type":"null"}]},"appRuntimeTierOptions":{"type":"array","items":{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"}},"defaultAppRuntimeTierCode":{"type":["string","null"],"enum":["euro-small","euro-medium","euro-large","euro-xlarge",null]},"appRuntimeTierPolicyState":{"oneOf":[{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ready","blocked","unavailable"]},"reasonCode":{"type":["string","null"]},"recoveryAction":{"type":["string","null"]}}},{"type":"null"}]},"planRuntimeAllowance":{"oneOf":[{"type":"object","required":["smallEquivalentHours","maxScale"],"properties":{"smallEquivalentHours":{"type":"string"},"maxScale":{"type":"integer"}}},{"type":"null"}]},"appRepo":{"anyOf":[{"$ref":"#/components/schemas/AppRepo"},{"type":"null"}]},"appSourceProfile":{"anyOf":[{"$ref":"#/components/schemas/AppSourceProfile"},{"type":"null"}]},"actionPermissions":{"type":"object","required":["canManageSource","canDetectAppSource","canQueueFirstDeployment"],"properties":{"canManageSource":{"type":"boolean"},"canDetectAppSource":{"type":"boolean"},"canQueueFirstDeployment":{"type":"boolean"}}}}},"ProjectResourceMapRegion":{"type":"object","required":["code","label"],"properties":{"code":{"type":"string"},"label":{"type":"string"}}},"ProjectResourceMapNodeStatus":{"type":"object","required":["code","label","tone"],"properties":{"code":{"type":"string"},"label":{"type":"string"},"tone":{"type":"string"}}},"ProjectResourceMapNodeAccess":{"type":"object","required":["mode","label","description"],"properties":{"mode":{"type":"string","enum":["public","private","signed"]},"label":{"type":"string"},"description":{"type":["string","null"]}}},"ProjectResourceMapNodeMeta":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"value":{"type":"string"}}},"ProjectResourceMapNode":{"type":"object","required":["id","kind","resourceId","label","subtitle","status","access","href","sourceProfile","meta"],"properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["region","git_source","app_deployment","container","function","storage_bucket"]},"resourceId":{"type":["string","null"]},"label":{"type":"string"},"subtitle":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/ProjectResourceMapNodeStatus"},"access":{"oneOf":[{"$ref":"#/components/schemas/ProjectResourceMapNodeAccess"},{"type":"null"}]},"href":{"type":["string","null"]},"sourceProfile":{"oneOf":[{"$ref":"#/components/schemas/ProjectSourceProfileSummary"},{"type":"null"}]},"meta":{"type":"array","maxItems":8,"items":{"$ref":"#/components/schemas/ProjectResourceMapNodeMeta"}}}},"ProjectResourceMapLink":{"type":"object","required":["fromNodeId","toNodeId","kind"],"properties":{"fromNodeId":{"type":"string"},"toNodeId":{"type":"string"},"kind":{"type":"string","enum":["project_context","source_dependency"]}}},"ProjectResourceMapResponse":{"type":"object","required":["project","region","nodes","links","generatedAt"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"region":{"$ref":"#/components/schemas/ProjectResourceMapRegion"},"nodes":{"type":"array","maxItems":153,"items":{"$ref":"#/components/schemas/ProjectResourceMapNode"}},"links":{"type":"array","maxItems":202,"items":{"$ref":"#/components/schemas/ProjectResourceMapLink"}},"generatedAt":{"type":"string","format":"date-time"}}},"ProjectDashboardResponse":{"type":"object","required":["resourceMap","telemetryOverview"],"properties":{"resourceMap":{"$ref":"#/components/schemas/ProjectResourceMapResponse"},"telemetryOverview":{"$ref":"#/components/schemas/ProjectTelemetryOverviewResponse"}}},"ProjectDiagnosticRecoveryAction":{"type":"object","required":["kind","label","href"],"properties":{"kind":{"type":"string"},"label":{"type":"string"},"href":{"type":["string","null"]}}},"ProjectDiagnosticFinding":{"type":"object","required":["id","state","label","severity","reasonCode","resource","deploymentId","firstObservedAt","lastObservedAt","lastSuccessAt","summary","recoveryAction"],"properties":{"id":{"type":"string"},"state":{"type":"string","enum":["healthy","pending","blocked","degraded","failed","unavailable","stale","deleting","delete_failed","resolved"]},"label":{"type":"string","enum":["Ready","Deploying","Blocked","Problem","Error","Unavailable","Deleting","Resolved"]},"severity":{"type":"string","enum":["info","warning","error","critical"]},"reasonCode":{"type":"string"},"resource":{"type":"object","required":["type","id","label"],"properties":{"type":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}}},"deploymentId":{"type":"string"},"firstObservedAt":{"type":"string","format":"date-time"},"lastObservedAt":{"type":"string","format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"summary":{"type":"string"},"recoveryAction":{"oneOf":[{"$ref":"#/components/schemas/ProjectDiagnosticRecoveryAction"},{"type":"null"}]}}},"ProjectDiagnosticsResponse":{"type":"object","required":["project","summary","findings","resources","timeline","actions","hasMore","generatedAt"],"properties":{"project":{"type":"object","required":["id","name","hostname"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"hostname":{"type":["string","null"]}}},"summary":{"type":"object","required":["state","label","primaryReasonCode","affectedResourceCount","openFindingCount","lastObservedAt"],"properties":{"state":{"type":"string"},"label":{"type":"string"},"primaryReasonCode":{"type":["string","null"]},"affectedResourceCount":{"type":"integer"},"openFindingCount":{"type":"integer"},"lastObservedAt":{"type":["string","null"],"format":"date-time"}}},"findings":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ProjectDiagnosticFinding"}},"resources":{"type":"array","maxItems":100,"items":{"type":"object"}},"timeline":{"type":"array","maxItems":50,"items":{"type":"object"}},"actions":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/ProjectDiagnosticRecoveryAction"}},"hasMore":{"type":"boolean"},"generatedAt":{"type":"string","format":"date-time"}}},"InternalOperatorProjectDiagnosticFinding":{"allOf":[{"$ref":"#/components/schemas/ProjectDiagnosticFinding"},{"type":"object","required":["tenantReasonCode","visibility","provider","providerResourceType","providerResourceId","sourceFamily","sourceRefType","sourceRefId","resolvedAt","staleAfter","title","operatorSummary","metadata"],"properties":{"tenantReasonCode":{"type":["string","null"]},"visibility":{"type":"string","enum":["tenant","operator"]},"provider":{"type":["string","null"]},"providerResourceType":{"type":["string","null"]},"providerResourceId":{"type":["string","null"]},"sourceFamily":{"type":"string"},"sourceRefType":{"type":["string","null"]},"sourceRefId":{"type":["string","null"]},"resolvedAt":{"type":["string","null"],"format":"date-time"},"staleAfter":{"type":["string","null"],"format":"date-time"},"title":{"type":"string"},"operatorSummary":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}}]},"InternalOperatorProjectDiagnosticsResponse":{"allOf":[{"$ref":"#/components/schemas/ProjectDiagnosticsResponse"},{"type":"object","required":["findings","evidenceEdges","providerRefs","maintenanceRuns","recentDeployments","recentLogs","quotaAndUsageEvidence"],"properties":{"findings":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/InternalOperatorProjectDiagnosticFinding"}},"evidenceEdges":{"type":"array","maxItems":100,"items":{"type":"object"}},"providerRefs":{"type":"array","maxItems":100,"items":{"type":"object"}},"maintenanceRuns":{"type":"array","items":{"type":"object"}},"recentDeployments":{"type":"array","items":{"type":"object"}},"recentLogs":{"type":"array","items":{"type":"object"}},"quotaAndUsageEvidence":{"nullable":true}}}]},"ProjectSettingsResponse":{"type":"object","required":["project","projectHealth","projectApiKey","providerIdentity","ipAllowlist","actionPermissions"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"anyOf":[{"$ref":"#/components/schemas/ProjectHealth"},{"type":"null"}]},"projectApiKey":{"anyOf":[{"$ref":"#/components/schemas/ProjectApiKey"},{"type":"null"}]},"providerIdentity":{"anyOf":[{"$ref":"#/components/schemas/ProjectProviderIdentity"},{"type":"null"}]},"ipAllowlist":{"$ref":"#/components/schemas/ProjectIpAllowlistPolicy"},"actionPermissions":{"type":"object","required":["canManageProject","canManageMembers","canManageProjectKey","canManageIpAllowlist","canManageSourceLock","canDeleteProject","canLeaveProject"],"properties":{"canManageProject":{"type":"boolean"},"canManageMembers":{"type":"boolean"},"canManageProjectKey":{"type":"boolean"},"canManageIpAllowlist":{"type":"boolean"},"canManageSourceLock":{"type":"boolean"},"canDeleteProject":{"type":"boolean"},"canLeaveProject":{"type":"boolean","description":"False for the person who pays for the project and for its last usable owner."}}}}},"ProjectIpAllowlistPolicy":{"type":"object","required":["enabled","entryCount","policyVersion","updatedAt","canEdit"],"properties":{"enabled":{"type":"boolean"},"entryCount":{"type":"integer","minimum":0,"maximum":50},"policyVersion":{"type":"integer","minimum":1},"updatedAt":{"type":["string","null"],"format":"date-time"},"canEdit":{"type":"boolean"},"cidrs":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":64}}}},"ProjectAccessPolicyResponse":{"type":"object","required":["projectId","ipAllowlist"],"properties":{"projectId":{"type":"string"},"ipAllowlist":{"$ref":"#/components/schemas/ProjectIpAllowlistPolicy"}}},"ProjectAccessPolicyRequest":{"type":"object","required":["ipAllowlist"],"properties":{"ipAllowlist":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"},"cidrs":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":64}}}}}},"AppRepo":{"type":"object","required":["repoId","repoFullName","branch","rootDir","runCommand","healthPath","containerPort","deploymentMode"],"properties":{"repoId":{"type":"string"},"repoName":{"type":["string","null"]},"repoFullName":{"type":"string"},"branch":{"type":"string"},"rootDir":{"type":"string"},"runCommand":{"type":"string"},"healthPath":{"type":"string"},"containerPort":{"type":"integer"},"deploymentMode":{"type":"string","enum":["runtime","static"]}}},"ProjectAppRepoResponse":{"type":"object","required":["project","appRepo"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"appRepo":{"oneOf":[{"$ref":"#/components/schemas/AppRepo"},{"type":"null"}]},"appRuntimeTier":{"oneOf":[{"$ref":"#/components/schemas/AppRuntimeTier"},{"type":"null"}]},"appSourceProfile":{"oneOf":[{"$ref":"#/components/schemas/AppSourceProfile"},{"type":"null"}]},"ok":{"type":"boolean"}}},"CreateProjectResponse":{"type":"object","required":["project","autoDeploy"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"autoDeploy":{"type":"boolean"}}},"ProjectContainerRoute":{"type":"object","required":["hostname","productUrl","accessMode","accessMapped","gatewayRegistrationReady","brandedHostGatewayProven","status","statusLabel","reasonCode","statusMessage"],"properties":{"hostname":{"type":"string"},"productUrl":{"type":["string","null"],"format":"uri","description":"Allocated Eurobase Function URL when known. Clients may display this value before route readiness, but Copy/Open actions require status=ready."},"accessMode":{"type":"string","enum":["public","private"]},"accessMapped":{"type":"boolean"},"gatewayRegistrationReady":{"type":"boolean"},"brandedHostGatewayProven":{"type":"boolean"},"status":{"type":"string","enum":["pending","ready","failed"]},"statusLabel":{"type":"string"},"reasonCode":{"type":"string"},"statusMessage":{"type":"string"}}},"ProjectContainerRuntimeTier":{"type":"object","required":["code","label","limitsKnown","cpuMillicores","memoryMb","minScale","maxScale","selectable"],"properties":{"code":{"type":"string","enum":["euro-small","euro-medium","euro-large","euro-xlarge","existing-unmanaged"]},"label":{"type":"string"},"limitsKnown":{"type":"boolean"},"cpuMillicores":{"type":["integer","null"]},"memoryMb":{"type":["integer","null"]},"minScale":{"type":["integer","null"]},"maxScale":{"type":["integer","null"]},"burnMultiplier":{"type":["string","null"]},"workloadGuidance":{"type":["string","null"]},"equivalentIncludedRuntimeHours":{"type":["string","null"]},"unavailableReason":{"type":["string","null"]},"recoveryAction":{"type":["string","null"]},"selectable":{"type":"boolean"}}},"ProjectContainerDefaults":{"type":"object","required":["runtimeTier","defaultRuntimeTierCode","runtimeTierOptions","planRuntimeAllowance"],"properties":{"runtimeTier":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"},{"type":"null"}]},"defaultRuntimeTierCode":{"type":["string","null"]},"runtimeTierOptions":{"type":"array","items":{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"}},"planRuntimeAllowance":{"oneOf":[{"type":"object","required":["smallEquivalentHours","maxScale"],"properties":{"smallEquivalentHours":{"type":"string"},"maxScale":{"type":"integer"}}},{"type":"null"}]},"unavailableReason":{"type":["string","null"]},"recoveryAction":{"type":["string","null"]}}},"ProjectContainerActionAvailability":{"type":"object","required":["canDeploy","canRedeploy","blockedReason","recoveryAction","targetContainerId"],"properties":{"canDeploy":{"type":"boolean"},"canRedeploy":{"type":"boolean"},"blockedReason":{"type":["string","null"],"enum":["not-authorized","container-not-configured","container-deploy-in-flight","container-delete-in-flight","container-tier-unmanaged","container-source-project-repo-missing","container-source-installation-missing","container-image-ref-required","container-runtime-tier-unavailable","project-key-revoked","project-provider-access-not-ready",null]},"recoveryAction":{"type":["string","null"],"enum":["configure_source","open_github","open_settings","request_plan_change",null]},"targetContainerId":{"type":["string","null"]}}},"ProjectContainerSecretStatusView":{"type":"object","required":["state","label","tone","canRestart"],"properties":{"state":{"type":"string","enum":["none","current","not_deployed","redeploy_required","restart_required","restart_queued","failed","unknown"]},"label":{"type":"string"},"tone":{"type":"string","enum":["ready","deploying","failed","draft"]},"canRestart":{"type":"boolean"}}},"ProjectContainerSourceIdentity":{"oneOf":[{"type":"object","additionalProperties":false,"required":["kind","framework","label"],"properties":{"kind":{"type":"string","enum":["configured_framework"]},"framework":{"type":"string","enum":["next","vite","astro","sveltekit","nuxt","node","express","nestjs","fastify","bun","deno","python","django","fastapi","flask","laravel","custom"]},"label":{"type":"string","enum":["Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime","Configured framework: Automatic runtime"]}}},{"type":"object","additionalProperties":false,"required":["kind","framework","label"],"properties":{"kind":{"type":"string","enum":["source"]},"framework":{"type":"null"},"label":{"type":"string","enum":["Source: Code build","Source: Dockerfile build","Source: Image registry"]}}}]},"ProjectContainer":{"type":"object","required":["id","organizationId","projectId","sourceType","accessMode","imageRef","sourceRootDir","sourceRunCommand","sourceFramework","sourceDockerfilePath","sourceCommitSha","containerName","containerHostname","containerPort","healthPath","runtimeTier","status","statusLabel","serving","customDomainStatus","configuredAt","lastDeployedAt","lastVerifiedAt","createdAt","updatedAt","latestDeployment","sourceIdentity","actionAvailability","route","secretStatusView"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"sourceType":{"type":"string","enum":["git","dockerfile","image"]},"accessMode":{"type":"string","enum":["public","private"]},"imageRef":{"type":["string","null"]},"sourceRootDir":{"type":"string"},"sourceRunCommand":{"type":["string","null"]},"sourceFramework":{"type":"string","enum":["auto","next","vite","astro","sveltekit","nuxt","node","express","nestjs","fastify","bun","deno","python","django","fastapi","flask","laravel","custom"]},"sourceDockerfilePath":{"type":["string","null"]},"sourceCommitSha":{"type":["string","null"]},"containerName":{"type":"string"},"containerHostname":{"type":["string","null"]},"containerPort":{"type":"integer"},"healthPath":{"type":"string"},"runtimeTier":{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"},"status":{"type":"string","enum":["draft","deploying","deleting","ready","failed"]},"statusLabel":{"type":"string"},"serving":{"$ref":"#/components/schemas/ProjectContainerServing"},"lastError":{"type":["string","null"]},"customDomainStatus":{"type":"string"},"configuredAt":{"type":"string","format":"date-time"},"lastDeployedAt":{"type":["string","null"],"format":"date-time"},"lastVerifiedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"sourceIdentity":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerSourceIdentity"},{"type":"null"}]},"actionAvailability":{"$ref":"#/components/schemas/ProjectContainerActionAvailability"},"route":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerRoute"},{"type":"null"}]},"secretStatusView":{"$ref":"#/components/schemas/ProjectContainerSecretStatusView"}}},"ProjectContainerListItem":{"type":"object","required":["id","organizationId","projectId","sourceType","accessMode","containerName","containerHostname","containerPort","healthPath","runtimeTier","status","statusLabel","serving","customDomainStatus","configuredAt","lastDeployedAt","lastVerifiedAt","createdAt","updatedAt","actionAvailability","route","secretStatusView"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"sourceType":{"type":"string","enum":["git","dockerfile","image"]},"accessMode":{"type":"string","enum":["public","private"]},"containerName":{"type":"string"},"containerHostname":{"type":["string","null"]},"containerPort":{"type":"integer"},"healthPath":{"type":"string"},"runtimeTier":{"$ref":"#/components/schemas/ProjectContainerRuntimeTier"},"status":{"type":"string","enum":["draft","deploying","deleting","ready","failed"]},"statusLabel":{"type":"string"},"serving":{"$ref":"#/components/schemas/ProjectContainerServing"},"lastError":{"type":["string","null"]},"customDomainStatus":{"type":"string"},"configuredAt":{"type":"string","format":"date-time"},"lastDeployedAt":{"type":["string","null"],"format":"date-time"},"lastVerifiedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"actionAvailability":{"$ref":"#/components/schemas/ProjectContainerActionAvailability"},"route":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerRoute"},{"type":"null"}]},"secretStatusView":{"$ref":"#/components/schemas/ProjectContainerSecretStatusView"}}},"ProjectContainerRequest":{"type":"object","description":"Project container source, route settings, optional inline startup secrets, and API-owned runtime tier code. CPU, memory, and scale are server-owned; payloads containing runtimeTier, tierId, cpuMillicores, memoryMb, memoryLimitMb, minScale, or maxScale are rejected with container-runtime-tier-not-configurable.","required":["sourceType"],"not":{"anyOf":[{"required":["runtimeTier"]},{"required":["tierId"]},{"required":["cpuMillicores"]},{"required":["memoryMb"]},{"required":["memoryLimitMb"]},{"required":["minScale"]},{"required":["maxScale"]}]},"properties":{"containerName":{"type":"string","minLength":2,"maxLength":41,"pattern":"^[a-z0-9][a-z0-9-]{1,40}$"},"sourceType":{"type":"string","enum":["git","dockerfile","image"]},"accessMode":{"type":"string","enum":["public","private"]},"imageRef":{"type":["string","null"]},"sourceRootDir":{"type":"string"},"sourceRunCommand":{"type":["string","null"]},"sourceFramework":{"type":"string","enum":["auto","next","vite","astro","sveltekit","nuxt","node","express","nestjs","fastify","bun","deno","python","django","fastapi","flask","laravel","custom"]},"sourceDockerfilePath":{"type":["string","null"]},"runtimeTierId":{"type":["string","null"],"enum":["euro-small","euro-medium","euro-large","euro-xlarge",null]},"containerPort":{"type":"integer","minimum":1,"maximum":65535},"healthPath":{"type":"string"},"secrets":{"type":"array","maxItems":64,"items":{"type":"object","required":["key","value"],"properties":{"key":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"isSecret":{"type":"boolean","default":true}}}}}},"ProjectContainerSourceDetectionProfile":{"type":"object","required":["branch","rootDirectory","sourceType","sourceFramework","containerPort","healthPath","frameworkLabel","detection","canUse"],"properties":{"repository":{"oneOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]},"fullName":{"type":"string"}}},{"type":"null"}]},"branch":{"type":"string"},"rootDirectory":{"type":"string"},"sourceType":{"type":"string","enum":["git","dockerfile"]},"sourceFramework":{"type":"string","enum":["auto","next","vite","astro","sveltekit","nuxt","node","express","nestjs","fastify","bun","deno","python","django","fastapi","flask","laravel","custom"]},"sourceRunCommand":{"type":["string","null"]},"sourceDockerfilePath":{"type":["string","null"]},"containerPort":{"type":"integer"},"healthPath":{"type":"string"},"frameworkLabel":{"type":"string"},"detection":{"$ref":"#/components/schemas/AppSourceDetection"},"canUse":{"type":"boolean"},"blockedReason":{"type":["string","null"]}}},"ProjectContainerSourceDetectionResponse":{"type":"object","required":["project","containerSourceProfile"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"containerSourceProfile":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainerSourceDetectionProfile"},{"type":"null"}]}}},"ProjectContainerResponse":{"type":"object","required":["ok","project","projectHealth","containerDefaults","container"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"anyOf":[{"$ref":"#/components/schemas/ProjectHealth"},{"type":"null"}]},"containerDefaults":{"$ref":"#/components/schemas/ProjectContainerDefaults"},"container":{"oneOf":[{"$ref":"#/components/schemas/ProjectContainer"},{"type":"null"}]}}},"ProjectContainersResponse":{"type":"object","required":["ok","project","projectHealth","containerDefaults","containers"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"anyOf":[{"$ref":"#/components/schemas/ProjectHealth"},{"type":"null"}]},"containerDefaults":{"$ref":"#/components/schemas/ProjectContainerDefaults"},"containers":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ProjectContainerListItem"}}}},"ProjectContainerMetricsScalar":{"type":"object","required":["value","unit"],"properties":{"value":{"type":["number","string","null"]},"unit":{"type":"string"}}},"ProjectContainerMetricsResponse":{"type":"object","required":["ok","project","container","timeRange","windowStart","windowEnd","windowGranularity","bucketStarts","availability","serviceLevel","requestsByStatus","slowRequestPaths","runtimeUsage","latestSignals","updatedAt"],"properties":{"ok":{"type":"boolean"},"project":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"container":{"type":"object","required":["id","name","hostname"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"hostname":{"type":["string","null"]}}},"timeRange":{"type":"string","enum":["30m","6h","24h","7d"]},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"},"windowGranularity":{"type":"string"},"bucketStarts":{"type":"array","items":{"type":"string","format":"date-time"}},"availability":{"type":"string","enum":["ready","partial","unavailable","empty"]},"serviceLevel":{"type":"object","required":["availability","totalRequests","successfulRequests","successfulRequestRate","fourXxRate","fiveXxRate","p95ResponseTimeMs","timeline"],"properties":{"availability":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"totalRequests":{"type":"integer","minimum":0},"successfulRequests":{"type":"integer","minimum":0},"successfulRequestRate":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"fourXxRate":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"fiveXxRate":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"p95ResponseTimeMs":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"timeline":{"type":"array","items":{"type":"object","required":["bucketStart","bucketEnd","totalRequests","successfulRequests","statusClasses","availability"],"properties":{"bucketStart":{"type":"string","format":"date-time"},"bucketEnd":{"type":"string","format":"date-time"},"totalRequests":{"type":"integer","minimum":0},"successfulRequests":{"type":"integer","minimum":0},"statusClasses":{"type":"object","required":["2xx","3xx","4xx","5xx"],"properties":{"2xx":{"type":"integer","minimum":0},"3xx":{"type":"integer","minimum":0},"4xx":{"type":"integer","minimum":0},"5xx":{"type":"integer","minimum":0}}},"availability":{"type":"string","enum":["empty","healthy","warning","error"]}}}}}},"requestsByStatus":{"type":"object","required":["totals","buckets"],"properties":{"totals":{"type":"object","required":["2xx","3xx","4xx","5xx"],"properties":{"2xx":{"type":"integer","minimum":0},"3xx":{"type":"integer","minimum":0},"4xx":{"type":"integer","minimum":0},"5xx":{"type":"integer","minimum":0}}},"buckets":{"type":"array","items":{"type":"object"}}}},"slowRequestPaths":{"type":"object","required":["items"],"properties":{"items":{"type":"array","maxItems":5,"items":{"type":"object","required":["requestPath","p95Ms","count","lastSeenAt"],"properties":{"requestPath":{"type":"string","maxLength":8000},"p95Ms":{"type":["number","null"]},"count":{"type":"integer","minimum":0},"lastSeenAt":{"type":["string","null"],"format":"date-time"}}}}}},"runtimeUsage":{"type":"object","required":["availability","reason","window","activeSeconds","cpuSeconds","memoryGbSeconds"],"properties":{"availability":{"type":"string","enum":["ready","unavailable"]},"reason":{"type":["string","null"]},"workerEvent":{"type":"object","description":"Present on a Workers project row the app host shipped (ADR 0076 contract §5a).","properties":{"kind":{"type":"string","enum":["console","runtime","dropped","stopped","startup-failed"]},"origin":{"type":"string","enum":["worker","platform"]},"level":{"type":["string","null"]},"reason":{"type":["string","null"]},"count":{"type":["integer","null"]}}},"workerRequest":{"type":"object","description":"Present on a Workers route Gateway access row: how the request was served. path never carries the query string.","properties":{"outcome":{"type":"string","enum":["ok","app-error","refused","suspended","startup-failed","instance-stopped","platform-restart","crashed","timeout","interrupted","gateway"]},"billed":{"type":["boolean","null"]},"cold":{"type":["boolean","null"]},"appClass":{"type":["string","null"]},"cause":{"type":"string","enum":["oom","watchdog","recycle-drain","crash"]},"path":{"type":["string","null"]}}},"window":{"type":"object","required":["code","startAt","endAt"],"properties":{"code":{"type":"string","enum":["current_billing_month"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"}}},"activeSeconds":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"cpuSeconds":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"},"memoryGbSeconds":{"$ref":"#/components/schemas/ProjectContainerMetricsScalar"}}},"latestSignals":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object"}}}},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectContainerMetricsErrorResponse":{"type":"object","properties":{"error":{"type":["string","null"]},"reason":{"type":["string","null"]}}},"ProjectContainerServingResponse":{"type":"object","required":["containerId","changed","serving"],"properties":{"containerId":{"type":"string"},"changed":{"type":"boolean"},"serving":{"$ref":"#/components/schemas/ProjectContainerServing"}}},"ProjectContainerServing":{"type":"object","required":["state","stoppedAt"],"properties":{"state":{"type":"string","enum":["serving","stopped"]},"stoppedAt":{"type":["string","null"],"format":"date-time"}}},"ProjectContainerDeployResponse":{"allOf":[{"$ref":"#/components/schemas/ProjectContainerResponse"},{"type":"object","required":["deployment"],"properties":{"deployment":{"$ref":"#/components/schemas/Deployment"}}}]},"ProjectContainerDeployConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"message":{"type":["string","null"]},"reason":{"type":"string","enum":["container-not-configured","container-deploy-in-flight","container-tier-unmanaged","container-source-project-repo-missing","container-source-installation-missing","project-key-revoked","project-provider-access-not-ready"]}}},"ProjectContainerConfigErrorResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["container-runtime-tier-not-configurable"]}}},"ProjectContainerDeleteConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["container-delete-in-flight","container-runtime-cleanup-incomplete"]},"detail":{"type":["string","null"]},"skipped":{"type":"array","items":{"type":"string"}}}},"FunctionDeployment":{"type":"object","additionalProperties":false,"required":["id","organizationId","projectId","functionId","sourceType","status","statusLabel","createdByUserId","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"functionId":{"type":"string"},"sourceType":{"type":"string","enum":["managed","git"]},"packageRef":{"type":["string","null"]},"status":{"type":"string","enum":["queued","deploying","ready","failed"]},"statusLabel":{"type":"string"},"lastError":{"type":["string","null"]},"createdByUserId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"FunctionActionAvailability":{"type":"object","required":["canDeploy","blockedReason","recoveryAction","targetFunctionId"],"additionalProperties":false,"properties":{"canDeploy":{"type":"boolean"},"blockedReason":{"type":["string","null"],"enum":["not-authorized","project-pending-delete","function-deploy-in-flight","function-deleted","function-cron-metering-unavailable","project-provider-access-not-ready",null]},"recoveryAction":{"type":["string","null"],"enum":["open_settings",null]},"targetFunctionId":{"type":["string","null"]}}},"FunctionRouteConvergence":{"type":"object","required":["state","reasonCode","statusLabel","statusMessage","pollRecommended"],"additionalProperties":false,"properties":{"state":{"type":"string","enum":["idle","deploying","route_pending","access_pending","proof_pending","ready","failed"]},"reasonCode":{"type":"string"},"statusLabel":{"type":"string"},"statusMessage":{"type":"string"},"pollRecommended":{"type":"boolean"}}},"FunctionStatusDeployment":{"type":"object","required":["id","status","statusLabel","createdAt","updatedAt"],"additionalProperties":false,"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","deploying","ready","failed"]},"statusLabel":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"FunctionRoute":{"type":"object","required":["status","statusLabel","accessMode","reasonCode","statusMessage"],"properties":{"hostname":{"type":["string","null"]},"path":{"type":["string","null"]},"productUrl":{"type":["string","null"],"format":"uri"},"accessMode":{"type":"string","enum":["public","private"]},"status":{"type":"string","enum":["pending","ready","failed"]},"statusLabel":{"type":"string"},"reasonCode":{"type":"string"},"statusMessage":{"type":"string"}}},"FunctionAsset":{"type":"object","description":"Role-authorized function fields. Internal query aliases, deployment source copies and raw provider metadata are not exposed.","required":["id","organizationId","projectId","name","sourceMode","entryPath","runtime","triggerType","authMode","authModeLabel","deploymentCount","status","statusLabel","actionAvailability","routeConvergence","createdByUserId","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"name":{"type":"string"},"sourceMode":{"type":"string","enum":["managed","git"]},"entryPath":{"type":"string"},"sourceFiles":{"description":"Present for project owners/admins. Omitted from contributor-readable function payloads.","type":"array","items":{"$ref":"#/components/schemas/FunctionSourceFile"}},"runtime":{"type":"string","enum":["deno_ts"]},"triggerType":{"type":"string","enum":["http","cron"]},"authMode":{"type":"string","enum":["public","signed"]},"authModeLabel":{"type":"string"},"deploymentCount":{"type":"integer"},"cronSchedule":{"type":["string","null"]},"status":{"type":"string","enum":["draft","deploying","ready","failed","deleted"]},"statusLabel":{"type":"string"},"route":{"oneOf":[{"$ref":"#/components/schemas/FunctionRoute"},{"type":"null"}]},"activeDeploymentId":{"type":["string","null"]},"actionAvailability":{"$ref":"#/components/schemas/FunctionActionAvailability"},"routeConvergence":{"$ref":"#/components/schemas/FunctionRouteConvergence"},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/FunctionDeployment"},{"type":"null"}]},"createdByUserId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"FunctionStatusProjection":{"type":"object","required":["id","projectId","status","statusLabel","route","latestDeployment","actionAvailability","routeConvergence","updatedAt"],"additionalProperties":false,"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"status":{"type":"string","enum":["draft","deploying","ready","failed","deleted"]},"statusLabel":{"type":"string"},"route":{"oneOf":[{"$ref":"#/components/schemas/FunctionRoute"},{"type":"null"}]},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/FunctionStatusDeployment"},{"type":"null"}]},"actionAvailability":{"$ref":"#/components/schemas/FunctionActionAvailability"},"routeConvergence":{"$ref":"#/components/schemas/FunctionRouteConvergence"},"updatedAt":{"type":"string","format":"date-time"}}},"FunctionStatusResponse":{"type":"object","required":["function"],"additionalProperties":false,"properties":{"function":{"$ref":"#/components/schemas/FunctionStatusProjection"}}},"FunctionLogEntry":{"type":"object","required":["id","level","message","observedAt"],"additionalProperties":false,"properties":{"id":{"type":"string"},"level":{"type":"string"},"message":{"type":"string"},"observedAt":{"type":"string","format":"date-time"},"payload":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"category":{"type":"string"},"functionDeploymentId":{"type":"string"},"method":{"type":"string"},"pathClass":{"type":"string"},"outcome":{"type":"string"},"failureCode":{"type":["string","null"]},"httpStatus":{"type":"integer"},"totalDurationMs":{"type":"integer"},"crashRecovered":{"type":"boolean"}}},{"type":"null"}]}}},"FunctionSourceFile":{"type":"object","required":["path","content"],"properties":{"path":{"type":"string"},"content":{"type":"string"}}},"FunctionCreateRequest":{"type":"object","required":["name","entryPath","sourceFiles"],"properties":{"name":{"type":"string"},"entryPath":{"type":"string"},"sourceFiles":{"type":"array","items":{"$ref":"#/components/schemas/FunctionSourceFile"}},"triggerType":{"type":"string","enum":["http","cron"]},"authMode":{"type":"string","enum":["public","signed"]},"cronSchedule":{"type":["string","null"]}}},"FunctionUpdateRequest":{"type":"object","properties":{"name":{"type":"string"},"entryPath":{"type":"string"},"sourceFiles":{"type":"array","items":{"$ref":"#/components/schemas/FunctionSourceFile"}},"triggerType":{"type":"string","enum":["http","cron"]},"authMode":{"type":"string","enum":["public","signed"]},"cronSchedule":{"type":["string","null"]}}},"ProjectFunctionsResponse":{"type":"object","required":["project","functions","nextCursor","limit","functionCount"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"functions":{"type":"array","items":{"$ref":"#/components/schemas/FunctionAsset"}},"nextCursor":{"type":["string","null"]},"limit":{"type":"integer","minimum":1,"maximum":50},"functionCount":{"type":"integer"}}},"FunctionResponse":{"type":"object","required":["project","function","deployments","nextCursor","limit","requestVolume"],"properties":{"nextCursor":{"type":"string","nullable":true},"limit":{"type":"integer","minimum":1,"maximum":100},"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"},"deployments":{"type":"array","items":{"$ref":"#/components/schemas/FunctionDeployment"}},"requestVolume":{"type":"object","required":["timeRange","requests"],"properties":{"timeRange":{"type":"string","enum":["24h"]},"requests":{"type":"integer","minimum":0}}}}},"FunctionMetricSeries":{"type":"object","required":["availability","unit","aggregation","value","series","updatedAt","reason"],"properties":{"availability":{"type":"string","enum":["ready","partial","unavailable"]},"unit":{"type":"string","enum":["percent","bytes","count"]},"aggregation":{"type":"string","enum":["average","maximum"]},"value":{"type":["string","null"]},"series":{"type":"array","items":{"type":["string","null"]}},"updatedAt":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"],"enum":["metrics-unavailable","metrics-not-ready","metrics-source-unavailable","metrics-source-stale","metrics-empty",null]}}},"FunctionCpuTimeDiagnostics":{"type":"object","required":["meaning","unit","aggregation","sumMs","series","sampleCount","lastObservedAt"],"properties":{"meaning":{"const":"terminated-worker-lifetime"},"unit":{"const":"millisecond"},"aggregation":{"const":"sum"},"sumMs":{"type":["string","null"]},"series":{"type":"array","items":{"type":["string","null"]}},"sampleCount":{"type":"integer","minimum":0},"lastObservedAt":{"type":["string","null"],"format":"date-time"}}},"FunctionMemoryDiagnostics":{"type":"object","required":["meaning","unit","aggregation","maxBytes","series","sampleCount","lastObservedAt"],"properties":{"meaning":{"const":"sampled-worker-heap-plus-external"},"unit":{"const":"bytes"},"aggregation":{"const":"maximum"},"maxBytes":{"type":["string","null"]},"series":{"type":"array","items":{"type":["string","null"]}},"sampleCount":{"type":"integer","minimum":0},"lastObservedAt":{"type":["string","null"],"format":"date-time"}}},"FunctionResourceDiagnostics":{"type":"object","required":["bestEffort","cpuTime","memory"],"properties":{"bestEffort":{"const":true},"cpuTime":{"$ref":"#/components/schemas/FunctionCpuTimeDiagnostics"},"memory":{"$ref":"#/components/schemas/FunctionMemoryDiagnostics"}}},"FunctionResponseStatusMetric":{"type":"object","required":["availability","unit","aggregation","value","series","classes","updatedAt","reason"],"properties":{"availability":{"type":"string","enum":["ready","unavailable"]},"unit":{"type":"string","enum":["percent"]},"aggregation":{"type":"string","enum":["distribution"]},"value":{"type":["string","null"]},"series":{"type":"array","description":"Reserved for future per-bucket status distribution; currently empty because the API returns window-level status classes.","items":{"type":["string","null"]}},"classes":{"type":"array","items":{"type":"object","required":["statusClass","value","count"],"properties":{"statusClass":{"type":"string","enum":["2xx","3xx","4xx","5xx"]},"value":{"type":["string","null"]},"count":{"type":["string","null"]}}}},"updatedAt":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"],"enum":["metrics-unavailable","metrics-not-ready","metrics-source-unavailable","metrics-source-stale","metrics-empty",null]}}},"FunctionServiceLevelMetric":{"type":"object","required":["value","unit"],"properties":{"value":{"type":["number","string","null"]},"unit":{"type":"string","enum":["percent","millisecond"]}}},"FunctionServiceLevel":{"type":"object","description":"Function Access traffic for the window through the read time, including requests already recorded in the in-progress interval. A live window is evaluated as of the oldest open Gateway store cut, which must be at most 7 minutes old; windows ending before that cut are evaluated strictly.","required":["trafficAvailability","asOf","availability","totalRequests","successfulRequests","successfulRequestRate","fourXxRate","fiveXxRate","p95ResponseTimeMs","timeline"],"properties":{"trafficAvailability":{"type":"string","enum":["ready","partial","unavailable"],"description":"ready: coverage is complete as of asOf; partial: recorded values are shown but some requests may be unconfirmed; unavailable: no request is recorded and the window is not confirmed empty."},"asOf":{"type":["string","null"],"format":"date-time","description":"Combined Gateway store cut the coverage is evaluated at."},"availability":{"$ref":"#/components/schemas/FunctionServiceLevelMetric"},"totalRequests":{"type":["integer","null"],"minimum":0,"description":"Null when no request is recorded and the window is not confirmed empty."},"successfulRequests":{"type":["integer","null"],"minimum":0},"successfulRequestRate":{"$ref":"#/components/schemas/FunctionServiceLevelMetric"},"fourXxRate":{"$ref":"#/components/schemas/FunctionServiceLevelMetric"},"fiveXxRate":{"$ref":"#/components/schemas/FunctionServiceLevelMetric"},"p95ResponseTimeMs":{"$ref":"#/components/schemas/FunctionServiceLevelMetric"},"timeline":{"type":"array","description":"At most 36 cells aligned to windowStart through windowEnd, plus one in-progress cell from windowEnd to the read time when the read falls inside a 5-minute interval.","items":{"type":"object","required":["bucketStart","bucketEnd","totalRequests","successfulRequests","statusClasses","trafficAvailability","asOf","availability"],"properties":{"bucketStart":{"type":"string","format":"date-time"},"bucketEnd":{"type":"string","format":"date-time"},"totalRequests":{"type":["integer","null"],"minimum":0},"successfulRequests":{"type":["integer","null"],"minimum":0},"statusClasses":{"type":"object","required":["2xx","3xx","4xx","5xx"],"properties":{"2xx":{"type":"integer","minimum":0},"3xx":{"type":"integer","minimum":0},"4xx":{"type":"integer","minimum":0},"5xx":{"type":"integer","minimum":0}}},"trafficAvailability":{"type":"string","enum":["ready","partial","unavailable"]},"asOf":{"type":["string","null"],"format":"date-time"},"availability":{"type":"string","enum":["empty","healthy","warning","error"]}}}}}},"FunctionMetricsResponse":{"type":"object","required":["project","function","timeRange","windowStart","windowEnd","bucketStarts","availability","serviceLevel","resourceDiagnostics","metrics"],"properties":{"project":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"function":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"timeRange":{"type":"string","enum":["15m","1h","3h","1d"]},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time","description":"End of the completed 5-minute grid used by the resource series."},"bucketStarts":{"type":"array","items":{"type":"string","format":"date-time"}},"availability":{"type":"string","enum":["ready","partial","unavailable"]},"serviceLevel":{"$ref":"#/components/schemas/FunctionServiceLevel"},"resourceDiagnostics":{"$ref":"#/components/schemas/FunctionResourceDiagnostics"},"metrics":{"type":"object","required":["cpuUsage","memoryUsage","instances","responseStatus"],"properties":{"cpuUsage":{"$ref":"#/components/schemas/FunctionMetricSeries"},"memoryUsage":{"$ref":"#/components/schemas/FunctionMetricSeries"},"instances":{"$ref":"#/components/schemas/FunctionMetricSeries"},"responseStatus":{"$ref":"#/components/schemas/FunctionResponseStatusMetric"}}}}},"FunctionMutationResponse":{"type":"object","required":["ok","project","function"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"}}},"FunctionDeploymentResponse":{"type":"object","required":["ok","project","function","deployment"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"},"deployment":{"$ref":"#/components/schemas/FunctionDeployment"}}},"FunctionDeploymentsResponse":{"type":"object","required":["project","function","deployments","nextCursor","limit"],"properties":{"nextCursor":{"type":"string","nullable":true},"limit":{"type":"integer","minimum":1,"maximum":100},"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"},"deployments":{"type":"array","items":{"$ref":"#/components/schemas/FunctionDeployment"}}}},"ProjectHealth":{"type":"object","required":["lifecycleState","overallState","reasonCode","keyState","providerIdentityState","driftState"],"properties":{"lifecycleState":{"type":"string","enum":["provisioning","ready","pending_delete","delete_failed"]},"overallState":{"type":"string","enum":["provisioning","ready","degraded","blocked","failed","pending_delete","delete_failed"]},"reasonCode":{"type":"string","enum":["none","project_key_missing","project_key_revoked","provider_identity_missing","provider_identity_not_ready","provider_bucket_missing","provider_drift_detected","provider_provisioning_failed","provider_delete_failed"]},"keyState":{"type":"string","enum":["pending","active","revoked"]},"providerIdentityState":{"type":"string","enum":["provisioning","ready","degraded","blocked","failed","pending_delete","delete_failed"]},"driftState":{"type":"string","enum":["in_sync","degraded","unknown"]},"keyLastUsedAt":{"type":["string","null"],"format":"date-time"},"keyLastRotatedAt":{"type":["string","null"],"format":"date-time"},"providerLastReconciledAt":{"type":["string","null"],"format":"date-time"},"providerRevokedAt":{"type":["string","null"],"format":"date-time"}}},"ProjectApiKey":{"type":"object","required":["id","organizationId","projectId","name","createdAt","updatedAt","status"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"lastRotatedAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string","enum":["pending","active","revoked"]}}},"ProjectProviderIdentity":{"type":"object","required":["id","provider","status","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"provider":{"type":"string"},"status":{"type":"string","enum":["provisioning","ready","degraded","blocked","failed","pending_delete","delete_failed"]},"lastReconciledAt":{"type":["string","null"],"format":"date-time"},"lastRotatedAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectApiKeyResponse":{"type":"object","required":["ok","project","projectHealth","projectApiKey"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"anyOf":[{"$ref":"#/components/schemas/ProjectHealth"},{"type":"null"}]},"projectApiKey":{"anyOf":[{"$ref":"#/components/schemas/ProjectApiKey"},{"type":"null"}]}}},"ProjectApiKeyRevealResponse":{"type":"object","required":["ok","project","projectHealth","projectApiKey","projectKey"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectHealth":{"$ref":"#/components/schemas/ProjectHealth"},"projectApiKey":{"$ref":"#/components/schemas/ProjectApiKey"},"projectKey":{"type":"string"}}},"ProjectLogEntry":{"type":"object","required":["id","assetType","assetId","severity","category","eventType","message","redacted","truncated","payloadSummary","observedAt","ingestedAt"],"properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["app","service","function","deployment","container","runtime","storage","static"]},"assetId":{"type":"string"},"assetName":{"type":["string","null"]},"deploymentId":{"type":["string","null"]},"severity":{"type":"string","enum":["info","warning","error"]},"logKind":{"type":["string","null"],"enum":["build","deploy","runtime","network","event",null]},"stream":{"type":["string","null"],"enum":["stdout","stderr","system",null]},"source":{"type":["string","null"],"enum":["builder","runner","deploy","health","gateway","runtime","api","storage","function",null]},"category":{"type":"string"},"eventType":{"type":["string","null"]},"message":{"type":"string"},"redacted":{"type":"boolean"},"truncated":{"type":"boolean"},"truncationReason":{"type":["string","null"]},"payloadSummary":{"type":["string","null"]},"requestId":{"type":["string","null"]},"method":{"type":["string","null"]},"requestTarget":{"type":["string","null"],"maxLength":8000},"pathClass":{"type":["string","null"]},"statusCode":{"type":["integer","null"]},"statusClass":{"type":["string","null"]},"latencyMs":{"type":["integer","null"]},"sourceIp":{"type":["string","null"]},"sourceGeo":{"$ref":"#/components/schemas/ProjectLogSourceGeo"},"sourceNetworkHash":{"type":["string","null"]},"userAgentFamily":{"type":["string","null"]},"reason":{"type":["string","null"]},"blocked":{"type":["object","null"],"description":"A grouped Mini WAF block row (ADR 0109): its exact count, first time, most active client IPs and user-agent families. Kind path is one URL; urls is several URLs of one scope, minute and method, named in urls (most blocked first, at most 50) with their exact distinct count; not_recorded is blocks the Gateway counted but could not record.","required":["kind","count","firstObservedAt","distinctIps","ips","userAgentFamilies","distinctUrls","urls"],"properties":{"kind":{"type":"string","enum":["path","urls","not_recorded"]},"distinctUrls":{"type":["integer","null"],"minimum":1},"urls":{"type":"array","maxItems":50,"items":{"type":"object","required":["url","count"],"properties":{"url":{"type":"string"},"count":{"type":"integer","minimum":0}}}},"count":{"type":"integer","minimum":1},"firstObservedAt":{"type":["string","null"],"format":"date-time"},"distinctIps":{"type":"integer","minimum":0},"ips":{"type":"array","maxItems":50,"items":{"type":"object","required":["ip","count"],"properties":{"ip":{"type":"string"},"count":{"type":"integer","minimum":0}}}},"userAgentFamilies":{"type":"array","items":{"type":"object","required":["family","count"],"properties":{"family":{"type":"string","enum":["Chrome","Firefox","Safari","curl","bot","other","unknown"]},"count":{"type":"integer","minimum":1}}}}}},"providerReady":{"type":["boolean","null"]},"gatewayStatusCode":{"type":["integer","null"],"minimum":100,"maximum":599},"gatewayRouteMatched":{"type":["boolean","null"]},"gatewayAppRespondedOk":{"type":["boolean","null"]},"gatewayTlsOk":{"type":["boolean","null"]},"probeAttempts":{"type":["integer","null"],"minimum":0,"maximum":100},"observedAt":{"type":"string","format":"date-time"},"ingestedAt":{"type":"string","format":"date-time"}}},"ProjectLogSourceGeo":{"type":["object","null"],"required":["label","countryCode","country","regionCode","region","city"],"properties":{"label":{"type":"string"},"countryCode":{"type":"string"},"country":{"type":"string"},"regionCode":{"type":["string","null"]},"region":{"type":["string","null"]},"city":{"type":["string","null"]}}},"ProjectLogAsset":{"type":"object","required":["assetType","assetId","assetName"],"properties":{"assetType":{"type":"string","enum":["app","service","function","deployment","container","runtime","storage","static"]},"assetId":{"type":"string"},"assetName":{"type":["string","null"]}}},"RuntimeLogState":{"type":"object","required":["status","reason","checkedAt","lastSuccessAt"],"properties":{"status":{"type":"string","enum":["ready","empty","blocked","delayed","failed","unavailable"]},"reason":{"type":["string","null"],"enum":["runtime-log-access-blocked","runtime-log-collection-delayed","runtime-log-collection-failed","runtime-log-source-unavailable",null]},"checkedAt":{"type":["string","null"],"format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"}}},"ProjectLogsResponse":{"type":"object","required":["project","revision","temporalEpoch","nextExpiryAt","filters","retentionPolicy","pagination","entries","runtimeLogState","accessLogState"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"revision":{"type":"string"},"temporalEpoch":{"type":["integer","null"],"minimum":0},"nextExpiryAt":{"type":["string","null"],"format":"date-time"},"filters":{"type":"object","required":["assetType","assetId","deploymentId","invocationId","severity","statusClass","method","statusCode","pathClass","excludePaths","hideBlocked","requestId","sourceNetwork","sourceIp","category","view","timeRange","from","to"],"properties":{"assetType":{"type":["string","null"],"enum":["app","service","function","deployment","container","runtime","storage","static",null]},"assetId":{"type":["string","null"]},"deploymentId":{"type":["string","null"]},"invocationId":{"type":["string","null"]},"severity":{"type":["string","null"],"enum":["info","warning","error",null]},"statusClass":{"type":["string","null"],"enum":["2xx","3xx","4xx","5xx",null]},"method":{"type":["string","null"]},"statusCode":{"type":["integer","null"]},"pathClass":{"type":["string","null"]},"excludePaths":{"type":"array","items":{"type":"string"},"maxItems":10},"hideBlocked":{"type":"boolean"},"requestId":{"type":["string","null"]},"sourceNetwork":{"type":["string","null"]},"sourceIp":{"type":["string","null"]},"category":{"type":["string","null"]},"view":{"type":["string","null"],"enum":["deployments","http","containers","functions","storage",null]},"timeRange":{"type":["string","null"],"enum":["1h","24h","7d","30d",null]},"from":{"type":["string","null"],"format":"date-time"},"to":{"type":["string","null"],"format":"date-time"}}},"retentionPolicy":{"type":"object","required":["maxEntriesPerCategory","maxAgeDays"],"properties":{"maxEntriesPerCategory":{"type":"integer"},"maxAgeDays":{"type":"integer"}}},"pagination":{"type":"object","required":["limit","nextCursor","hasMore"],"properties":{"limit":{"type":"integer","minimum":1,"maximum":50},"nextCursor":{"type":["string","null"]},"hasMore":{"type":"boolean"}}},"entries":{"type":"array","items":{"$ref":"#/components/schemas/ProjectLogEntry"}},"runtimeLogState":{"oneOf":[{"$ref":"#/components/schemas/RuntimeLogState"},{"type":"null"}]},"accessLogState":{"type":"object","required":["status","reason"],"properties":{"status":{"type":"string","enum":["ready","empty","delayed","unavailable"]},"reason":{"type":"string","enum":["access-log-ready","access-log-empty","access-log-delayed","access-log-unavailable"]},"checkedAt":{"type":["string","null"],"format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"}}}}},"ProjectLogSummary":{"type":"object","required":["total","newestObservedAt","oldestObservedAt","byAssetType","bySeverity","byCategory","byStatusClass","stderrCount","sourceIpCount","p95LatencyMs"],"properties":{"total":{"type":"integer"},"newestObservedAt":{"type":["string","null"],"format":"date-time"},"oldestObservedAt":{"type":["string","null"],"format":"date-time"},"byAssetType":{"type":"object","additionalProperties":{"type":"integer"}},"bySeverity":{"type":"object","additionalProperties":{"type":"integer"}},"byCategory":{"type":"object","additionalProperties":{"type":"integer"}},"byStatusClass":{"type":"object","additionalProperties":{"type":"integer"}},"stderrCount":{"type":"integer"},"sourceIpCount":{"type":["integer","null"]},"p95LatencyMs":{"type":["integer","null"]}}},"ProjectLogsSummaryResponse":{"type":"object","required":["project","revision","asOf","window","filters","summary"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"revision":{"type":"string"},"asOf":{"type":"string","format":"date-time","description":"DB read transaction start time; preserved when a completed snapshot is shared."},"window":{"type":"object","required":["from","to","temporalEpoch"],"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"temporalEpoch":{"type":["integer","null"]}}},"filters":{"type":"object","required":["assetType","assetId","deploymentId","invocationId","severity","statusClass","method","statusCode","pathClass","excludePaths","hideBlocked","requestId","sourceNetwork","sourceIp","category","view","timeRange","from","to"],"properties":{"assetType":{"type":["string","null"],"enum":["app","service","function","deployment","container","runtime","storage","static",null]},"assetId":{"type":["string","null"]},"deploymentId":{"type":["string","null"]},"invocationId":{"type":["string","null"]},"severity":{"type":["string","null"],"enum":["info","warning","error",null]},"statusClass":{"type":["string","null"],"enum":["2xx","3xx","4xx","5xx",null]},"method":{"type":["string","null"]},"statusCode":{"type":["integer","null"]},"pathClass":{"type":["string","null"]},"excludePaths":{"type":"array","items":{"type":"string"},"maxItems":10},"hideBlocked":{"type":"boolean"},"requestId":{"type":["string","null"]},"sourceNetwork":{"type":["string","null"]},"sourceIp":{"type":["string","null"]},"category":{"type":["string","null"]},"view":{"type":["string","null"],"enum":["deployments","http","containers","functions","storage",null]},"timeRange":{"type":["string","null"],"enum":["1h","24h","7d","30d",null]},"from":{"type":["string","null"],"format":"date-time"},"to":{"type":["string","null"],"format":"date-time"}}},"summary":{"$ref":"#/components/schemas/ProjectLogSummary"}}},"ProjectUsageSummary":{"type":"object","required":["metrics","retentionPolicy","attribution","updatedAt"],"properties":{"metrics":{"type":"object","required":["runtime_requests","runtime_response_bytes","runtime_latency_ms_sum","runtime_active_seconds","runtime_cpu_seconds","runtime_memory_gb_seconds","function_requests","function_execution_gb_seconds","storage_stored_bytes","storage_egress_bytes","storage_operations","build_seconds","stored_artifact_bytes","storage_bandwidth_bytes","centralized_log_bytes","workers_cpu_ms"],"properties":{"runtime_requests":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"runtime_response_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"runtime_latency_ms_sum":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"runtime_active_seconds":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"runtime_cpu_seconds":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"runtime_memory_gb_seconds":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"function_requests":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"function_execution_gb_seconds":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"storage_stored_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"storage_egress_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"storage_operations":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"build_seconds":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"stored_artifact_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"storage_bandwidth_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"centralized_log_bytes":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"workers_cpu_ms":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"}}},"retentionPolicy":{"type":"object","required":["tenantLogDays"],"properties":{"tenantLogDays":{"type":"integer"}}},"attribution":{"type":"object","required":["runtime","logs","storage","sharedOverhead"],"properties":{"runtime":{"type":"string"},"logs":{"type":"string"},"storage":{"type":"string"},"sharedOverhead":{"type":"string"}}},"updatedAt":{"type":"string","format":"date-time"}}},"BillingUsageState":{"type":"object","required":["state","label","meterAvailability","billingMonth"],"properties":{"state":{"type":"string","enum":["Estimated","Finalizing","Final"]},"label":{"type":"string"},"meterAvailability":{"type":"string","enum":["available","unavailable"]},"billingMonth":{"type":["string","null"]}}},"BillingSubscriptionState":{"type":"object","required":["state","label","planCode","currentPeriodEnd","cancelAtPeriodEnd","manageBillingAvailable"],"properties":{"state":{"type":"string","enum":["free","granted","processing","active","canceling","past_due","unpaid","canceled"]},"label":{"type":"string"},"planCode":{"type":["string","null"],"enum":["free","starter","pro",null]},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"},"cancelAtPeriodEnd":{"type":"boolean"},"manageBillingAvailable":{"type":"boolean"}}},"AccountBillingResponse":{"type":"object","required":["plan","scope","billingSubscription","canManageBilling","lastUpdatedAt"],"properties":{"plan":{"type":"object","required":["code","name","pricingVersion"],"properties":{"code":{"type":"string"},"name":{"type":"string"},"pricingVersion":{"type":["string","null"]}}},"scope":{"type":"object","required":["kind","organizationId","userId"],"properties":{"kind":{"type":"string","enum":["organization"]},"organizationId":{"type":["string","null"]},"userId":{"type":"null"}}},"billingSubscription":{"$ref":"#/components/schemas/BillingSubscriptionState"},"canManageBilling":{"type":"boolean"},"lastUpdatedAt":{"type":"string","format":"date-time"}}},"BillingCheckoutSessionResponse":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},"BillingPortalSessionResponse":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},"ProjectUsageResponse":{"type":"object","required":["project","window","lastUpdatedAt","status","usage","billingState","estimatedCost","period","summary"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"window":{"$ref":"#/components/schemas/UsageWindow"},"lastUpdatedAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["available","empty","unavailable"]},"usage":{"type":"array","items":{"$ref":"#/components/schemas/UsageMeterRow"}},"estimatedCost":{"anyOf":[{"$ref":"#/components/schemas/EstimatedCost"},{"type":"null"}]},"billingState":{"$ref":"#/components/schemas/BillingUsageState"},"period":{"type":"object","required":["startAt","endAt"],"properties":{"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"}}},"summary":{"$ref":"#/components/schemas/ProjectUsageSummary"}}},"UsageWindow":{"type":"object","required":["code","start","end"],"properties":{"code":{"type":"string","enum":["current_month","billing_month"]},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"UsageMeterRow":{"type":"object","description":"Usage meter value returned by the API. Derived account meters such as runtime_average_latency_ms are computed by the API from DB-owned counters and are not accepted as persisted usage metrics.","required":["code","label","unit","value"],"properties":{"code":{"type":"string"},"label":{"type":"string"},"unit":{"type":"string"},"value":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"}}},"EstimatedCost":{"type":"object","required":["currency","amount","label","pricingVersion"],"properties":{"currency":{"type":"string","enum":["EUR"]},"amount":{"type":"string","pattern":"^[0-9]+\\.[0-9]{2}$"},"label":{"type":"string"},"pricingVersion":{"type":"string"}}},"AccountActionQuota":{"type":"object","description":"Current API-owned abuse/action allowance. This is separate from monthly usage meters.","additionalProperties":false,"required":["actionCode","metricCode","label","used","limit","resetAt","state","plan","recoveryActions"],"properties":{"actionCode":{"type":"string","enum":["deploy"]},"metricCode":{"type":"string","enum":["deployments"]},"label":{"type":"string"},"used":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"limit":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"resetAt":{"type":"string","format":"date-time"},"state":{"type":"string","enum":["available","blocked"]},"plan":{"type":"object","additionalProperties":false,"required":["code","name","pricingVersion"],"properties":{"code":{"type":"string"},"name":{"type":"string"},"pricingVersion":{"type":["string","null"]}}},"recoveryActions":{"type":"array","uniqueItems":true,"items":{"type":"string","enum":["open_usage","wait_until_reset","request_plan_change"]}}}},"AccountUsageResponse":{"type":"object","required":["plan","scope","period","lastUpdatedAt","status","meters","runtimeUsage","estimatedCost","billingState","billingSubscription","actionQuotas","resourceContributors","projection"],"properties":{"plan":{"type":"object","required":["code","name","pricingVersion"],"properties":{"code":{"type":"string"},"name":{"type":"string"},"pricingVersion":{"type":["string","null"]}}},"scope":{"type":"object","required":["kind","organizationId","userId"],"properties":{"kind":{"type":"string","enum":["user","organization"]},"organizationId":{"type":["string","null"]},"userId":{"type":["string","null"]}}},"period":{"$ref":"#/components/schemas/UsageWindow"},"lastUpdatedAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["available","empty","unavailable"]},"meters":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/UsageMeterRow"},{"type":"object","required":["used","limit","resetAt","state","recoveryActions"],"properties":{"used":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"reserved":{"type":"string","description":"Build seconds held for builds in progress, separate from consumed usage."},"limit":{"type":["string","null"]},"resetAt":{"type":["string","null"],"format":"date-time"},"state":{"type":"string","enum":["ok","blocked","unavailable"]},"recoveryActions":{"type":"array","items":{"type":"string"}}}}]}},"runtimeUsage":{"oneOf":[{"type":"object","required":["label","usedSmallEquivalentHours","includedSmallEquivalentHours","remainingSmallEquivalentHours","state","sourceMeters","resetStrategy"],"properties":{"label":{"type":"string"},"usedSmallEquivalentHours":{"type":"string"},"includedSmallEquivalentHours":{"type":"string"},"remainingSmallEquivalentHours":{"type":"string"},"state":{"type":"string","enum":["ok","blocked"]},"sourceMeters":{"type":"array","items":{"type":"string"}},"resetStrategy":{"type":"string"}}},{"type":"null"}]},"estimatedCost":{"anyOf":[{"$ref":"#/components/schemas/EstimatedCost"},{"type":"null"}]},"billingState":{"$ref":"#/components/schemas/BillingUsageState"},"billingSubscription":{"$ref":"#/components/schemas/BillingSubscriptionState"},"actionQuotas":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/AccountActionQuota"}},"resourceContributors":{"type":"array","items":{"$ref":"#/components/schemas/AccountUsageResourceContributor"}},"projection":{"type":"object","required":["status","asOf","pendingCount","pendingCountIsLowerBound","quarantinedCount","quarantinedCountIsLowerBound","oldestPendingAt","lagMs"],"properties":{"status":{"type":"string","enum":["ready","applying","delayed","rebuilding","blocked","unavailable"]},"asOf":{"type":"string","format":"date-time"},"pendingCount":{"type":"integer","minimum":0},"pendingCountIsLowerBound":{"type":"boolean"},"quarantinedCountIsLowerBound":{"type":"boolean"},"quarantinedCount":{"type":"integer","minimum":0},"oldestPendingAt":{"type":["string","null"],"format":"date-time"},"lagMs":{"type":"integer","minimum":0}}}}},"AccountUsageResourceContributor":{"type":"object","required":["projectId","projectName","resourceType","resourceLabel","meter","estimatedCost","share","updatedAt"],"properties":{"projectId":{"type":"string"},"projectName":{"type":"string"},"resourceType":{"type":"string"},"resourceLabel":{"type":"string"},"meter":{"anyOf":[{"$ref":"#/components/schemas/UsageMeterRow"},{"type":"null"}]},"estimatedCost":{"anyOf":[{"$ref":"#/components/schemas/EstimatedCost"},{"type":"null"}]},"share":{"type":["number","null"],"minimum":0,"maximum":1},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"AccountUsageResourceContributorsResponse":{"type":"object","required":["resourceContributors"],"properties":{"resourceContributors":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/AccountUsageResourceContributor"}}}},"AccountUsageTimeSeriesPoint":{"type":"object","required":["start","end","value","state","final"],"properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"value":{"anyOf":[{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},{"type":"null"}]},"state":{"type":"string","enum":["available","empty","unavailable"]},"final":{"type":"boolean"}}},"AccountUsageTimeSeries":{"type":"object","required":["metricCode","unit","status","points"],"properties":{"metricCode":{"type":"string"},"unit":{"type":"string"},"status":{"type":"string","enum":["available","empty","unavailable","unsupported"]},"points":{"type":"array","maxItems":168,"items":{"$ref":"#/components/schemas/AccountUsageTimeSeriesPoint"}}}},"AccountUsageTimeSeriesResponse":{"type":"object","required":["range","bucket","window","series","generatedAt"],"properties":{"range":{"type":"string","enum":["24h","7d","30d","90d"]},"bucket":{"type":"string","enum":["1h","1d"]},"window":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"series":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/AccountUsageTimeSeries"}},"generatedAt":{"type":"string","format":"date-time"}}},"MeteringIngestRequest":{"type":"object","description":"The union of every counter sourceReservationIds array and every function request sourceReservationId must exactly equal the top-level sourceReservationIds set. Every row member must belong to that set. A batch contains at most 500 counters plus function requests and at most 2,000 contribution references.","required":["producerId","batchId","batchSequence","schemaVersion","sourceReservationIds"],"properties":{"producerId":{"type":"string"},"batchId":{"type":"string"},"batchSequence":{"type":"integer"},"schemaVersion":{"type":"string","const":"usage-metering.v2"},"sourceReservationIds":{"type":"array","minItems":1,"maxItems":500,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":160}},"observedAfter":{"type":["string","null"],"format":"date-time"},"counters":{"type":"array","maxItems":500,"items":{"type":"object","required":["projectId","resourceType","resourceId","metricCode","unit","windowStart","windowEnd","valueDecimal","sourceFamily","sourceReservationIds","observedAt"],"properties":{"organizationId":{"type":["string","null"]},"projectId":{"type":"string"},"resourceType":{"type":"string"},"resourceId":{"type":"string"},"metricCode":{"type":"string"},"unit":{"type":"string"},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"},"valueDecimal":{"type":"string","pattern":"^[0-9]+(?:\\.[0-9]+)?$"},"sourceFamily":{"type":"string"},"sourceReservationIds":{"type":"array","minItems":1,"maxItems":500,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":160}},"pricingVersion":{"type":["string","null"]},"observedAt":{"type":"string","format":"date-time"}}}},"functionRequests":{"type":"array","maxItems":500,"items":{"type":"object","required":["sourceReservationId","projectId","resourceType","resourceId","routeId","functionId","startedAt","finishedAt","httpStatus","latencyMs","outcome","sourceFamily"],"properties":{"sourceReservationId":{"type":"string","minLength":1,"maxLength":160},"projectId":{"type":"string"},"resourceType":{"type":"string","enum":["function"]},"resourceId":{"type":"string"},"routeId":{"type":"string"},"functionId":{"type":"string"},"deploymentId":{"type":["string","null"]},"method":{"type":["string","null"]},"normalizedPath":{"type":["string","null"]},"observedHost":{"type":["string","null"]},"startedAt":{"type":"string","format":"date-time"},"finishedAt":{"type":"string","format":"date-time"},"httpStatus":{"type":"integer"},"statusClass":{"type":["string","null"]},"latencyMs":{"type":"integer"},"responseBytes":{"type":"integer"},"outcome":{"type":"string","enum":["success","error","timeout"]},"sourceFamily":{"type":"string","enum":["gateway"]}}}}}},"AppHostBinary":{"type":"object","additionalProperties":false,"required":["version","maxCompatibilityDate","sha256"],"properties":{"version":{"type":"string","pattern":"^1\\.[0-9]{8}\\.[0-9]+$"},"maxCompatibilityDate":{"type":"string","format":"date"},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$"}}},"AppHostFactsV1":{"type":"object","additionalProperties":false,"required":["hostId","bootId","softwareRevision","vcpuCount","binaries","reportedAt"],"properties":{"hostId":{"type":"string","pattern":"^aph_[0-9a-f]{12}$"},"bootId":{"type":"string","format":"uuid"},"softwareRevision":{"type":"string","pattern":"^[0-9a-f]{40}$"},"vcpuCount":{"type":"integer","minimum":1,"maximum":256},"binaries":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"object","additionalProperties":false,"required":["version","maxCompatibilityDate","sha256"],"properties":{"version":{"type":"string","pattern":"^1\\.[0-9]{8}\\.[0-9]+$"},"maxCompatibilityDate":{"type":"string","format":"date"},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$"}}}},"reportedAt":{"type":"string","format":"date-time"}}},"AppHostFactsResult":{"type":"object","required":["disposition","mirrored"],"properties":{"disposition":{"type":"string","enum":["stored","unchanged","stale"]},"mirrored":{"type":"boolean","description":"The report is now the newest boot mirrored into app_hosts"}}},"AppHostUsageBatchV1":{"type":"object","additionalProperties":false,"required":["schemaVersion","hostId","bootId","records"],"properties":{"schemaVersion":{"type":"string","enum":["app-host-usage.v1"]},"hostId":{"type":"string","pattern":"^aph_[0-9a-f]{12}$"},"bootId":{"type":"string","format":"uuid"},"records":{"type":"array","minItems":1,"maxItems":500,"description":"Every element receives a disposition; malformed records receive rejected record_invalid.","items":{}}}},"AppHostUsageResults":{"type":"object","required":["results"],"description":"Results correspond to input records by array position. Invalid shapes may have null invocationId or seq.","properties":{"results":{"type":"array","items":{"type":"object","required":["invocationId","seq","disposition"],"properties":{"invocationId":{"oneOf":[{"type":"string"},{"type":"null"}]},"seq":{"oneOf":[{"type":"integer"},{"type":"null"}]},"disposition":{"type":"string","enum":["accepted","duplicate","rejected"]},"reason":{"type":"string","enum":["record_invalid","conflict","route_unknown","route_binding_mismatch","invocation_inconsistent","after_final","counter_regressed","cpu_bound_exceeded","outside_acceptance_window"]}}}}}},"AppHostLogsBatchV1":{"type":"object","additionalProperties":false,"required":["schemaVersion","hostId","bootId","streams"],"properties":{"schemaVersion":{"type":"string","enum":["app-host-logs.v1"]},"hostId":{"type":"string","pattern":"^aph_[0-9a-f]{12}$"},"bootId":{"type":"string","format":"uuid"},"streams":{"type":"array","minItems":1,"maxItems":64,"description":"One stream per unit start: routeId, deploymentId, projectId, releaseId, unitStartedAt and 1..500 records in total (kinds console, runtime, dropped, stopped, startup-failed). Every stream receives a disposition.","items":{}}}},"AppHostLogsResults":{"type":"object","required":["results"],"description":"Results correspond to input streams by array position.","properties":{"results":{"type":"array","items":{"type":"object","required":["index","routeId","disposition"],"properties":{"index":{"type":"integer"},"routeId":{"oneOf":[{"type":"string"},{"type":"null"}]},"disposition":{"type":"string","enum":["accepted","rejected"]},"reason":{"type":"string","enum":["stream_invalid","route_unknown","route_binding_mismatch","stream_unstorable"]}}}}}},"AppHostMembershipRequest":{"type":"object","required":["privateAddress","port","state","instanceId","zone"],"properties":{"privateAddress":{"type":"string","format":"ipv4","description":"A private IPv4 address"},"port":{"type":"integer","minimum":1024,"maximum":65535},"state":{"type":"string","enum":["provisioning","active","draining","retired"]},"instanceId":{"type":"string","format":"uuid"},"zone":{"type":"string","pattern":"^[a-z]{2}-[a-z]{3}-[1-9]$"},"capacityVcpu":{"type":"integer","minimum":1,"maximum":256,"description":"Operator-owned immutable CPU capacity; never taken from host facts"}}},"AppHostMembershipResponse":{"type":"object","required":["host","changed"],"properties":{"changed":{"type":"boolean"},"host":{"type":"object","required":["id","privateAddress","port","state","instanceId","zone","bootId","softwareRevision","binaries","factsReportedAt","createdAt","updatedAt","retiredAt"],"properties":{"id":{"type":"string"},"privateAddress":{"type":"string"},"port":{"type":"integer"},"state":{"type":"string","enum":["provisioning","active","draining","retired"]},"instanceId":{"type":"string"},"zone":{"type":"string"},"capacityVcpu":{"type":["integer","null"]},"bootId":{"type":["string","null"]},"softwareRevision":{"type":["string","null"]},"binaries":{"type":"array","items":{"type":"object"}},"binaryChange":{"type":["object","null"],"description":"Latest pending, applied or restored binary-set transition"},"factsReportedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"retiredAt":{"type":["string","null"],"format":"date-time"}}}}},"MeteringIngestResponse":{"type":"object","required":["id","producerId","batchId","batchSequence","schemaVersion","payloadFingerprint","replayed","status","acceptedRows","rejectedRows","receivedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"producerId":{"type":"string"},"batchId":{"type":"string"},"batchSequence":{"type":"integer"},"schemaVersion":{"type":"string","const":"usage-metering.v2"},"payloadFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"replayed":{"type":"boolean"},"status":{"type":"string","enum":["processing","accepted","partial","rejected"]},"acceptedRows":{"type":"integer"},"rejectedRows":{"type":"integer"},"receivedAt":{"type":"string","format":"date-time"},"processedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"rejectionSummary":{"$ref":"#/components/schemas/MeteringRejectionSummary"}}},"GatewayMeteringTerminalRecord":{"type":"object","additionalProperties":false,"allOf":[{"if":{"properties":{"resourceType":{"const":"app_route"}},"required":["resourceType"]},"then":{"required":["requestClass","deploymentId"]},"else":{"not":{"required":["requestClass"]}}}],"required":["gatewayInstanceId","reservationId","projectId","resourceType","resourceId","routeId","surfaceKind","minuteBucket","startedAt","httpStatus","statusClass","responseBytes","latencyMs","outcome","finishedAt"],"properties":{"gatewayInstanceId":{"type":"string"},"reservationId":{"type":"string"},"projectId":{"type":"string"},"organizationId":{"type":"string"},"resourceType":{"type":"string","enum":["container_route","domain_binding","static_storage_prefix","function","app_route"]},"resourceId":{"type":"string"},"routeId":{"type":"string"},"requestClass":{"type":"string","enum":["worker","asset","redirect","not_found","reserved","manifest_unavailable"],"description":"Required for app_route; immutable through Gateway WAL, receipt, and usage."},"routeRevisionId":{"type":"string","pattern":"^fnrev_[0-9a-f]{32}$"},"functionId":{"type":"string"},"deploymentId":{"type":"string"},"method":{"type":"string"},"normalizedPath":{"type":"string"},"observedHost":{"type":"string"},"surfaceKind":{"type":"string"},"minuteBucket":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"httpStatus":{"type":"integer","minimum":100,"maximum":599},"statusClass":{"type":"string"},"responseBytes":{"type":"integer","minimum":0},"latencyMs":{"type":"integer","minimum":0},"outcome":{"type":"string","enum":["success","error","timeout"]},"denyReason":{"type":"string"},"finishedAt":{"type":"string","format":"date-time"},"leaseId":{"type":"string"},"grantId":{"type":"string","pattern":"^fqg_[0-9a-f]{32}$"},"leaseSerial":{"type":"integer","minimum":1},"leaseOwnerBootId":{"type":"string"},"leaseAdmittedAt":{"type":"string","format":"date-time"},"executionLeaseId":{"type":"string"},"executionSerial":{"type":"integer","minimum":1},"admissionProtocol":{"type":"string"},"projectionVersion":{"type":"integer","minimum":1}}},"GatewayMeteringTerminalRecordV1":{"allOf":[{"$ref":"#/components/schemas/GatewayMeteringTerminalRecord"},{"not":{"anyOf":[{"required":["organizationId"]},{"required":["admissionProtocol"]},{"required":["projectionVersion"]},{"required":["resourceType","requestClass"],"properties":{"resourceType":{"const":"app_route"},"requestClass":{"const":"worker"}}}]}}]},"GatewayMeteringTerminalRecordV2":{"allOf":[{"$ref":"#/components/schemas/GatewayMeteringTerminalRecord"},{"required":["organizationId","deploymentId","method","normalizedPath","admissionProtocol","projectionVersion"],"properties":{"admissionProtocol":{"type":"string","const":"org-state-v1"}},"oneOf":[{"required":["routeRevisionId","functionId"],"properties":{"resourceType":{"const":"function"}}},{"required":["requestClass"],"properties":{"resourceType":{"const":"app_route"},"requestClass":{"const":"worker"}},"not":{"anyOf":[{"required":["routeRevisionId"]},{"required":["functionId"]}]}}],"not":{"anyOf":[{"required":["leaseId"]},{"required":["grantId"]},{"required":["leaseSerial"]},{"required":["leaseOwnerBootId"]},{"required":["leaseAdmittedAt"]},{"required":["executionLeaseId"]},{"required":["executionSerial"]}]}}]},"GatewayMeteringTerminalSourceV1":{"type":"object","additionalProperties":false,"required":["storeUid","walRecordId","sourceReservationId","terminal"],"properties":{"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"walRecordId":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}:[A-Za-z0-9._-]{1,160}:[0-9]{20}:(FINALIZE|RECOVERED)$"},"sourceReservationId":{"type":"string","minLength":1,"maxLength":160},"terminal":{"$ref":"#/components/schemas/GatewayMeteringTerminalRecordV1"}}},"GatewayMeteringTerminalSourceV2":{"type":"object","additionalProperties":false,"required":["storeUid","walRecordId","sourceReservationId","terminal"],"properties":{"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"walRecordId":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}:[A-Za-z0-9._-]{1,160}:[0-9]{20}:(FINALIZE|RECOVERED)$"},"sourceReservationId":{"type":"string","minLength":1,"maxLength":160},"terminal":{"$ref":"#/components/schemas/GatewayMeteringTerminalRecordV2"}}},"GatewayMeteringSourceEnvelopeRequest":{"oneOf":[{"type":"object","additionalProperties":false,"required":["producerId","schemaVersion","sources"],"properties":{"producerId":{"type":"string","pattern":"^gateway-gwevstore_[0-9a-f]{32}$"},"schemaVersion":{"type":"string","const":"gateway-metering-source.v1"},"sources":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/GatewayMeteringTerminalSourceV1"}}}},{"type":"object","additionalProperties":false,"required":["producerId","schemaVersion","sources"],"properties":{"producerId":{"type":"string","pattern":"^gateway-gwevstore_[0-9a-f]{32}$"},"schemaVersion":{"type":"string","const":"gateway-metering-source.v2"},"sources":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/GatewayMeteringTerminalSourceV2"}}}}]},"GatewayMeteringSourceResult":{"oneOf":[{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","sourceFingerprint","contributionFingerprint","status","statusCode","acknowledgement"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"status":{"type":"string","const":"accepted"},"statusCode":{"type":"integer","const":200},"acknowledgement":{"$ref":"#/components/schemas/GatewayMeteringSourceAcknowledgement"}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","sourceFingerprint","contributionFingerprint","status","statusCode","disposition","dispositionReceipt","acknowledgement"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"status":{"type":"string","enum":["accepted","exact_retry"]},"statusCode":{"type":"integer","const":200},"disposition":{"type":"string","const":"denied_nonbilling"},"dispositionReceipt":{"$ref":"#/components/schemas/GatewayMeteringDeniedNonbillingReceipt"},"acknowledgement":{"$ref":"#/components/schemas/GatewayMeteringDeniedNonbillingAcknowledgement"}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","sourceFingerprint","contributionFingerprint","status","statusCode","acknowledgement"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"status":{"type":"string","const":"exact_retry"},"statusCode":{"type":"integer","const":200},"acknowledgement":{"$ref":"#/components/schemas/GatewayMeteringSourceAcknowledgement"}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","sourceFingerprint","contributionFingerprint","status","statusCode","reason","dispositionReceipt"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"status":{"type":"string","const":"discarded_nonbilling"},"statusCode":{"type":"integer","const":200},"reason":{"type":"string","minLength":1},"dispositionReceipt":{"$ref":"#/components/schemas/GatewayMeteringNonbillingDiscardReceipt"}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","status","statusCode","reason"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"status":{"type":"string","const":"retryable_rejection"},"statusCode":{"type":"integer","enum":[429,503]},"reason":{"type":"string","minLength":1}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","status","statusCode","reason"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"nullable":true,"enum":[null]},"status":{"type":"string","const":"retryable_rejection"},"statusCode":{"type":"integer","const":503},"reason":{"type":"string","const":"gateway-metering-source-envelope-invalid"}}},{"type":"object","additionalProperties":false,"required":["sourceIndex","sourceReservationId","walRecordId","batchId","status","statusCode","reason"],"properties":{"sourceIndex":{"type":"integer","minimum":0},"sourceReservationId":{"type":"string"},"walRecordId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"status":{"type":"string","const":"conflict"},"statusCode":{"type":"integer","const":409},"reason":{"type":"string","minLength":1}}}]},"GatewayMeteringNonbillingDiscardReceipt":{"type":"object","additionalProperties":false,"required":["schemaVersion","id","authorizationFingerprint","approvalReference","authorizedAt","producerId","storeUid","walRecordId","sourceReservationId","batchId","sourceSequence","sourceSchemaVersion","sourceFingerprint","contributionFingerprint","payloadFingerprint","disposition","reason","discardedAt"],"properties":{"schemaVersion":{"type":"string","const":"gateway-metering-nonbilling-discard-receipt.v1"},"id":{"type":"string","pattern":"^gmsd_[0-9a-f]{32}$"},"authorizationFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"approvalReference":{"type":"string","minLength":1},"authorizedAt":{"type":"string","format":"date-time"},"producerId":{"type":"string","pattern":"^gateway-gwevstore_[0-9a-f]{32}$"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"walRecordId":{"type":"string"},"sourceReservationId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceSequence":{"type":"integer","minimum":0},"sourceSchemaVersion":{"type":"string","enum":["gateway-metering-source.v1","gateway-metering-source.v2"]},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"payloadFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"disposition":{"type":"string","const":"discarded_nonbilling"},"reason":{"type":"string","minLength":1},"discardedAt":{"type":"string","format":"date-time"}}},"GatewayMeteringDeniedNonbillingReceipt":{"type":"object","additionalProperties":false,"required":["schemaVersion","producerId","storeUid","walRecordId","sourceReservationId","batchId","sourceSequence","sourceSchemaVersion","sourceFingerprint","contributionFingerprint","payloadFingerprint","disposition","denyReason","settledAt","dispositionFingerprint"],"properties":{"schemaVersion":{"type":"string","const":"gateway-metering-denied-nonbilling-receipt.v1"},"producerId":{"type":"string","pattern":"^gateway-gwevstore_[0-9a-f]{32}$"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"walRecordId":{"type":"string"},"sourceReservationId":{"type":"string"},"batchId":{"type":"string","pattern":"^gwms_[0-9a-f]{64}$"},"sourceSequence":{"type":"integer","minimum":1},"sourceSchemaVersion":{"type":"string","enum":["gateway-metering-source.v1","gateway-metering-source.v2"]},"sourceFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"contributionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"payloadFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"disposition":{"type":"string","const":"denied_nonbilling"},"denyReason":{"type":"string","minLength":1},"settledAt":{"type":"string","format":"date-time"},"dispositionFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"GatewayMeteringSourceAcknowledgement":{"allOf":[{"$ref":"#/components/schemas/MeteringIngestResponse"},{"type":"object","required":["schemaVersion","status","rejectedRows"],"properties":{"schemaVersion":{"type":"string","enum":["gateway-metering-source.v1","gateway-metering-source.v2"]},"status":{"type":"string","const":"accepted"},"rejectedRows":{"type":"integer","const":0}}}]},"GatewayMeteringDeniedNonbillingAcknowledgement":{"allOf":[{"$ref":"#/components/schemas/GatewayMeteringSourceAcknowledgement"},{"type":"object","required":["acceptedRows","rejectedRows"],"properties":{"acceptedRows":{"type":"integer","const":0},"rejectedRows":{"type":"integer","const":0}}}]},"GatewayMeteringSourceEnvelopeResponse":{"type":"object","additionalProperties":false,"required":["ok","producerId","schemaVersion","results"],"properties":{"ok":{"type":"boolean","enum":[true]},"producerId":{"type":"string"},"schemaVersion":{"type":"string","enum":["gateway-metering-source.v1","gateway-metering-source.v2"]},"results":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/GatewayMeteringSourceResult"}}}},"GatewayMeteringTransientDbError":{"type":"object","additionalProperties":false,"required":["error","reason"],"properties":{"error":{"type":"string","const":"Database resource exhausted"},"reason":{"type":"string","const":"db-resource-exhausted"}}},"GatewayMeteringOperationTimeoutError":{"type":"object","additionalProperties":false,"required":["error","reason"],"properties":{"error":{"type":"string","const":"Service unavailable"},"reason":{"type":"string","const":"metering-operation-timeout"}}},"MeteringIdempotencyProofError":{"type":"object","additionalProperties":false,"required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","const":"metering-idempotency-proof-invalid"}}},"MeteringRejectionSummary":{"type":"object","required":["reason","reasonCounts","sampleRows","truncated"],"properties":{"reason":{"type":"string"},"reasonCounts":{"type":"array","items":{"type":"object","required":["reason","count"],"properties":{"reason":{"type":"string"},"count":{"type":"integer"}}}},"sampleRows":{"type":"array","items":{"type":"object","additionalProperties":true}},"truncated":{"type":"boolean"}}},"ProjectsUsageSummaryRow":{"type":"object","required":["metric","label","value","valueDisplay","progress"],"properties":{"metric":{"type":"string","enum":["runtime_requests","runtime_response_bytes","runtime_latency_ms_sum","runtime_active_seconds","runtime_cpu_seconds","runtime_memory_gb_seconds","function_requests","function_execution_gb_seconds","storage_stored_bytes","storage_egress_bytes","storage_operations","build_seconds","stored_artifact_bytes","storage_bandwidth_bytes","centralized_log_bytes"]},"label":{"type":"string"},"value":{"type":"string","pattern":"^[0-9]+$"},"valueDisplay":{"type":"string"},"progress":{"type":"number","minimum":0,"maximum":1}}},"ProjectsUsageSummary":{"type":"object","required":["period","rows","updatedAt"],"properties":{"period":{"type":"object","required":["startAt","endAt"],"properties":{"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"}}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ProjectsUsageSummaryRow"}},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectsResponse":{"type":"object","required":["projects","nextCursor","usageSummary"],"properties":{"projects":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ProjectCard"}},"nextCursor":{"type":["string","null"]},"usageSummary":{"oneOf":[{"$ref":"#/components/schemas/ProjectsUsageSummary"},{"type":"null"}]}}},"ProjectTelemetryCoverage":{"type":"object","required":["fullyIncluded","includedSubsurfaces","missingSubsurfaces"],"properties":{"fullyIncluded":{"type":"boolean"},"includedSubsurfaces":{"type":["array","null"],"items":{"type":"string"}},"missingSubsurfaces":{"type":["array","null"],"items":{"type":"string"}}}},"ProjectTelemetryFamilySummary":{"type":"object","required":["value","series","statusTotals","statusSeries","blockedTotal","blockedSeries","availability","includedInTotal","coverage","cutoverStartedAt","updatedAt","reason"],"properties":{"value":{"type":["integer","null"]},"series":{"type":["array","null"],"items":{"type":["integer","null"]}},"statusTotals":{"type":["object","null"],"required":["success","warning","error"],"properties":{"success":{"type":"integer"},"warning":{"type":"integer"},"error":{"type":"integer"}}},"statusSeries":{"type":["object","null"],"required":["success","warning","error"],"properties":{"success":{"type":"array","items":{"type":["integer","null"]}},"warning":{"type":"array","items":{"type":["integer","null"]}},"error":{"type":"array","items":{"type":["integer","null"]}}}},"blockedTotal":{"type":["integer","null"],"description":"Requests the Mini WAF blocked on this family's surfaces in the window (ADR 0109). Not part of value. Null when there were none, the family has no blockable surfaces, or the value is unavailable."},"blockedSeries":{"type":["array","null"],"items":{"type":["integer","null"]},"description":"Blocked requests per bucket, aligned with series; null when blockedTotal is null."},"availability":{"type":"string","enum":["ready","partial","unavailable","cutover_incomplete"]},"includedInTotal":{"type":"boolean"},"coverage":{"$ref":"#/components/schemas/ProjectTelemetryCoverage"},"cutoverStartedAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"reason":{"type":["string","null"]}}},"ProjectTelemetryBreakdownItem":{"type":"object","required":["key","value"],"properties":{"key":{"type":"string"},"value":{"type":["integer","null"]}}},"ProjectTelemetryOverviewResponse":{"type":"object","required":["project","timeRange","windowGranularity","windowStart","windowEnd","bucketStarts","availability","totals","series","families","breakdowns","updatedAt"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"timeRange":{"type":"string","enum":["30m","6h","24h","7d"]},"windowGranularity":{"type":"string","enum":["5m","1h","1d"]},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"},"bucketStarts":{"type":"array","items":{"type":"string","format":"date-time"}},"availability":{"type":"string","enum":["ready","partial","unavailable","cutover_incomplete"]},"totals":{"type":"object","required":["totalActivity","totalRequests","successRate"],"properties":{"totalActivity":{"type":["integer","null"]},"totalRequests":{"type":"integer","minimum":0},"successRate":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Percentage of requests with a recorded status that did not return 5xx; null when none has a status."}}},"series":{"type":"object","required":["totalActivity","totalRequests"],"properties":{"totalActivity":{"type":"array","items":{"type":["integer","null"]}},"totalRequests":{"type":"array","items":{"type":"integer","minimum":0}}}},"families":{"type":"object","required":["deploymentTraffic","containerTraffic","functionHostTraffic","storageActivity"],"properties":{"deploymentTraffic":{"$ref":"#/components/schemas/ProjectTelemetryFamilySummary"},"containerTraffic":{"$ref":"#/components/schemas/ProjectTelemetryFamilySummary"},"functionHostTraffic":{"$ref":"#/components/schemas/ProjectTelemetryFamilySummary"},"storageActivity":{"$ref":"#/components/schemas/ProjectTelemetryFamilySummary"}}},"breakdowns":{"type":"object","required":["deploymentTraffic","containerTraffic","functionHostTraffic","storageActivity"],"properties":{"deploymentTraffic":{"type":"object","required":["bySurfaceKind","byStatusClass"],"properties":{"bySurfaceKind":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}},"byStatusClass":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}}}},"containerTraffic":{"type":"object","required":["bySurfaceKind","byStatusClass"],"properties":{"bySurfaceKind":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}},"byStatusClass":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}}}},"functionHostTraffic":{"type":"object","required":["byStatusClass"],"properties":{"byStatusClass":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}}}},"storageActivity":{"type":"object","required":["byOperationKind","byActorType"],"properties":{"byOperationKind":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}},"byActorType":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}}}}}},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectTelemetryFamilyResponse":{"type":"object","required":["project","family","timeRange","windowGranularity","telemetry","breakdowns","updatedAt"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"family":{"type":"string","enum":["deployment_traffic","container_traffic","function_host_traffic","storage_activity"]},"timeRange":{"type":"string","enum":["30m","6h","24h","7d"]},"windowGranularity":{"type":"string","enum":["5m","1h","1d"]},"telemetry":{"$ref":"#/components/schemas/ProjectTelemetryFamilySummary"},"breakdowns":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/ProjectTelemetryBreakdownItem"}}},"updatedAt":{"type":"string","format":"date-time"}}},"FunctionProjectLogsResponse":{"type":"object","required":["project","function","filters","retentionPolicy","entries","nextCursor"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"},"filters":{"type":"object","required":["severity","category","timeRange"],"properties":{"severity":{"type":["string","null"],"enum":["info","warning","error",null]},"category":{"type":["string","null"]},"timeRange":{"type":"string","enum":["30m","6h","24h","7d"]}}},"retentionPolicy":{"type":"object","required":["maxEntriesPerCategory","maxAgeDays"],"properties":{"maxEntriesPerCategory":{"type":"integer"},"maxAgeDays":{"type":"integer"}}},"entries":{"type":"array","items":{"$ref":"#/components/schemas/ProjectLogEntry"}},"nextCursor":{"type":["string","null"]}}},"FunctionInvocation":{"type":"object","required":["id","projectId","functionId","triggerType","startedAt","totalDurationMs","outcome","metadata","logLink"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"functionId":{"type":"string"},"deploymentId":{"type":["string","null"]},"triggerType":{"type":"string","enum":["http","cron"]},"startedAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"},"coldStart":{"type":["boolean","null"]},"initDurationMs":{"type":["integer","null"]},"executionDurationMs":{"type":["integer","null"]},"totalDurationMs":{"type":"integer"},"outcome":{"type":"string","enum":["success","error","timeout"]},"httpStatus":{"type":["integer","null"]},"failureSummary":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true},"logLink":{"type":"object","required":["invocationId","path"],"properties":{"invocationId":{"type":"string"},"path":{"type":"string"}}}}},"FunctionInvocationsResponse":{"type":"object","required":["project","function","filters","invocations"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"function":{"$ref":"#/components/schemas/FunctionAsset"},"filters":{"type":"object","required":["timeRange","limit"],"properties":{"timeRange":{"type":"string","enum":["30m","6h","24h","7d"]},"limit":{"type":"integer"}}},"invocations":{"type":"array","items":{"$ref":"#/components/schemas/FunctionInvocation"}}}},"FunctionLogsResponse":{"type":"object","required":["functionDeploymentId","source","entries","logs"],"properties":{"functionDeploymentId":{"type":"string"},"source":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/FunctionLogEntry"}},"logs":{"type":"string"}}},"GatewayEvidenceConflictResponse":{"type":"object","additionalProperties":false,"required":["error","reason","conflictClass","incidentId"],"properties":{"error":{"type":"string"},"reason":{"type":"string"},"conflictClass":{"type":"string","enum":["sequence","evidence_identity","log_proof","receipt","membership"]},"incidentId":{"type":"string","pattern":"^gweinc_[0-9a-f]{32}$"}}},"GatewayEvidenceSequenceSupersession":{"type":"object","additionalProperties":false,"required":["incidentId","originalWalRecordId","originalSourceReservationId","originalSequence","originalRowFingerprint","canonicalSegmentId","canonicalWalRecordId","canonicalSequence"],"properties":{"incidentId":{"type":"string","pattern":"^gweinc_[0-9a-f]{32}$"},"originalWalRecordId":{"type":"string"},"originalSourceReservationId":{"type":"string"},"originalSequence":{"type":"integer","minimum":1},"originalRowFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"canonicalSegmentId":{"type":"string"},"canonicalWalRecordId":{"type":"string"},"canonicalSequence":{"type":"integer","minimum":1}}},"GatewayAccessEvidencePage":{"type":"object","additionalProperties":false,"required":["schemaVersion","storeUid","records"],"properties":{"schemaVersion":{"type":"string","const":"gateway-access-evidence.v2"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"records":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","required":["walRecordId","segmentId","sequence","sourceReservationId","rowFingerprint","projectId","assetType","assetId","deploymentId","entry"],"properties":{"walRecordId":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}:[A-Za-z0-9._-]{1,160}:[0-9]{20}:FINALIZE$"},"segmentId":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,160}$"},"sequence":{"type":"integer","minimum":1},"sourceReservationId":{"type":"string","pattern":"^[A-Za-z0-9:_-]{8,200}$"},"rowFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"projectId":{"type":"string"},"assetType":{"type":"string","enum":["app","container","function","static"]},"assetId":{"type":"string"},"deploymentId":{"type":"string"},"entry":{"type":"object","additionalProperties":true,"description":"The Access entry exactly as the Gateway wrote it"}}}}}},"GatewayAccessEvidencePageAnswer":{"type":"object","additionalProperties":false,"required":["schemaVersion","storeUid","envelopeFingerprint","results"],"properties":{"schemaVersion":{"type":"string","const":"gateway-access-evidence.v2"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"envelopeFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"results":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["index","status"],"properties":{"index":{"type":"integer","minimum":0},"walRecordId":{"type":"string"},"sourceReservationId":{"type":"string"},"sequence":{"type":"integer","minimum":1},"status":{"type":"string","enum":["accepted","exact_retry","project_deleted","rejected","conflict"]},"disposition":{"type":"string","enum":["accepted","project-deleted"]},"reason":{"type":"string"},"conflictClass":{"type":"string","enum":["sequence","evidence_identity","log_proof","receipt","membership"]},"incidentId":{"type":"string","pattern":"^gweinc_[0-9a-f]{32}$"}}}}}},"GatewayEvidenceSequenceRecoveryCandidate":{"type":"object","additionalProperties":false,"required":["walRecordId","sourceReservationId","sequence","rowFingerprint"],"properties":{"walRecordId":{"type":"string"},"sourceReservationId":{"type":"string"},"sequence":{"type":"integer","minimum":1},"rowFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"GatewayEvidenceSequenceAllocationRequest":{"type":"object","additionalProperties":false,"required":["schemaVersion","reservationId","storeUid","ownerId","localHighWater","requestedCount","recoveryFingerprint","recoveryCandidates"],"properties":{"schemaVersion":{"type":"integer","enum":[1]},"reservationId":{"type":"string","pattern":"^gwevr_[0-9a-f]{32}$"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"ownerId":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,160}$"},"localHighWater":{"type":"integer","minimum":0},"requestedCount":{"type":"integer","minimum":1,"maximum":4294967296},"recoveryFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"recoveryCandidates":{"type":"array","maxItems":32,"items":{"$ref":"#/components/schemas/GatewayEvidenceSequenceRecoveryCandidate"}},"predecessorReservationId":{"type":"string","pattern":"^gwevr_[0-9a-f]{32}$","description":"ADR 0105: the reservation a running Gateway rotates from. Absent at boot; granted only while it is the store's newest reservation."}}},"InternalGatewayEvidenceSequenceRequest":{"type":"object","additionalProperties":false,"required":["sequenceAllocation"],"properties":{"sequenceAllocation":{"$ref":"#/components/schemas/GatewayEvidenceSequenceAllocationRequest"}}},"GatewayEvidenceSequenceAllocationReceipt":{"type":"object","additionalProperties":false,"required":["schemaVersion","reservationId","storeUid","ownerId","writerEpoch","segmentId","localHighWater","requestedCount","recoveryFingerprint","firstSequence","lastSequence","supersessions"],"properties":{"schemaVersion":{"type":"integer","enum":[1]},"reservationId":{"type":"string","pattern":"^gwevr_[0-9a-f]{32}$"},"storeUid":{"type":"string","pattern":"^gwevstore_[0-9a-f]{32}$"},"ownerId":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,160}$"},"writerEpoch":{"type":"integer","minimum":1},"segmentId":{"type":"string","pattern":"^gwepoch-[0-9]{20}$"},"localHighWater":{"type":"integer","minimum":0},"requestedCount":{"type":"integer","minimum":1,"maximum":4294967296},"recoveryFingerprint":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"firstSequence":{"type":"integer","minimum":1},"lastSequence":{"type":"integer","minimum":1},"supersessions":{"type":"array","maxItems":32,"items":{"$ref":"#/components/schemas/GatewayEvidenceSequenceSupersession"}},"predecessorReservationId":{"type":"string","pattern":"^gwevr_[0-9a-f]{32}$"}}},"InternalGatewayEvidenceSequenceResponse":{"type":"object","additionalProperties":false,"required":["ok","sequenceAllocation"],"properties":{"ok":{"type":"boolean","enum":[true]},"sequenceAllocation":{"$ref":"#/components/schemas/GatewayEvidenceSequenceAllocationReceipt"}}},"RuntimeSecretState":{"type":"string","enum":["current","not_deployed","redeploy_required","restart_required","restart_queued","failed"]},"EnvBinding":{"type":"object","required":["resourceType","resourceId","resourceName","state"],"properties":{"resourceType":{"type":"string","enum":["app","function","container"]},"resourceId":{"type":"string"},"resourceName":{"type":"string"},"state":{"$ref":"#/components/schemas/RuntimeSecretState"}}},"EnvBindingTarget":{"type":"object","required":["resourceType","resourceId"],"properties":{"resourceType":{"type":"string","enum":["app","function","container"]},"resourceId":{"type":"string"}}},"EnvFunctionResourceOption":{"type":"object","required":["id","name","triggerType","bindable"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"triggerType":{"type":"string","enum":["http","cron"]},"bindable":{"type":"boolean"},"secretState":{"$ref":"#/components/schemas/RuntimeSecretState"},"blockedReason":{"type":"string"}}},"EnvContainerResourceOption":{"type":"object","required":["id","name","bindable","runtimeState","restartEligible","secretState"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"bindable":{"type":"boolean"},"runtimeState":{"type":"string"},"restartEligible":{"type":"boolean"},"secretState":{"$ref":"#/components/schemas/RuntimeSecretState"}}},"EnvAppResourceOption":{"type":"object","required":["id","name","bindable","runtimeState","secretState"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"bindable":{"type":"boolean"},"runtimeState":{"type":"string"},"secretState":{"$ref":"#/components/schemas/RuntimeSecretState"}}},"EnvResourceOptions":{"type":"object","required":["app","functions","containers"],"properties":{"app":{"$ref":"#/components/schemas/EnvAppResourceOption"},"functions":{"type":"array","items":{"$ref":"#/components/schemas/EnvFunctionResourceOption"}},"containers":{"type":"array","items":{"$ref":"#/components/schemas/EnvContainerResourceOption"}}}},"EnvImpactItem":{"type":"object","required":["id","name","state"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"state":{"$ref":"#/components/schemas/RuntimeSecretState"},"deploymentId":{"type":["string","null"]},"jobId":{"type":["string","null"]}}},"EnvImpact":{"type":"object","required":["functions","containers"],"properties":{"functions":{"type":"array","items":{"$ref":"#/components/schemas/EnvImpactItem"}},"containers":{"type":"array","items":{"$ref":"#/components/schemas/EnvImpactItem"}}}},"EnvEntry":{"type":"object","required":["id","key","isSecret","valueMasked","generation","status","updatedAt","bindings"],"properties":{"id":{"type":"string"},"key":{"type":"string"},"isSecret":{"type":"boolean","enum":[true]},"valueMasked":{"type":"string"},"generation":{"type":"integer","minimum":1},"status":{"type":"string","enum":["active","deleted"]},"updatedAt":{"type":["string","null"],"format":"date-time"},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/EnvBinding"}}}},"EnvEntryWrite":{"type":"object","required":["key","bindings"],"properties":{"key":{"type":"string"},"value":{"type":"string","description":"Required when creating a new key; optional when only rebinding an existing key."},"isSecret":{"type":"boolean","enum":[true]},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/EnvBindingTarget"}}}},"ProjectEnvUpsertRequest":{"type":"object","required":["entries"],"properties":{"entries":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/EnvEntryWrite"}},"containerRestart":{"type":"string","enum":["now","later"]}}},"ProjectEnvDeleteRequest":{"type":"object","properties":{"containerRestart":{"type":"string","enum":["now","later"]}}},"ProjectEnvContainerRestartRequest":{"type":"object","required":["containerIds"],"properties":{"containerIds":{"type":"array","minItems":1,"items":{"type":"string"}}}},"ProjectEnvContainerRestartResponse":{"type":"object","required":["containers"],"properties":{"containers":{"type":"array","items":{"$ref":"#/components/schemas/EnvImpactItem"}}}},"ProjectEnvErrorResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"message":{"type":["string","null"]},"reason":{"type":"string","enum":["secret-entries-required","secret-value-required","secret-bindings-required","duplicate-secret-key","secret-binding-target-invalid","duplicate-secret-binding-target","secret-binding-target-not-found","secret-binding-target-not-supported","container-restart-decision-required","container-ids-required","secret-restart-container-not-found","container-not-deployed","container-operation-in-flight","container-delete-in-flight","container-image-ref-required","container-image-digest-required","container-secret-restart-dispatch-failed","secret-not-found"]}}},"ProjectEnvResponse":{"type":"object","required":["project","projectId","env","resourceOptions","nextCursor","limit","envCount"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectId":{"type":"string"},"env":{"type":"array","items":{"$ref":"#/components/schemas/EnvEntry"}},"resourceOptions":{"$ref":"#/components/schemas/EnvResourceOptions"},"impact":{"$ref":"#/components/schemas/EnvImpact"},"restartError":{"$ref":"#/components/schemas/ProjectEnvErrorResponse"},"nextCursor":{"type":["string","null"]},"limit":{"type":"integer","minimum":1,"maximum":100},"envCount":{"type":"integer"}}},"StorageObject":{"type":"object","required":["id","organizationId","projectId","createdByUserId","logicalKey","visibility","uploadStatus","preview","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"projectId":{"type":"string"},"bucketId":{"type":["string","null"]},"createdByUserId":{"type":"string"},"logicalKey":{"type":"string"},"objectKey":{"type":["string","null"]},"contentType":{"type":["string","null"]},"sizeBytes":{"type":["integer","null"]},"visibility":{"type":"string","enum":["private","public"]},"uploadStatus":{"type":"string","enum":["pending","ready","failed","deleted"]},"preview":{"type":"object","required":["status","imageUrl","width","height","actions"],"properties":{"status":{"type":"string","enum":["loading","ready","unavailable","none"]},"imageUrl":{"type":["string","null"],"format":"uri-reference"},"width":{"type":["integer","null"],"minimum":1,"maximum":960},"height":{"type":["integer","null"],"minimum":1,"maximum":960},"actions":{"type":"object","required":["retryPreview"],"properties":{"retryPreview":{"type":"boolean"}}}}},"productUrl":{"type":["string","null"],"format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectStorageBucketSummary":{"type":"object","required":["id","name","pathPrefix","accessMode","status","objectCount","readyCount","totalBytes","createdAt","visibilitySummary","mimeSummary"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"pathPrefix":{"type":"string"},"accessMode":{"type":"string","enum":["private","public"]},"status":{"type":"string","enum":["provisioning","ready","failed","pending_delete","delete_failed","deleted"]},"objectCount":{"type":"integer"},"readyCount":{"type":"integer"},"totalBytes":{"type":"integer"},"createdAt":{"type":["string","null"],"format":"date-time"},"visibilitySummary":{"type":"string"},"mimeSummary":{"type":"string"}}},"ProjectStorageSnapshot":{"type":"object","required":["bucketCount","objectCount","readyObjectCount","pendingObjectCount","failedObjectCount","imageObjectCount","totalBytes","visibilitySummary","latestObjectUpdatedAt"],"properties":{"bucketCount":{"type":"integer"},"objectCount":{"type":"integer"},"readyObjectCount":{"type":"integer"},"pendingObjectCount":{"type":"integer"},"failedObjectCount":{"type":"integer"},"imageObjectCount":{"type":"integer"},"totalBytes":{"type":"integer"},"visibilitySummary":{"type":"string"},"latestObjectUpdatedAt":{"type":["string","null"],"format":"date-time"}}},"ProjectStorageListResponse":{"type":"object","required":["project","prefix","bucketSummaries","snapshot","objects","nextCursor"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"prefix":{"type":["string","null"]},"bucketSummaries":{"type":"array","items":{"$ref":"#/components/schemas/ProjectStorageBucketSummary"}},"snapshot":{"anyOf":[{"$ref":"#/components/schemas/ProjectStorageSnapshot"},{"type":"null"}]},"bucket":{"anyOf":[{"$ref":"#/components/schemas/ProjectStorageBucketSummary"},{"type":"null"}]},"objects":{"type":"array","items":{"$ref":"#/components/schemas/StorageObject"}},"nextCursor":{"type":["string","null"]}}},"CreateProjectStorageUploadBatchRequest":{"type":"object","required":["files"],"properties":{"files":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"object","required":["objectKey","contentType","sizeBytes","sha256"],"properties":{"objectKey":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$"}}}}}},"CreateProjectStorageUploadBatchResponse":{"type":"object","required":["project","bucket","uploads"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"bucket":{"$ref":"#/components/schemas/ProjectStorageBucketSummary"},"uploads":{"type":"array","items":{"$ref":"#/components/schemas/CreateProjectStorageUploadResponse"}}}},"CreateStorageBucketRequest":{"type":"object","required":["name","accessMode"],"properties":{"name":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$"},"accessMode":{"type":"string","enum":["private","public"]}}},"UpdateStorageBucketRequest":{"type":"object","required":["accessMode"],"additionalProperties":false,"properties":{"accessMode":{"type":"string","enum":["private","public"]}}},"StorageBucketResponse":{"type":"object","required":["project","bucket"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"bucket":{"$ref":"#/components/schemas/ProjectStorageBucketSummary"},"ok":{"type":"boolean"}}},"CreateProjectStorageUploadResponse":{"type":"object","required":["project","storageObject","completionRequired","uploadInProgress","upload"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"bucket":{"$ref":"#/components/schemas/ProjectStorageBucketSummary"},"snapshot":{"anyOf":[{"$ref":"#/components/schemas/ProjectStorageSnapshot"},{"type":"null"}]},"storageObject":{"$ref":"#/components/schemas/StorageObject"},"completionRequired":{"type":"boolean","description":"True only when the original bytes are durable and this upload attempt must resume authenticated completion."},"uploadInProgress":{"type":"boolean","description":"True only when the same upload attempt is still processing and authenticated completion may be retried within the bounded client wait."},"upload":{"anyOf":[{"type":"object","required":["id","transport","method","url","headers","expiresAt","maxBytes"],"properties":{"id":{"type":"string"},"transport":{"type":"string","enum":["object-storage"]},"method":{"type":"string","enum":["PUT"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"expiresAt":{"type":"string","format":"date-time"},"maxBytes":{"type":"integer"}}},{"type":"null"}]}}},"StorageObjectResponse":{"type":"object","required":["project","storageObject"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"bucket":{"anyOf":[{"$ref":"#/components/schemas/ProjectStorageBucketSummary"},{"type":"null"}]},"snapshot":{"anyOf":[{"$ref":"#/components/schemas/ProjectStorageSnapshot"},{"type":"null"}]},"storageObject":{"$ref":"#/components/schemas/StorageObject"},"ok":{"type":"boolean"}}},"StoragePreviewBackfillResponse":{"type":"object","required":["ok","project","processedCount","sourceBytes","results"],"properties":{"ok":{"type":"boolean"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"processedCount":{"type":"integer","minimum":0,"maximum":10},"sourceBytes":{"type":"integer","minimum":0,"maximum":52428800},"results":{"type":"array","maxItems":10,"items":{"type":"object","required":["storageObjectId","previewStatus"],"properties":{"storageObjectId":{"type":"string"},"previewStatus":{"type":"string","enum":["loading","ready","unavailable","none"]}}}}}},"CreateStorageObjectReadUrlResponse":{"type":"object","required":["project","storageObject","readUrl","expiresAt"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"storageObject":{"$ref":"#/components/schemas/StorageObject"},"readUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"}}},"InvalidEmailError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string","enum":["Invalid email address"]},"reason":{"type":"string","enum":["invalid-email"]}}},"PasswordResetRequiredError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string","enum":["Set a new password to log in. We sent a link to your email."]},"reason":{"type":"string","enum":["password-reset-required"]}}},"EmailDomainRejectedError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["email-domain-disposable","email-domain-no-mail"]}}},"EmailDomainUnavailableError":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["email-domain-check-unavailable"]},"retryable":{"type":"boolean","enum":[true]}}},"Deployment":{"type":"object","required":["id","projectId","version","deploymentMode","runtime","runtimeWorkersReason","status","displayStatus","releaseKind","statusView","terminal","visible","stale","freshness","lastObservedAt","lastProvenExecutionPhase","displayStatusReasonCode","deployableOutput","actionAvailability","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"version":{"type":"integer"},"deploymentMode":{"type":"string","enum":["runtime","static"]},"runtime":{"type":"string","enum":["workers","container","static"],"description":"Where this deployment runs: a Worker, a container, or static files."},"runtimeWorkersReason":{"type":["string","null"],"description":"Why a Workers route of this deployment runs as a container instead, as short display copy of the build Job detection reason; null otherwise or when the reason has no display copy."},"primaryHostname":{"type":["string","null"],"description":"The deployment's project's official address today (see ProjectSummary.primaryHostname)."},"provider":{"type":["string","null"],"enum":["scaleway",null],"description":"Owner/admin deployment detail proof only; list and contributor surfaces omit this field."},"imageRef":{"type":["string","null"],"description":"Owner/admin deployment detail proof only; list and contributor surfaces omit this field."},"rollbackTargetImageRef":{"type":["string","null"],"description":"Owner/admin deployment detail rollback proof only; list and contributor surfaces omit this field."},"status":{"type":"string","enum":["queued","building","deploying","healthy","unhealthy","failed","rolled_back"]},"displayStatus":{"type":"string","enum":["queued","waiting_for_builder","building_image","waiting_for_deploy_runner","deploying","healthy","unhealthy","failed","rolled_back","status_check_delayed"]},"releaseKind":{"type":"string","enum":["runtime_release","static_release","deployment_attempt"]},"statusView":{"$ref":"#/components/schemas/DeploymentStatusView"},"terminal":{"type":"boolean"},"visible":{"type":"boolean"},"stale":{"type":"boolean"},"freshness":{"type":"string","enum":["fresh","reconciling","stale"]},"lastObservedAt":{"type":"string","format":"date-time"},"lastProvenExecutionPhase":{"type":["string","null"],"enum":["queued","waiting_for_builder","building_image","waiting_for_deploy_runner","deploying",null]},"displayStatusReasonCode":{"type":"string","enum":["none","builder_capacity_wait_exceeded","build_output_delayed","deploy_runner_wait_exceeded","deploy_execution_delayed","projection_evidence_conflict"]},"statusReason":{"type":["string","null"]},"failureSummary":{"oneOf":[{"$ref":"#/components/schemas/DeploymentFailureSummary"},{"type":"null"}]},"artifactType":{"type":["string","null"],"enum":["static_archive",null]},"artifactRef":{"type":["string","null"],"description":"Internal static artifact object key is withheld from member-readable responses; member clients must use deployableOutput."},"artifactSha256":{"type":["string","null"]},"publishTarget":{"type":["string","null"],"description":"Internal static publish prefix is withheld from member-readable responses; member clients must use deployableOutput."},"detailRevision":{"type":"string","description":"Changes only when lifecycle, immutable output or preview detail is invalidated."},"deployableOutput":{"type":"object","required":["kind","digest","displayLabel","deploymentId"],"properties":{"kind":{"type":"string","enum":["runtime_image","static_artifact","app_release","none"]},"digest":{"type":["string","null"]},"displayLabel":{"type":"string"},"releaseId":{"type":["string","null"]},"deploymentId":{"type":["string","null"]}}},"actionAvailability":{"type":"object","required":["canPromote","canRollback","canRebuild","rebuildBlockedReason","rebuildRecoveryAction","rebuildDescriptor","compatibleOutputKind","blockedReason","targetDeploymentId"],"properties":{"canPromote":{"type":"boolean"},"canRollback":{"type":"boolean"},"canRebuild":{"type":"boolean"},"rebuildBlockedReason":{"type":["string","null"],"enum":["deployment-not-terminal","source-snapshot-unavailable","repository-access-unavailable","route-convergence-in-progress","source-build-engine-retired",null]},"rebuildRecoveryAction":{"anyOf":[{"$ref":"#/components/schemas/DeploymentRebuildRecoveryAction"},{"type":"null"}]},"rebuildDescriptor":{"oneOf":[{"type":"object","required":["repository","branch","commitSha","domain"],"additionalProperties":false,"properties":{"repository":{"type":"string"},"branch":{"type":"string"},"commitSha":{"type":"string"},"domain":{"type":"string","description":"The project's official address the redeploy serves: its linked domain once one serves it, otherwise its eurobase.dev host"}}},{"type":"null"}]},"compatibleOutputKind":{"type":"string","enum":["runtime_image","static_artifact","app_release","none"]},"blockedReason":{"type":["string","null"]},"targetDeploymentId":{"type":["string","null"]}}},"assetType":{"type":["string","null"],"enum":["app","container",null]},"assetId":{"type":["string","null"]},"canonicalContainerDetailPath":{"type":["string","null"]},"previewCaptureStatus":{"type":["string","null"],"enum":["pending","ready","failed",null]},"previewCapturedAt":{"type":["string","null"],"format":"date-time"},"previewImageUrl":{"type":["string","null"],"format":"uri-reference","description":"Same-origin API-owned authenticated preview image route path. Container deployment previews are exposed only on the selected project container detail screen model; generic deployment detail and container list rows keep this null. Missing preview storage read capability also returns null instead of failing the parent screen model."},"previewRefreshGeneration":{"type":["integer","null"]},"previewRefreshStatus":{"type":["string","null"],"enum":["pending","failed",null]},"previewRefreshRequestedAt":{"type":["string","null"],"format":"date-time"},"previewRefreshFailedAt":{"type":["string","null"],"format":"date-time"},"previewRefreshError":{"type":["string","null"]},"routeConvergence":{"oneOf":[{"type":"object","required":["state","statusLabel","pollRecommended"],"additionalProperties":false,"properties":{"state":{"type":"string","enum":["recovering","exhausted","ready"]},"statusLabel":{"type":"string"},"pollRecommended":{"type":"boolean"}}},{"type":"null"}]},"providerMetadata":{"$ref":"#/components/schemas/DeploymentProviderMetadata"},"lifecycle":{"oneOf":[{"$ref":"#/components/schemas/DeploymentLifecycle"},{"type":"null"}],"description":"API-owned member-safe deployment lifecycle projection for the detail screen. Complete successful phase spans use durable deployment timing evidence; in-flight or incomplete spans use available deployment, event, and job evidence. Queue and dispatch gaps are assigned to the phase that owns the wait."},"timingEvidence":{"oneOf":[{"$ref":"#/components/schemas/DeploymentTimingEvidence"},{"type":"null"}],"description":"Replay-stable API/DB-owned timing evidence. Incomplete historical or unobserved boundaries remain null and complete=false; values are never reconstructed from producer clocks or prunable events."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SourceBuildRegistryCredentialReceipt":{"type":"object","additionalProperties":false,"required":["leaseId","generation","dispatchAttemptId"],"properties":{"leaseId":{"type":"string","pattern":"^scrcl_[a-z0-9]+$"},"generation":{"type":"integer","minimum":1},"dispatchAttemptId":{"type":"string","pattern":"^sba_[a-z0-9]+$"}}},"SourceBuildCacheReceipt":{"type":"object","additionalProperties":false,"required":["rootId","leaseId","generationId","compatibilityHash"],"properties":{"rootId":{"type":"string","pattern":"^sbcr_[a-z0-9]+$"},"leaseId":{"type":"string","pattern":"^sbcl_[a-z0-9]+$"},"generationId":{"type":"string","pattern":"^sbcg_[a-z0-9]+$"},"compatibilityHash":{"type":"string","pattern":"^[a-f0-9]{64}$"}}},"DeploymentTimingEvidence":{"type":"object","additionalProperties":false,"required":["version","complete","outcome","totalMs","userTotalMs","builderTimingsVersion","builderTimingsMs","publicMarkerProof","triggerReceivedAt","requestedAt","buildDispatchAt","builderReadyAt","callbackReceivedAt","callbackAcceptedAt","deployDispatchAt","deployWorkerClaimedAt","deployRunnerStartedAt","deployRunnerReadyAt","providerRequestStartedAt","providerReadyAt","brandedRouteProvedAt","activatedAt","terminalAt","warmRunnerTimingsMs"],"properties":{"version":{"type":"string","enum":["deployment-timing-evidence-v2","deployment-timing-evidence-v3"]},"complete":{"type":"boolean"},"outcome":{"type":["string","null"],"enum":["healthy","rolled_back","failed","unhealthy",null]},"totalMs":{"type":["integer","null"],"minimum":0},"userTotalMs":{"type":["integer","null"],"minimum":0},"builderTimingsVersion":{"type":["string","null"],"enum":["railpack-phase-timings-v1","railpack-phase-timings-v2","railpack-phase-timings-v3","source-build-phase-timings-v1",null]},"builderTimingsMs":{"type":["object","null"],"additionalProperties":{"type":"integer","minimum":0}},"publicMarkerProof":{"type":["object","null"],"additionalProperties":false,"required":["deploymentId","acceptedDigest","sourceFingerprint","requestIdSha256","apiObservedAt"],"properties":{"deploymentId":{"type":"string"},"acceptedDigest":{"type":"string","pattern":"^(sha256:)?[a-f0-9]{64}$"},"sourceFingerprint":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"requestIdSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"apiObservedAt":{"type":"string","format":"date-time"}}},"triggerReceivedAt":{"type":["string","null"],"format":"date-time"},"requestedAt":{"type":["string","null"],"format":"date-time"},"buildDispatchAt":{"type":["string","null"],"format":"date-time"},"builderReadyAt":{"type":["string","null"],"format":"date-time"},"callbackReceivedAt":{"type":["string","null"],"format":"date-time"},"callbackAcceptedAt":{"type":["string","null"],"format":"date-time"},"deployDispatchAt":{"type":["string","null"],"format":"date-time"},"deployWorkerClaimedAt":{"type":["string","null"],"format":"date-time"},"deployRunnerStartedAt":{"type":["string","null"],"format":"date-time"},"deployRunnerReadyAt":{"type":["string","null"],"format":"date-time"},"providerRequestStartedAt":{"type":["string","null"],"format":"date-time"},"providerReadyAt":{"type":["string","null"],"format":"date-time"},"brandedRouteProvedAt":{"type":["string","null"],"format":"date-time"},"activatedAt":{"type":["string","null"],"format":"date-time"},"terminalAt":{"type":["string","null"],"format":"date-time"},"warmRunnerTimingsMs":{"type":["object","null"],"additionalProperties":false,"required":["dispatchToWorkerClaimMs","workerClaimToRunnerStartMs","runnerStartToProviderRequestMs","providerRequestToReadyMs"],"properties":{"dispatchToWorkerClaimMs":{"type":["integer","null"],"minimum":0},"workerClaimToRunnerStartMs":{"type":["integer","null"],"minimum":0},"runnerStartToProviderRequestMs":{"type":["integer","null"],"minimum":0},"providerRequestToReadyMs":{"type":["integer","null"],"minimum":0}}}}},"DeploymentStatusView":{"type":"object","required":["code","primaryCode","primaryLabel","secondaryLabel","tone","freshnessLabel"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["queued","waiting_for_builder","building_image","waiting_for_deploy_runner","deploying","healthy","unhealthy","failed","rolled_back","status_check_delayed"]},"primaryCode":{"type":"string","enum":["queued","waiting_for_builder","building_image","waiting_for_deploy_runner","deploying","healthy","unhealthy","failed","rolled_back"]},"primaryLabel":{"type":"string"},"secondaryLabel":{"type":["string","null"]},"tone":{"type":"string","enum":["neutral","active","success","warning","danger"]},"freshnessLabel":{"type":["string","null"],"enum":["Live","Refreshing","Status delayed",null]}}},"DeploymentLifecycle":{"type":"object","required":["source","phases"],"additionalProperties":false,"properties":{"source":{"type":"string","enum":["api_projection"]},"phases":{"type":"array","minItems":4,"maxItems":4,"items":{"$ref":"#/components/schemas/DeploymentLifecyclePhase"}}}},"DeploymentLifecyclePhase":{"type":"object","required":["key","label","status","startedAt","endedAt","durationMs","detailLabel","skipReason"],"additionalProperties":false,"properties":{"key":{"type":"string","enum":["initialize","build","deploy","verify"]},"label":{"type":"string","enum":["Initialize","Build","Deploy","Verify"]},"status":{"type":"string","enum":["pending","running","recovering","completed","failed","skipped","unavailable"]},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"durationMs":{"type":["integer","null"],"minimum":0},"detailLabel":{"type":["string","null"]},"skipReason":{"type":["string","null"],"enum":["image-only",null]}}},"DeploymentProviderMetadata":{"type":"object","additionalProperties":false,"properties":{"visibility":{"type":["string","null"]},"supersededByDeploymentId":{"type":["string","null"]},"customDomainStatus":{"type":["string","null"]},"resolution":{"type":["string","null"]}}},"DeploymentFailureSummary":{"type":"object","required":["category","phase","severity","headline","observedAt"],"properties":{"category":{"type":"string","enum":["clone_failed","build_failed","image_push_failed","deploy_failed","healthcheck_failed","runtime_startup_failed","runtime_startup_timeout","app_health_failed","route_activation_failed","platform_capacity_failed","invalid_runtime_config","internal_platform_error"]},"phase":{"type":"string","enum":["queue","build","deploy","healthcheck","system"]},"severity":{"type":"string","enum":["info","warning","error"]},"headline":{"type":"string"},"detail":{"type":["string","null"],"description":"One short line: the typed failure reason in owner copy, never the raw reason code."},"explanation":{"type":["string","null"],"description":"The full failure sentence shown in the status popover, when it says more than detail."},"fixCommand":{"type":["string","null"],"description":"The command named in explanation that fixes the failure, offered for copying."},"observedAt":{"type":"string","format":"date-time"}}},"DeploymentLogEntry":{"type":"object","required":["id","phase","severity","redacted","truncated","observedAt","createdAt"],"properties":{"id":{"type":"string"},"phase":{"type":"string","enum":["queue","build","deploy","healthcheck","system"]},"category":{"type":["string","null"],"enum":["clone_failed","build_failed","image_push_failed","deploy_failed","healthcheck_failed","runtime_startup_failed","runtime_startup_timeout","app_health_failed","route_activation_failed","platform_capacity_failed","invalid_runtime_config","internal_platform_error",null]},"severity":{"type":"string","enum":["info","warning","error"]},"logKind":{"type":["string","null"],"enum":["build","deploy","runtime","event",null]},"stream":{"type":["string","null"],"enum":["stdout","stderr","system",null]},"redacted":{"type":"boolean"},"truncated":{"type":"boolean"},"truncationReason":{"type":["string","null"]},"observedAt":{"type":"string","format":"date-time"},"message":{"type":["string","null"]},"providerReady":{"type":["boolean","null"]},"gatewayStatusCode":{"type":["integer","null"],"minimum":100,"maximum":599},"gatewayRouteMatched":{"type":["boolean","null"]},"gatewayAppRespondedOk":{"type":["boolean","null"]},"gatewayTlsOk":{"type":["boolean","null"]},"probeAttempts":{"type":["integer","null"],"minimum":0,"maximum":100},"createdAt":{"type":"string","format":"date-time"}}},"DeploymentLogRetention":{"type":"object","required":["expiredLogKinds","expiredErrorLogKinds"],"properties":{"expiredLogKinds":{"type":"array","uniqueItems":true,"maxItems":4,"items":{"type":"string","enum":["build","deploy","runtime","event"]}},"expiredErrorLogKinds":{"type":"array","uniqueItems":true,"maxItems":4,"items":{"type":"string","enum":["build","deploy","runtime","event"]}}}},"DeploymentLogsResponse":{"type":"object","required":["deploymentId","source","retentionPolicy","retention","truncatedLogKinds","streamState","streamStates","runtimeLogState","entries"],"properties":{"retention":{"$ref":"#/components/schemas/DeploymentLogRetention"},"truncatedLogKinds":{"type":"array","uniqueItems":true,"maxItems":4,"items":{"type":"string","enum":["build","deploy","runtime","event"]},"description":"Replayed kinds whose newest window this read cut while older retained rows of that kind may exist (not removed by retention). Covers only the kinds this read replays: the requested logKind, or all four."},"deploymentId":{"type":"string"},"logKind":{"type":["string","null"],"enum":["build","deploy","runtime","event",null]},"source":{"type":"string","enum":["project_logs"]},"cursor":{"type":["string","null"]},"retentionPolicy":{"type":"object","required":["maxEntriesPerCategory","maxAgeDays"],"properties":{"maxEntriesPerCategory":{"type":"integer"},"maxAgeDays":{"type":"integer"}}},"streamState":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"streamStates":{"$ref":"#/components/schemas/DeploymentLogStreamStateByKind"},"runtimeLogState":{"oneOf":[{"$ref":"#/components/schemas/RuntimeLogState"},{"type":"null"}]},"entries":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentLogEntry"}}}},"DeploymentLogStreamState":{"type":"string","enum":["live","reconnecting","catching_up","delayed","completed","blocked"]},"DeploymentLogStreamStateByKind":{"type":"object","required":["event","build","deploy","runtime"],"properties":{"event":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"build":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"deploy":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"runtime":{"$ref":"#/components/schemas/DeploymentLogStreamState"}}},"DeploymentLogStreamStatePatchByKind":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"build":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"deploy":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"runtime":{"$ref":"#/components/schemas/DeploymentLogStreamState"}}},"DeploymentLogStreamSnapshot":{"type":"object","required":["type","deploymentId","entries","cursor","streamState","runtimeLogState","retention","truncatedLogKinds"],"properties":{"retention":{"$ref":"#/components/schemas/DeploymentLogRetention"},"truncatedLogKinds":{"type":"array","uniqueItems":true,"maxItems":4,"items":{"type":"string","enum":["build","deploy","runtime","event"]},"description":"Replayed kinds whose newest window this read cut while older retained rows of that kind may exist (not removed by retention). Covers only the kinds this read replays: the requested logKind, or all four."},"type":{"type":"string","enum":["deployment_logs_snapshot"]},"deploymentId":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentLogEntry"}},"cursor":{"type":["string","null"]},"streamState":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"streamStates":{"oneOf":[{"$ref":"#/components/schemas/DeploymentLogStreamStateByKind"},{"type":"null"}]},"runtimeLogState":{"oneOf":[{"$ref":"#/components/schemas/RuntimeLogState"},{"type":"null"}]}}},"DeploymentLogStreamEvent":{"type":"object","required":["type","deploymentId","entry","cursor","streamState"],"properties":{"type":{"type":"string","enum":["deployment_logs_event"]},"deploymentId":{"type":"string"},"entry":{"$ref":"#/components/schemas/DeploymentLogEntry"},"cursor":{"type":["string","null"]},"streamState":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"streamStates":{"oneOf":[{"$ref":"#/components/schemas/DeploymentLogStreamStatePatchByKind"},{"type":"null"}]}}},"DeploymentLogStreamStatus":{"type":"object","required":["type","deploymentId","streamState"],"properties":{"type":{"type":"string","enum":["deployment_logs_status"]},"deploymentId":{"type":"string"},"logKind":{"type":["string","null"],"enum":["build","deploy","runtime","event",null]},"streamState":{"$ref":"#/components/schemas/DeploymentLogStreamState"},"streamStates":{"oneOf":[{"$ref":"#/components/schemas/DeploymentLogStreamStatePatchByKind"},{"type":"null"}]}}},"DeploymentsResponse":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/Deployment"}}}},"DeploymentResponse":{"type":"object","required":["deployment","project","projectRoute","releaseUsability","actionPermissions"],"properties":{"deployment":{"$ref":"#/components/schemas/Deployment"},"project":{"$ref":"#/components/schemas/ProjectSummary"},"projectRoute":{"$ref":"#/components/schemas/ProjectRoute"},"releaseUsability":{"$ref":"#/components/schemas/ReleaseUsability"},"sourceDeploy":{"oneOf":[{"$ref":"#/components/schemas/ProjectSourceDeploy"},{"type":"null"}]},"actionPermissions":{"type":"object","required":["canManageSource"],"properties":{"canManageSource":{"type":"boolean"}}}}},"DeploymentConflictResponse":{"type":"object","required":["reason"],"properties":{"error":{"type":["string","null"]},"reason":{"type":"string","enum":["deployment-in-flight","deployment-action-idempotency-conflict","project-repository-missing","deployment-not-terminal","route-convergence-in-progress","source-deployment-not-redeployable","source-deployment-snapshot-incomplete","source-deployment-repository-unavailable","dependency-lockfile-required","dependency-package-manager-unsupported"]},"missingFields":{"type":"array","items":{"type":"string"}},"requestedAction":{"type":["string","null"]},"existingDeploymentId":{"type":["string","null"]},"existingJobId":{"type":["string","null"]},"existingDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"sourceDeploy":{"oneOf":[{"$ref":"#/components/schemas/ProjectSourceDeploy"},{"type":"null"}]}}},"ProjectIncidentResponse":{"type":"object","required":["project","incidentState","latestDeployment","activeDeployment","publicRoute","releaseUsability","incidentDeployment","reason","source","eventTail","rollbackCandidate","retentionPolicy"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"incidentState":{"type":"string","enum":["none","open"]},"latestDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"activeDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"publicRoute":{"$ref":"#/components/schemas/ProjectRoute"},"releaseUsability":{"$ref":"#/components/schemas/ReleaseUsability"},"incidentDeployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"reason":{"type":["string","null"]},"source":{"type":"string"},"eventTail":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentLogEntry"}},"rollbackCandidate":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"retentionPolicy":{"type":"object","required":["maxEventsPerDeployment","maxAgeDays"],"properties":{"maxEventsPerDeployment":{"type":"integer"},"maxAgeDays":{"type":"integer"}}}}},"GitHubSyncError":{"type":"object","required":["code","scope","actor","recoveryAction","message"],"properties":{"code":{"type":"string"},"scope":{"type":"string","enum":["installations","repositories"]},"actor":{"type":"string","enum":["user","operator","unknown"]},"recoveryAction":{"type":"string","enum":["reconnect-oauth","install-app","open-installation-access","retry-refresh","operator-fix"]},"message":{"type":"string"}}},"GitHubSyncState":{"type":"object","required":["status","errors"],"properties":{"status":{"type":"string","enum":["ok","partial","stale"]},"message":{"type":["string","null"]},"errors":{"type":"array","items":{"$ref":"#/components/schemas/GitHubSyncError"}},"primaryError":{"oneOf":[{"$ref":"#/components/schemas/GitHubSyncError"},{"type":"null"}]}}},"GitHubAccount":{"type":["object","null"],"required":["login"],"properties":{"login":{"type":"string"},"name":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"oauthStatus":{"type":["string","null"],"enum":["connected","revoked","unknown",null]},"oauthStatusReason":{"type":["string","null"]},"oauthVerifiedAt":{"type":["string","null"],"format":"date-time"},"snapshotVersion":{"type":"integer"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"GitHubInstallation":{"type":"object","required":["id","repoCount"],"properties":{"id":{"type":"string"},"accountLogin":{"type":["string","null"]},"repoCount":{"type":"integer","minimum":0,"description":"Selected or allowed repository count recorded for this installation. A missing stored count is serialized as 0 only while the top-level snapshot remains not ready with refresh recovery; it is not proven empty inventory."},"repositoryAccessAction":{"oneOf":[{"$ref":"#/components/schemas/GitHubConnectAction"},{"type":"null"}]},"syncStatus":{"type":"string","enum":["ok","empty","error","stale"]},"syncError":{"oneOf":[{"$ref":"#/components/schemas/GitHubSyncError"},{"type":"null"}]}}},"GitHubRepo":{"type":"object","required":["id","name","fullName","private","defaultBranch"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"fullName":{"type":"string"},"private":{"type":"boolean"},"defaultBranch":{"type":"string"}}},"GitHubStateSummary":{"type":"object","required":["accountStatus","installationCount","repoCount","sync","snapshotVersion","hasSavedAccess","projectCreateAvailable","recommendedAction","recoveryAction","navStatus","ready"],"properties":{"accountStatus":{"type":"string","enum":["none","unknown","connected","revoked"]},"accountStatusReason":{"type":["string","null"]},"accountVerifiedAt":{"type":["string","null"],"format":"date-time"},"installationCount":{"type":"integer"},"repoCount":{"type":"integer","minimum":0,"description":"Sum of non-negative cached installation repository counts before repository filtering or response bounds. Any missing stored installation count keeps the snapshot not ready with refresh recovery."},"sync":{"$ref":"#/components/schemas/GitHubSyncState"},"snapshotVersion":{"type":"integer"},"snapshotUpdatedAt":{"type":["string","null"],"format":"date-time"},"hasSavedAccess":{"type":"boolean"},"projectCreateAvailable":{"type":"boolean"},"recommendedAction":{"type":"string","enum":["none","oauth","refresh","install","manage","review","disabled"]},"recoveryAction":{"$ref":"#/components/schemas/GitHubConnectAction"},"repositoryAccessAction":{"oneOf":[{"$ref":"#/components/schemas/GitHubConnectAction"},{"type":"null"}]},"navStatus":{"type":"object","required":["tone","label"],"properties":{"tone":{"type":"string","enum":["neutral","healthy","warning","danger"]},"label":{"type":"string"}}},"ready":{"type":"boolean"}}},"GitHubConnectAction":{"type":"object","required":["kind","label"],"properties":{"kind":{"type":"string","enum":["none","oauth","refresh","install","manage","review","disabled"]},"label":{"type":"string"},"href":{"type":["string","null"]},"disabled":{"type":"boolean"},"reason":{"type":["string","null"]}}},"DeploymentRebuildRecoveryAction":{"type":"object","required":["kind","label","href","disabled","reason"],"properties":{"kind":{"type":"string","enum":["oauth","refresh","install","manage","review","disabled"]},"label":{"type":"string"},"href":{"type":["string","null"]},"disabled":{"type":"boolean"},"reason":{"type":["string","null"]}}},"AuthUser":{"type":"object","required":["id","email","emailVerified","authAccessState","avatarUrl","createdAt"],"properties":{"id":{"type":"string"},"email":{"type":"string"},"status":{"type":["string","null"]},"deleteRequestedAt":{"type":["string","null"],"format":"date-time"},"deletionState":{"type":["string","null"],"enum":["billing_pending","cleanup_pending",null]},"emailVerifiedAt":{"type":["string","null"],"format":"date-time"},"emailVerified":{"type":"boolean"},"authAccessState":{"type":"string","enum":["verified","email_verification_required"]},"avatarUrl":{"type":["string","null"],"description":"Profile picture of the most recently used linked Google or GitHub sign-in that has one."},"createdAt":{"type":"string","format":"date-time"}}},"AuthResponse":{"type":"object","required":["user","authAccessState","emailVerification","capabilities","clientIp"],"properties":{"user":{"$ref":"#/components/schemas/AuthUser"},"authAccessState":{"type":"string","enum":["verified","email_verification_required"]},"emailVerification":{"type":"object","required":["required","verified","sent"],"properties":{"required":{"type":"boolean"},"verified":{"type":"boolean"},"sent":{"type":"boolean"}}},"capabilities":{"$ref":"#/components/schemas/SessionCapabilities"},"clientIp":{"type":["string","null"]}}},"EmailVerificationConfirmationResponse":{"type":"object","required":["ok","status"],"properties":{"ok":{"type":"boolean"},"status":{"type":"string","enum":["verified","login_required"]}}},"PasswordResetRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string"}}},"AuthCredentialsRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"},"authChallenge":{"$ref":"#/components/schemas/AuthChallengeSolution"}}},"AuthChallengeRequest":{"type":"object","properties":{}},"GoogleNonceResponse":{"type":"object","required":["nonce"],"properties":{"nonce":{"type":"string","description":"Server-issued, single-use Google nonce; bound to the initiating browser and, for links, its session."}}},"GoogleVerifyRequest":{"type":"object","required":["credential","nonce"],"properties":{"credential":{"type":"string"},"nonce":{"type":"string"},"returnTo":{"type":"string"}}},"ClientIpUnavailableError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["client-ip-unavailable"]}}},"AuthChallengeSolution":{"type":"string","maxLength":4096,"description":"ADR 0088: base64 JSON {algorithm, challenge, number, salt, signature} solving a challenge this client received for this action; valid once within five minutes. Accepted in the JSON body of every step-up route."},"AuthStepUpError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["auth-challenge-required","rate-limit-exceeded"]},"challenge":{"type":"object","description":"Present with auth-challenge-required: an ALTCHA v1 challenge (altcha-lib 2.5.0).","required":["algorithm","challenge","maxnumber","salt","signature"],"properties":{"algorithm":{"type":"string","enum":["SHA-256"]},"challenge":{"type":"string"},"maxnumber":{"type":"integer"},"salt":{"type":"string"},"signature":{"type":"string"}}},"scope":{"type":"string","description":"auth.step_up for the per-client step-up ceiling, otherwise the retained per-email auth limit"},"limit":{"type":"integer"},"remaining":{"type":"integer"},"retryAfterSeconds":{"type":"integer"},"resetAt":{"type":"string","format":"date-time"}}},"PasswordResetRequestResponse":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true]}}},"PasswordResetConfirmation":{"type":"object","required":["token","password"],"properties":{"token":{"type":"string"},"password":{"type":"string"}}},"PasswordResetConfirmationResponse":{"type":"object","required":["ok","status","providerSignInsDisconnected"],"properties":{"ok":{"type":"boolean","enum":[true]},"status":{"type":"string","enum":["reset"]},"providerSignInsDisconnected":{"type":"boolean","description":"Whether the reset removed at least one linked Google or GitHub sign-in"}}},"PasswordResetLinkError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["password-reset-link-invalid","password-reset-link-used","password-reset-link-expired","password-reset-link-replaced"]},"status":{"type":"string","enum":["invalid","used","expired","replaced"]}}},"PasswordPolicyError":{"type":"object","required":["error","reason","minLength","maxLength"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["password-required","password-too-short","password-too-long"]},"minLength":{"type":"integer","enum":[16]},"maxLength":{"type":"integer","enum":[256]}}},"PasswordResetRateLimitError":{"type":"object","required":["error","reason","scope"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["rate-limit-exceeded"]},"scope":{"type":"string","enum":["auth.password_reset_email","auth.password_reset_confirm"]},"limit":{"type":"integer"},"remaining":{"type":"integer"},"retryAfterSeconds":{"type":"integer"},"resetAt":{"type":"string","format":"date-time"}}},"PasswordHashingBusyError":{"type":"object","required":["error","reason","retryable"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["password-hashing-saturated"]},"retryable":{"type":"boolean","enum":[true]}}},"PasswordResetUnavailableError":{"type":"object","required":["error","reason"],"properties":{"error":{"type":"string"},"reason":{"type":"string","enum":["password-reset-unavailable"]}}},"AuthProviderHandoffResponse":{"type":"object","required":["ok","provider","handoffToken","returnTo","identity"],"properties":{"ok":{"type":"boolean"},"provider":{"type":"string","enum":["google","github"]},"handoffToken":{"type":"string"},"returnTo":{"type":"string"},"identity":{"oneOf":[{"$ref":"#/components/schemas/AuthIdentitySummary"},{"type":"null"}]}}},"AuthProviderExchangeResponse":{"allOf":[{"$ref":"#/components/schemas/AuthResponse"},{"type":"object","required":["provider","returnTo"],"properties":{"provider":{"type":"string","enum":["google","github"]},"returnTo":{"type":"string"}}}]},"SessionResponse":{"type":"object","required":["user","authAccessState","emailVerification","capabilities","clientIp"],"properties":{"user":{"$ref":"#/components/schemas/AuthUser"},"authAccessState":{"type":"string","enum":["verified","email_verification_required"]},"emailVerification":{"type":"object","required":["required","verified","sent"],"properties":{"required":{"type":"boolean"},"verified":{"type":"boolean"},"sent":{"type":"boolean"}}},"capabilities":{"$ref":"#/components/schemas/SessionCapabilities"},"clientIp":{"type":["string","null"]}}},"AuthIdentitySummary":{"type":"object","required":["provider","providerEmail","providerEmailVerifiedAt","providerLogin","providerAvatarUrl","linkedAt","lastLoginAt"],"properties":{"provider":{"type":"string","enum":["google","github"]},"providerEmail":{"type":["string","null"]},"providerEmailVerifiedAt":{"type":["string","null"],"format":"date-time"},"providerLogin":{"type":["string","null"]},"providerAvatarUrl":{"type":["string","null"]},"linkedAt":{"type":["string","null"],"format":"date-time"},"lastLoginAt":{"type":["string","null"],"format":"date-time"}}},"AuthIdentitiesResponse":{"type":"object","required":["identities","hasPassword"],"properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/AuthIdentitySummary"}},"hasPassword":{"type":"boolean"}}},"AuthIdentityDeleteResponse":{"type":"object","required":["deletedIdentity","identities","hasPassword"],"properties":{"deletedIdentity":{"oneOf":[{"$ref":"#/components/schemas/AuthIdentitySummary"},{"type":"null"}]},"identities":{"type":"array","items":{"$ref":"#/components/schemas/AuthIdentitySummary"}},"hasPassword":{"type":"boolean"}}},"AuthBootstrapResponse":{"type":"object","required":["user","authAccessState","emailVerification","capabilities","clientIp","workspace","githubAccount","githubState","notificationSummary","bootstrapVersion"],"properties":{"user":{"$ref":"#/components/schemas/AuthUser"},"authAccessState":{"type":"string","enum":["verified","email_verification_required"]},"emailVerification":{"type":"object","required":["required","verified","sent"],"properties":{"required":{"type":"boolean"},"verified":{"type":"boolean"},"sent":{"type":"boolean"}}},"capabilities":{"$ref":"#/components/schemas/SessionCapabilities"},"clientIp":{"anyOf":[{"type":"string"},{"type":"null"}]},"workspace":{"$ref":"#/components/schemas/SessionWorkspace"},"githubAccount":{"$ref":"#/components/schemas/GitHubAccount"},"githubState":{"$ref":"#/components/schemas/GitHubStateSummary"},"notificationSummary":{"$ref":"#/components/schemas/NotificationSummary"},"bootstrapVersion":{"type":"integer"},"projectList":{"type":"object","description":"Present only with includeProjectList=1. body is ProjectsResponse when statusCode is 200, else the error GET /projects would return, with this response's requestId; headers then carries its retry-after. The part runs after the bootstrap read within one 2 s budget, past which it is a 503 db-read-timeout.","required":["statusCode","body"],"properties":{"statusCode":{"type":"integer"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"anyOf":[{"$ref":"#/components/schemas/ProjectsResponse"},{"type":"object"}]}}},"projectDashboard":{"description":"Present only with includeProjectDashboard=1; null when the workspace has no project. body is ProjectDashboardResponse when statusCode is 200, else the error GET /projects/{id}/dashboard would return for projectId, as for projectList.","anyOf":[{"type":"object","required":["projectId","statusCode","body"],"properties":{"projectId":{"type":"string"},"statusCode":{"type":"integer"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"anyOf":[{"$ref":"#/components/schemas/ProjectDashboardResponse"},{"type":"object"}]}}},{"type":"null"}]}}},"SessionCapabilities":{"type":"object","required":["operator","ownerOperator"],"properties":{"operator":{"type":"boolean"},"ownerOperator":{"type":"boolean"}}},"OperatorCountGroup":{"type":"object","required":["key","count"],"properties":{"key":{"type":"string"},"count":{"type":"integer"}}},"OperatorPairCountGroup":{"type":"object","required":["key","status","count"],"properties":{"key":{"type":"string"},"status":{"type":"string"},"count":{"type":"integer"}}},"OperatorSummaryMetric":{"type":"object","required":["key","label","value"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"number"},"unit":{"type":"string"},"availability":{"type":"string","enum":["available","unavailable"]}}},"OperatorChartPoint":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"value":{"type":["number","null"]}}},"OperatorChartSeries":{"type":"object","required":["key","label","unit","points"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"unit":{"type":"string","enum":["number","requests","bytes","seconds","gb_seconds","EUR"]},"points":{"type":"array","maxItems":30,"items":{"$ref":"#/components/schemas/OperatorChartPoint"}}}},"OperatorScope":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["read_only"]}}},"OperatorAnalyticsTabList":{"type":"array","maxItems":5,"items":{"type":"object","required":["key","label","availability"],"properties":{"key":{"type":"string","enum":["health","growth","revenue","usage","drift"]},"label":{"type":"string"},"availability":{"type":"string","enum":["available","unavailable"]}}}},"OperatorSourceBuildTimingStat":{"type":"object","required":["availability","sampleCount","avgSeconds","p50Seconds","p95Seconds","maxSeconds"],"properties":{"availability":{"type":"string","enum":["available","unavailable"]},"sampleCount":{"type":"integer"},"avgSeconds":{"type":["integer","null"]},"p50Seconds":{"type":["integer","null"]},"p95Seconds":{"type":["integer","null"]},"maxSeconds":{"type":["integer","null"]}}},"OperatorSourceBuildCapacity":{"type":"object","required":["availability","window","admission","queue","activeAttempts","terminalAttempts","timings"],"properties":{"availability":{"type":"string","enum":["available","unavailable"]},"window":{"type":"object","required":["label","start","end"],"properties":{"label":{"type":"string","enum":["30d"]},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"admission":{"type":"object","required":["globalCap","activeGlobal","availableGlobalSlots","byPool"],"properties":{"globalCap":{"type":["integer","null"],"minimum":1,"maximum":100},"activeGlobal":{"type":"integer","minimum":0},"availableGlobalSlots":{"type":["integer","null"],"minimum":0},"byPool":{"type":"array","maxItems":1,"items":{"type":"object","required":["poolCode","cap","active","availableSlots","reason"],"properties":{"poolCode":{"type":"string","enum":["source_build_paketo"]},"cap":{"type":"integer","minimum":1,"maximum":100},"active":{"type":"integer","minimum":0},"availableSlots":{"type":"integer","minimum":0},"reason":{"type":"string","enum":["available","capacity-full"]}}}}}},"queue":{"type":"object","required":["pendingEligibleJobs","oldestPendingAgeSeconds"],"properties":{"pendingEligibleJobs":{"type":"integer","minimum":0},"oldestPendingAgeSeconds":{"type":["integer","null"],"minimum":0}}},"activeAttempts":{"type":"object","required":["total","oldestActiveAgeSeconds","byPoolStatus"],"properties":{"total":{"type":"integer"},"oldestActiveAgeSeconds":{"type":["integer","null"]},"byPoolStatus":{"type":"array","maxItems":20,"items":{"type":"object","required":["poolCode","poolKind","status","count"],"properties":{"poolCode":{"type":"string","enum":["source_build_paketo","github_hosted_default","self_hosted_wsl_backup","unknown"]},"poolKind":{"type":"string","enum":["scaleway_jobs","github_hosted","self_hosted","unknown"]},"status":{"type":"string","enum":["selected","dispatching","dispatched","unknown"]},"count":{"type":"integer"}}}}}},"terminalAttempts":{"type":"object","required":["total","byPoolReason"],"properties":{"total":{"type":"integer"},"byPoolReason":{"type":"array","maxItems":20,"items":{"type":"object","required":["poolCode","status","reasonCode","count"],"properties":{"poolCode":{"type":"string","enum":["source_build_paketo","github_hosted_default","self_hosted_wsl_backup","unknown"]},"status":{"type":"string","enum":["dispatch_failed","reconciled_terminal","unknown"]},"reasonCode":{"type":"string"},"count":{"type":"integer"}}}}}},"timings":{"type":"object","required":["dispatchWaitSeconds"],"properties":{"dispatchWaitSeconds":{"$ref":"#/components/schemas/OperatorSourceBuildTimingStat"}}}}},"OperatorAnalytics":{"type":"object","required":["window","tabs","growth","revenue","usage","sourceBuildCapacity"],"properties":{"window":{"type":"object","required":["label","start","end"],"properties":{"label":{"type":"string"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"tabs":{"$ref":"#/components/schemas/OperatorAnalyticsTabList"},"growth":{"type":"object","required":["availability","summary","funnel","daily"],"properties":{"availability":{"type":"string","enum":["available","unavailable"]},"summary":{"type":"array","items":{"$ref":"#/components/schemas/OperatorSummaryMetric"}},"funnel":{"type":"array","items":{"type":"object","required":["key","label","count","rateFromPrevious"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"count":{"type":"integer"},"rateFromPrevious":{"type":["number","null"]}}}},"daily":{"type":"array","maxItems":30,"items":{"type":"object","required":["day","signups","projectsCreated","deploymentsHealthy","resourcesCreated"],"properties":{"day":{"type":"string","format":"date-time"},"signups":{"type":"integer"},"projectsCreated":{"type":"integer"},"deploymentsHealthy":{"type":"integer"},"resourcesCreated":{"type":"integer"}}}}}},"revenue":{"type":"object","required":["availability","summary","plans","finalizedUsageSeries"],"properties":{"availability":{"type":"string","enum":["available","unavailable"]},"summary":{"type":"array","items":{"$ref":"#/components/schemas/OperatorSummaryMetric"}},"plans":{"type":"array","maxItems":20,"items":{"type":"object","required":["planId","status","entitlementStatus","count"],"properties":{"planId":{"type":"string"},"status":{"type":"string"},"entitlementStatus":{"type":"string"},"count":{"type":"integer"}}}},"finalizedUsageSeries":{"type":"array","items":{"$ref":"#/components/schemas/OperatorChartSeries"}}}},"usage":{"type":"object","required":["availability","summary","topConsumers","usageSeries"],"properties":{"availability":{"type":"string","enum":["available","unavailable"]},"summary":{"type":"array","items":{"$ref":"#/components/schemas/OperatorSummaryMetric"}},"topConsumers":{"type":"array","maxItems":10,"items":{"type":"object","required":["projectId","projectName","primaryMetric","primaryMetricLabel","primaryUnit","primaryValue","totalValue","resourceCount","storageBytes"],"properties":{"projectId":{"type":"string"},"projectName":{"type":"string"},"primaryMetric":{"type":"string"},"primaryMetricLabel":{"type":"string"},"primaryUnit":{"type":"string","enum":["bytes","seconds","gb_seconds","number"]},"primaryValue":{"type":"number"},"totalValue":{"type":"number"},"resourceCount":{"type":"integer"},"storageBytes":{"type":"integer"}}}},"usageSeries":{"type":"array","items":{"$ref":"#/components/schemas/OperatorChartSeries"}}}},"sourceBuildCapacity":{"$ref":"#/components/schemas/OperatorSourceBuildCapacity"}}},"OperatorHealthBucket":{"type":"object","required":["key","label","status","count"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"status":{"type":"string","enum":["none","healthy","notice","warning","error"]},"count":{"type":"integer"}}},"OperatorHealthRow":{"type":"object","required":["key","label","buckets"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/OperatorHealthBucket"}}}},"OperatorInventoryRow":{"type":"object","required":["id","kind","label","projectId","projectName","status","resourceCount","traffic24h","protected"],"properties":{"id":{"type":"string"},"kind":{"type":"string"},"label":{"type":"string"},"projectId":{"type":"string"},"projectName":{"type":["string","null"]},"projectSlug":{"type":["string","null"]},"ownerStatus":{"type":["string","null"]},"status":{"type":"string"},"resourceCount":{"type":"integer"},"traffic24h":{"type":"integer"},"cpuPercent":{"type":["number","null"]},"memoryPercent":{"type":["number","null"]},"storagePercent":{"type":["number","null"]},"storageBytes":{"type":["integer","null"]},"routeStatus":{"type":["string","null"]},"resourceStatus":{"type":["string","null"]},"protected":{"type":"boolean"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"OperatorResourceWorklistRow":{"type":"object","required":["id","kind","label","projectId","projectName","status","provider","resourceType","protected"],"properties":{"id":{"type":"string"},"kind":{"type":"string"},"label":{"type":"string"},"projectId":{"type":"string"},"projectName":{"type":["string","null"]},"status":{"type":"string"},"provider":{"type":"string"},"resourceType":{"type":"string"},"protected":{"type":"boolean"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"InternalSignupProgress":{"type":"object","required":["id","email","status","signInMethods","stage","steps","projectCount","deploymentCount","lastDeploymentAt","lastDeploymentStatus","requests7d","errors7d","problems"],"properties":{"id":{"type":"string"},"email":{"type":"string"},"status":{"type":"string"},"signInMethods":{"type":"array","items":{"type":"string","description":"email, or a linked identity provider such as github or google"}},"stage":{"type":"string","enum":["signed_up","email_verified","github_connected","project_created","deployed","live"]},"steps":{"type":"object","required":["signedUpAt","emailVerifiedAt","githubConnectedAt","firstProjectAt","firstDeploymentAt","firstLiveAt"],"properties":{"signedUpAt":{"type":"string","format":"date-time"},"emailVerifiedAt":{"type":["string","null"],"format":"date-time"},"githubConnectedAt":{"type":["string","null"],"format":"date-time"},"firstProjectAt":{"type":["string","null"],"format":"date-time"},"firstDeploymentAt":{"type":["string","null"],"format":"date-time"},"firstLiveAt":{"type":["string","null"],"format":"date-time"}}},"projectCount":{"type":"integer"},"deploymentCount":{"type":"integer"},"lastDeploymentAt":{"type":["string","null"],"format":"date-time"},"lastDeploymentStatus":{"type":["string","null"]},"requests7d":{"type":"integer","description":"App and Function requests to the user's live projects in the last 168 hours"},"errors7d":{"type":"integer","description":"5xx responses among requests7d"},"problems":{"type":"array","items":{"type":"string","enum":["route_issue","suspended","deployment_failed","container_failed","function_failed","quota_blocked"]}}}},"InternalSignupListResponse":{"type":"object","required":["windowDays","page","limit","total","funnel","items"],"properties":{"windowDays":{"type":["integer","null"],"description":"null for all time"},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer","description":"Signups matching the filters"},"funnel":{"type":"array","description":"Signups in the window that reached each step, unfiltered","items":{"type":"object","required":["stage","count"],"properties":{"stage":{"type":"string"},"count":{"type":"integer"}}}},"items":{"type":"array","items":{"$ref":"#/components/schemas/InternalSignupProgress"}}}},"SignupQuotaPlan":{"type":"object","required":["code","name","source","grant"],"properties":{"code":{"type":"string"},"name":{"type":"string"},"source":{"type":"string","enum":["free","subscription","operator_grant"]},"grant":{"type":["object","null"],"required":["id","createdAt","grantedByUserId"],"properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"grantedByUserId":{"type":["string","null"]}}}}},"SignupQuotaMeter":{"type":"object","required":["metricCode","actionCode","label","unit","used","limit","resetAt","state","projectId","projectName"],"properties":{"metricCode":{"type":"string"},"actionCode":{"type":"string"},"label":{"type":"string"},"unit":{"type":"string"},"used":{"type":["string","null"],"description":"Decimal amount; null when the tenant usage reader is unavailable"},"reserved":{"type":["string","null"]},"limit":{"type":"string"},"resetAt":{"type":["string","null"],"format":"date-time"},"state":{"type":"string","enum":["ok","blocked","unavailable"]},"projectId":{"type":["string","null"],"description":"Set for limits enforced per project"},"projectName":{"type":["string","null"]}}},"SignupQuota":{"description":"Own-plan quota; null means no own plan. Unavailable quota does not hide signup detail.","oneOf":[{"type":"null"},{"type":"object","required":["state","reason"],"additionalProperties":false,"properties":{"state":{"const":"unavailable"},"reason":{"const":"quota-state-unavailable"}}},{"type":"object","required":["state","organizationId","plan","period","meters","functionQuota","subscriptionPlan","grantablePlanCodes"],"properties":{"state":{"const":"available"},"organizationId":{"type":"string"},"plan":{"$ref":"#/components/schemas/SignupQuotaPlan"},"subscriptionPlan":{"type":["object","null"],"required":["code","name"],"properties":{"code":{"type":"string"},"name":{"type":"string"}}},"grantablePlanCodes":{"type":"array","items":{"type":"string","enum":["starter","pro"]}},"period":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"meters":{"type":"array","items":{"$ref":"#/components/schemas/SignupQuotaMeter"}},"functionQuota":{"type":["object","null"],"required":["state","revision"],"properties":{"state":{"type":"string","enum":["allowed","blocked","unavailable"]},"revision":{"type":["string","null"]}}}}}]},"SignupQuotaActionRequest":{"oneOf":[{"type":"object","additionalProperties":false,"required":["action","reason","clientRequestId","confirmEmail","planCode"],"properties":{"action":{"type":"string","enum":["grant_plan"]},"reason":{"type":"string","minLength":10,"maxLength":2000,"description":"Must not contain NUL or unpaired UTF-16 surrogates"},"clientRequestId":{"type":"string","minLength":16,"maxLength":64,"pattern":"^[A-Za-z0-9_-]{16,64}$"},"confirmEmail":{"type":"string","maxLength":320,"description":"Must equal the target email, case-insensitively"},"planCode":{"type":"string","enum":["starter","pro"]}}},{"type":"object","additionalProperties":false,"required":["action","reason","clientRequestId","confirmEmail"],"properties":{"action":{"type":"string","enum":["revoke_plan"]},"reason":{"type":"string","minLength":10,"maxLength":2000,"description":"Must not contain NUL or unpaired UTF-16 surrogates"},"clientRequestId":{"type":"string","minLength":16,"maxLength":64,"pattern":"^[A-Za-z0-9_-]{16,64}$"},"confirmEmail":{"type":"string","maxLength":320,"description":"Must equal the target email, case-insensitively"}}},{"type":"object","additionalProperties":false,"required":["action","reason","clientRequestId","confirmEmail"],"properties":{"action":{"type":"string","enum":["release_stuck_quota"]},"reason":{"type":"string","minLength":10,"maxLength":2000,"description":"Must not contain NUL or unpaired UTF-16 surrogates"},"clientRequestId":{"type":"string","minLength":16,"maxLength":64,"pattern":"^[A-Za-z0-9_-]{16,64}$"},"confirmEmail":{"type":"string","maxLength":320,"description":"Must equal the target email, case-insensitively"}}},{"type":"object","additionalProperties":false,"required":["action","reason","clientRequestId","confirmEmail"],"properties":{"action":{"type":"string","enum":["reset_daily_deployments"]},"reason":{"type":"string","minLength":10,"maxLength":2000,"description":"Must not contain NUL or unpaired UTF-16 surrogates"},"clientRequestId":{"type":"string","minLength":16,"maxLength":64,"pattern":"^[A-Za-z0-9_-]{16,64}$"},"confirmEmail":{"type":"string","maxLength":320,"description":"Must equal the target email, case-insensitively"}}}]},"SignupQuotaActionSnapshot":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/SignupQuotaPlan"},"meters":{"type":"array","items":{"$ref":"#/components/schemas/SignupQuotaMeter"}}}},"SignupQuotaActionResponse":{"type":"object","required":["id","action","userId","organizationId","before","after","createdAt"],"properties":{"id":{"type":"string"},"action":{"type":"string","enum":["grant_plan","revoke_plan","release_stuck_quota","reset_daily_deployments"]},"userId":{"type":"string"},"organizationId":{"type":"string"},"before":{"$ref":"#/components/schemas/SignupQuotaActionSnapshot"},"after":{"$ref":"#/components/schemas/SignupQuotaActionSnapshot"},"createdAt":{"type":"string","format":"date-time"}}},"InternalSignupDetailResponse":{"type":"object","required":["signup","quota","quotaBlock","projects","deployments"],"properties":{"signup":{"$ref":"#/components/schemas/InternalSignupProgress"},"quota":{"$ref":"#/components/schemas/SignupQuota"},"quotaBlock":{"type":["object","null"],"description":"Latest quota block from the last 7 days that has not reset or been followed by an allowed decision for the same limit","properties":{"metricCode":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"projects":{"type":"array","items":{"type":"object","required":["id","name","createdAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectSlug":{"type":["string","null"]},"projectHostname":{"type":["string","null"]},"repoFullName":{"type":["string","null"]},"framework":{"type":["string","null"]},"frameworkLabel":{"type":["string","null"]},"deploymentMode":{"type":["string","null"]},"lifecycleState":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"problems":{"type":"array","description":"Open problems of a live project; empty for deleted projects","items":{"type":"string","enum":["route_issue","suspended","deployment_failed","container_failed","function_failed"]}},"requests7d":{"type":"integer"},"errors7d":{"type":"integer"},"averageLatencyMs7d":{"type":["integer","null"]}}}},"deployments":{"type":"array","items":{"type":"object","required":["id","kind","projectId","projectName","status","createdAt"],"properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["app","function"]},"projectId":{"type":"string"},"projectName":{"type":"string"},"functionName":{"type":["string","null"]},"status":{"type":"string"},"sourceType":{"type":["string","null"]},"repoFullName":{"type":["string","null"]},"branch":{"type":["string","null"]},"commitSha":{"type":["string","null"]},"url":{"type":["string","null"]},"lastError":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}}}}},"InternalOperatorOverviewResponse":{"type":"object","required":["generatedAt","source","scope","grafana","dashboard","dataSources","coverage"],"properties":{"generatedAt":{"type":"string","format":"date-time"},"source":{"type":"string","enum":["operator-config"]},"scope":{"$ref":"#/components/schemas/OperatorScope"},"grafana":{"type":"object","required":["status","url","label","dashboards"],"properties":{"status":{"type":"string","enum":["configured","missing","invalid"]},"url":{"type":["string","null"],"format":"uri"},"label":{"type":"string"},"dashboards":{"type":"array","items":{"type":"object","required":["key","status","url","label"],"properties":{"key":{"type":"string","enum":["command_center","control_plane"]},"status":{"type":"string","enum":["configured","missing","invalid"]},"url":{"type":["string","null"],"format":"uri"},"label":{"type":"string"}}}}}},"dashboard":{"type":"object","required":["uid","title","folder","refresh","timeRange","status"],"properties":{"uid":{"type":"string"},"title":{"type":"string"},"folder":{"type":"string"},"refresh":{"type":"string"},"timeRange":{"type":"string"},"status":{"type":"string","enum":["not_verified","launcher_unavailable"]}}},"dataSources":{"type":"array","items":{"type":"object","required":["key","label","source","status"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"source":{"type":"string","enum":["cockpit_custom_metrics","cockpit_native_metrics","cockpit_native_logs"]},"status":{"type":"string","enum":["not_verified"]}}}},"coverage":{"type":"array","items":{"type":"object","required":["key","label"],"properties":{"key":{"type":"string","enum":["market","traffic","usage","billing"]},"label":{"type":"string"}}}},"maintenance":{"type":"object","required":["status","runs"],"properties":{"status":{"type":"string","enum":["success","partial_failure","failed","no_runs"]},"consecutiveFailures":{"type":"integer"},"threshold":{"type":"integer"},"thresholdReached":{"type":"boolean"},"runs":{"type":"array","items":{"type":"object","required":["runId","status","summary"],"properties":{"runId":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"failedPhase":{"type":["string","null"]},"errorClass":{"type":["string","null"]},"summary":{"type":"object"}}}}}}}},"OrganizationMembership":{"type":["object","null"],"required":["id","organizationId","userId","status","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"userId":{"type":"string"},"status":{"type":"string","enum":["active","invited","suspended"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"OrganizationSummary":{"type":"object","required":["id","name","projectCount","membership","createdByUserId","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectCount":{"type":"integer"},"membership":{"$ref":"#/components/schemas/OrganizationMembership"},"createdByUserId":{"type":"string"},"canRename":{"type":"boolean","description":"Whether the caller is the billing owner and may rename it. Present on organization reads, not on the session workspace."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SessionWorkspace":{"type":"object","required":["currentOrganizationId","accessibleProjectCount","defaultProject","organizations"],"properties":{"currentOrganizationId":{"type":["string","null"]},"accessibleProjectCount":{"type":"integer"},"defaultProject":{"oneOf":[{"$ref":"#/components/schemas/SessionProjectSummary"},{"type":"null"}]},"organizations":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationSummary"}}}},"SessionProjectSummary":{"type":"object","required":["id","name","projectRole","branch"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"projectRole":{"type":["string","null"]},"branch":{"type":"string"}}},"OrganizationsResponse":{"type":"object","required":["organizations"],"properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationSummary"}}}},"OrganizationResponse":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationSummary"}}},"FeedbackSubmitRequest":{"type":"object","required":["kind","message","routePath"],"properties":{"projectId":{"type":["string","null"]},"kind":{"type":"string","enum":["bug","suggestion"]},"message":{"type":"string","minLength":1,"maxLength":5000},"routePath":{"type":"string","maxLength":512},"routeQuery":{"type":["string","null"],"maxLength":1024},"viewport":{"type":"object","properties":{"width":{"type":"integer","minimum":1,"maximum":10000},"height":{"type":"integer","minimum":1,"maximum":10000}}},"screenshot":{"oneOf":[{"type":"object","required":["contentType","base64"],"properties":{"contentType":{"type":"string","enum":["image/webp","image/png"]},"base64":{"type":"string","contentEncoding":"base64"}}},{"type":"null"}]}}},"FeedbackScreenshotSummary":{"type":"object","required":["attached","contentType","byteSize"],"properties":{"attached":{"type":"boolean"},"contentType":{"type":["string","null"],"enum":["image/webp","image/png",null]},"byteSize":{"type":["integer","null"]}}},"FeedbackSubmission":{"type":"object","required":["id","createdAt","createdByUserId","kind","message","routePath","routeQuery","viewport","screenshot","status"],"properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"createdByUserId":{"type":"string"},"createdByEmail":{"type":["string","null"]},"organizationId":{"type":["string","null"]},"projectId":{"type":["string","null"]},"projectName":{"type":["string","null"]},"projectSlug":{"type":["string","null"]},"kind":{"type":"string","enum":["bug","suggestion"]},"message":{"type":["string","null"]},"routePath":{"type":"string"},"routeQuery":{"type":"string"},"viewport":{"type":"object","required":["width","height"],"properties":{"width":{"type":["integer","null"]},"height":{"type":["integer","null"]}}},"screenshot":{"$ref":"#/components/schemas/FeedbackScreenshotSummary"},"status":{"type":"string","enum":["new","reviewed","archived"]},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewedByUserId":{"type":["string","null"]},"archivedAt":{"type":["string","null"],"format":"date-time"}}},"FeedbackSubmitResponse":{"type":"object","required":["feedback"],"properties":{"feedback":{"$ref":"#/components/schemas/FeedbackSubmission"}}},"InternalFeedbackListResponse":{"type":"object","required":["items","limit","nextCursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FeedbackSubmission"}},"limit":{"type":"integer"},"nextCursor":{"type":["string","null"]}}},"InternalFeedbackDetailResponse":{"type":"object","required":["feedback"],"properties":{"feedback":{"$ref":"#/components/schemas/FeedbackSubmission"}}},"InternalFeedbackUpdateRequest":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["new","reviewed","archived"]}}},"ProjectMember":{"type":"object","required":["id","projectId","organizationMembershipId","organizationId","organizationMembershipStatus","role","createdAt","updatedAt","user"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"organizationMembershipId":{"type":"string"},"organizationId":{"type":"string"},"organizationMembershipStatus":{"type":"string","enum":["active","invited","suspended"]},"role":{"type":"string","enum":["owner","admin","contributor"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"user":{"type":"object","required":["id","email","createdAt"],"properties":{"id":{"type":"string"},"email":{"type":"string"},"status":{"type":["string","null"]},"deleteRequestedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}},"ProjectInvitation":{"type":"object","required":["id","projectId","email","role","status","expiresAt","createdAt"],"properties":{"id":{"type":"string"},"projectId":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","contributor"]},"status":{"type":"string","enum":["pending","expired"]},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"projectName":{"type":"string"},"invitedByEmail":{"type":"string"}}},"ProjectInvitationRequest":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","contributor"]}}},"ProjectInvitationResponse":{"type":"object","required":["invitation","emailDelivery"],"properties":{"invitation":{"$ref":"#/components/schemas/ProjectInvitation"},"emailDelivery":{"type":"string","enum":["sent","failed","not_configured"]}}},"MyProjectInvitationsResponse":{"type":"object","required":["invitations"],"properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/ProjectInvitation"}}}},"WorkspaceDomainRequest":{"type":"object","required":["organizationId","hostname"],"properties":{"organizationId":{"type":"string"},"hostname":{"type":"string","example":"example.com"},"projectId":{"type":["string","null"],"description":"The project the domain serves; omitted or null to add it unlinked"}}},"ProjectDomain":{"type":"object","required":["id","hostname","status","statusReason","zone","records","dnsTargetState","certificateState","www","converging","checkedAt","activeAt","createdAt"],"properties":{"id":{"type":"string"},"hostname":{"type":"string"},"status":{"type":"string","enum":["pending","issuing","active","failed"]},"statusReason":{"type":["string","null"],"enum":["verification_timeout","certificate_failed","challenge_record_missing","challenge_record_removed",null]},"records":{"type":"array","description":"The records to add, each with what public DNS shows. A zone apex also lists its www companion (_acme-challenge.www and www), which redirects to the apex.","items":{"type":"object","required":["type","name","host","value","purpose","state"],"properties":{"type":{"type":"string","enum":["CNAME","A"]},"name":{"type":"string","description":"Fully qualified record name"},"host":{"type":["string","null"],"description":"Record name relative to the domain DNS zone (@ for the zone itself); null until the zone is known"},"value":{"type":["string","null"],"description":"Null only while custom domains are unavailable"},"purpose":{"type":"string","enum":["verification","traffic"]},"state":{"type":"string","enum":["ok","waiting","elsewhere"],"description":"elsewhere: a traffic record that resolves to an address other than the edge"},"observed":{"type":"array","items":{"type":"string"}},"aliasValue":{"type":"string","description":"For an A record: the hostname an ALIAS, ANAME or flattened CNAME may point to instead"},"acceptedValue":{"type":"string","description":"For the www record of a zone apex: the apex, which the CNAME may point to instead"}}}},"zone":{"type":["string","null"],"description":"The DNS zone the domain lives in, once public DNS shows it"},"dnsTargetState":{"type":"string","enum":["unknown","ok","elsewhere","missing"]},"certificateState":{"type":"string","enum":["waiting","issuing","issued"]},"www":{"type":["object","null"],"description":"A zone apex only: its www companion, which redirects to the apex while the apex certificate covers it. requested: being added to the certificate; issued: covered; failing: covered but not renewing; failed: not covered within 24 hours, so it was removed and the apex renews alone.","required":["name","certificateState"],"properties":{"name":{"type":"string"},"certificateState":{"type":"string","enum":["none","requested","issued","failing","failed"]}}},"converging":{"type":"boolean","description":"The domain will change state without anyone acting (pending or issuing)"},"checkedAt":{"type":["string","null"],"format":"date-time"},"activeAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"ProjectDomainResponse":{"type":"object","required":["domain"],"properties":{"domain":{"$ref":"#/components/schemas/ProjectDomain"}}},"WorkspaceDomainsResponse":{"type":"object","required":["domains","canManage","linkableProjects","availability","used","limit"],"properties":{"canManage":{"type":"boolean","description":"Whether the caller owns the workspace and so adds, links, unlinks and removes its domains"},"linkableProjects":{"type":"array","description":"Workspace projects a domain can be linked to; empty unless the caller owns the workspace","items":{"type":"object","required":["id","name","hostname","repoFullName","branch"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"hostname":{"type":["string","null"]},"repoFullName":{"type":["string","null"]},"branch":{"type":["string","null"]}}}},"used":{"type":"integer","description":"Domains the workspace has, linked or not; the limit applies to this count"},"domains":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ProjectDomain"},{"type":"object","required":["project"],"properties":{"project":{"type":["object","null"],"description":"The project the domain serves; null while it is not linked","required":["id","name","hostname","repoFullName","branch"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"hostname":{"type":["string","null"],"description":"The project production hostname the domain serves"},"repoFullName":{"type":["string","null"]},"branch":{"type":["string","null"]}}}}}]}},"availability":{"type":"string","enum":["available","unavailable"]},"limit":{"type":"integer","description":"Domains this workspace may have: 1 on Free, 10 on paid plans"}}},"ProjectMembersResponse":{"type":"object","required":["project","members","invitations"],"properties":{"project":{"$ref":"#/components/schemas/ProjectSummary"},"members":{"type":"array","items":{"$ref":"#/components/schemas/ProjectMember"}},"invitations":{"type":"array","items":{"$ref":"#/components/schemas/ProjectInvitation"}}}},"ProjectMemberUpsertRequest":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","contributor"]},"transferOwnership":{"type":"boolean","description":"Explicitly transfer this project and, if managed by the caller, its shared billing responsibility to this existing member."},"confirmation":{"type":"string","description":"Exact project name required for ownership transfer."}}},"ProjectMemberResponse":{"type":"object","required":["member"],"properties":{"member":{"$ref":"#/components/schemas/ProjectMember"},"detachedAppRepo":{"type":"boolean"},"ok":{"type":"boolean"}}},"InternalAdminTableColumn":{"type":"object","required":["name","keyRole","sortable","filterable","referenceTable","dataType"],"properties":{"name":{"type":"string"},"keyRole":{"type":"string","enum":["none","primary","foreign"]},"sortable":{"type":"boolean"},"filterable":{"type":"boolean"},"referenceTable":{"type":["string","null"]},"dataType":{"type":["string","null"]}}},"InternalAdminTable":{"type":"object","required":["name","label","description","defaultSort","sortColumns","filterColumns","columnMetadata"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"defaultSort":{"type":"string"},"sortColumns":{"type":"array","items":{"type":"string"}},"filterColumns":{"type":"array","items":{"type":"string"}},"columnMetadata":{"type":"array","items":{"$ref":"#/components/schemas/InternalAdminTableColumn"}}}},"InternalAdminTablesResponse":{"type":"object","required":["tables"],"properties":{"tables":{"type":"array","items":{"$ref":"#/components/schemas/InternalAdminTable"}}}},"InternalAdminRowLink":{"type":"object","required":["kind","label","table"],"properties":{"kind":{"type":"string","enum":["record","rows"]},"label":{"type":"string"},"table":{"type":"string"},"rowId":{"type":["string","null"]},"filterColumn":{"type":["string","null"]},"filterValue":{"type":["string","null"]}}},"InternalAdminRowsResponse":{"type":"object","required":["table","totalCount","limit","offset","sort","direction","rows"],"properties":{"table":{"$ref":"#/components/schemas/InternalAdminTable"},"totalCount":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"sort":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]},"rows":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"InternalAdminRowResponse":{"type":"object","required":["table","rowId","row","relatedLinks"],"properties":{"table":{"$ref":"#/components/schemas/InternalAdminTable"},"rowId":{"type":"string"},"row":{"type":"object","additionalProperties":true},"relatedLinks":{"type":"array","items":{"$ref":"#/components/schemas/InternalAdminRowLink"}}}},"Notification":{"type":"object","required":["id","category","severity","title","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"organizationId":{"type":["string","null"]},"projectId":{"type":["string","null"]},"deploymentId":{"type":["string","null"]},"source":{"type":["string","null"]},"category":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"]},"tone":{"type":["string","null"],"enum":["success","warning","error","info"]},"title":{"type":"string"},"message":{"type":["string","null"]},"resourceType":{"type":["string","null"]},"resourceId":{"type":["string","null"]},"resourceLabel":{"type":["string","null"]},"resourceState":{"type":"string","enum":["available","pending_delete","inaccessible","none"]},"reason":{"type":["string","null"]},"primaryAction":{"anyOf":[{"type":"object","required":["label","path","enabled","disabledReason"],"properties":{"label":{"type":"string"},"path":{"type":"string"},"enabled":{"type":"boolean"},"disabledReason":{"type":["string","null"]}}},{"type":"null"}]},"readAt":{"type":["string","null"],"format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"NotificationSummary":{"type":"object","required":["unreadCount","criticalUnreadCount","updatedAt","cursor"],"properties":{"organizationId":{"type":["string","null"]},"unreadCount":{"type":"integer"},"criticalUnreadCount":{"type":"integer"},"latestUnreadAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"cursor":{"type":["string","null"]}}},"NotificationsSummaryResponse":{"type":"object","required":["notificationSummary"],"properties":{"notificationSummary":{"$ref":"#/components/schemas/NotificationSummary"}}},"NotificationsResponse":{"type":"object","required":["notifications","unreadCount","scopeUnreadCount","summary","projectOptions"],"properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"unreadCount":{"type":"integer"},"scopeUnreadCount":{"type":"integer"},"summary":{"$ref":"#/components/schemas/NotificationSummary"},"projectOptions":{"type":"array","items":{"$ref":"#/components/schemas/NotificationProjectOption"}},"filterCounts":{"type":"object","required":["inbox","unread","archived","critical"],"properties":{"inbox":{"type":"integer"},"unread":{"type":"integer"},"archived":{"type":"integer"},"critical":{"type":"integer"}}},"nextCursor":{"type":["string","null"]}}},"NotificationDetailProjection":{"type":"object","required":["threadId","statusLabel","sourceLabel","resourceTypeLabel","threadEventCount","firstEventAt","latestEventAt"],"properties":{"threadId":{"type":"string"},"statusLabel":{"type":"string"},"sourceLabel":{"type":"string"},"resourceTypeLabel":{"type":"string"},"threadEventCount":{"type":"integer"},"firstEventAt":{"type":"string","format":"date-time"},"latestEventAt":{"type":"string","format":"date-time"}}},"NotificationThreadEvent":{"type":"object","required":["id","title","severity","createdAt"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"message":{"type":["string","null"]},"severity":{"type":"string","enum":["info","warning","critical"]},"createdAt":{"type":"string","format":"date-time"}}},"NotificationDetailResponse":{"type":"object","required":["notification","detail","threadEvents"],"properties":{"notification":{"$ref":"#/components/schemas/Notification"},"detail":{"$ref":"#/components/schemas/NotificationDetailProjection"},"threadEvents":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/NotificationThreadEvent"}}}},"NotificationProjectOption":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"organizationId":{"type":["string","null"]}}},"NotificationsReadRequest":{"type":"object","properties":{"notificationId":{"type":"string"},"notificationIds":{"type":"array","maxItems":50,"items":{"type":"string"}},"allUnread":{"type":"boolean"},"view":{"type":"string","enum":["inbox","unread"]},"category":{"type":"string","enum":["deployment","runtime","github","usage","account"]},"severity":{"type":"string","enum":["info","warning","critical"]},"organizationId":{"type":"string"},"projectId":{"type":"string"},"q":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":50},"listPatch":{"type":"boolean"},"listPatchView":{"type":"string","enum":["inbox","unread","archived"]},"listPatchCategory":{"type":"string","enum":["deployment","runtime","github","usage","account"]},"listPatchSeverity":{"type":"string","enum":["info","warning","critical"]},"listPatchOrganizationId":{"type":"string"},"listPatchProjectId":{"type":"string"},"listPatchQuery":{"type":"string"},"listPatchCursor":{"type":"string"},"listPatchWindowSize":{"type":"integer","minimum":1,"maximum":50}}},"NotificationsArchiveRequest":{"type":"object","properties":{"notificationId":{"type":"string"},"notificationIds":{"type":"array","maxItems":50,"items":{"type":"string"}},"view":{"type":"string","enum":["inbox","unread","archived"]},"category":{"type":"string","enum":["deployment","runtime","github","usage","account"]},"severity":{"type":"string","enum":["info","warning","critical"]},"organizationId":{"type":"string"},"projectId":{"type":"string"},"q":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":50},"listPatch":{"type":"boolean"},"listPatchView":{"type":"string","enum":["inbox","unread","archived"]},"listPatchCategory":{"type":"string","enum":["deployment","runtime","github","usage","account"]},"listPatchSeverity":{"type":"string","enum":["info","warning","critical"]},"listPatchOrganizationId":{"type":"string"},"listPatchProjectId":{"type":"string"},"listPatchQuery":{"type":"string"},"listPatchCursor":{"type":"string"},"listPatchWindowSize":{"type":"integer","minimum":1,"maximum":50}}},"NotificationsReadResponse":{"type":"object","required":["ok","updatedCount","notificationSummary"],"properties":{"ok":{"type":"boolean"},"notificationId":{"type":["string","null"]},"updatedCount":{"type":"integer"},"readAt":{"type":["string","null"],"format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"},"notificationSummary":{"$ref":"#/components/schemas/NotificationSummary"},"listPatch":{"anyOf":[{"$ref":"#/components/schemas/NotificationsResponse"},{"type":"null"}]}}},"GitHubConnectResponse":{"type":"object","required":["url","nextAction"],"properties":{"url":{"type":"string"},"state":{"type":"string"},"nextAction":{"type":"string","enum":["oauth","install","manage","review"]}}},"GitHubReposResponse":{"type":"object","required":["githubAccount","installations","repos","accountStatus","installationCount","repoCount","sync","snapshotVersion","hasSavedAccess","projectCreateAvailable","recommendedAction","recoveryAction","navStatus","ready"],"properties":{"githubAccount":{"$ref":"#/components/schemas/GitHubAccount"},"installations":{"type":"array","items":{"$ref":"#/components/schemas/GitHubInstallation"}},"repos":{"type":"array","description":"Browser-safe repository rows after applying the bounded q and limit projection.","items":{"$ref":"#/components/schemas/GitHubRepo"}},"accountStatus":{"type":"string","enum":["none","unknown","connected","revoked"]},"accountStatusReason":{"type":["string","null"]},"accountVerifiedAt":{"type":["string","null"],"format":"date-time"},"sync":{"$ref":"#/components/schemas/GitHubSyncState"},"installationCount":{"type":"integer"},"repoCount":{"type":"integer","minimum":0,"description":"Sum of installation repository counts before q and limit are applied; it can exceed the returned or persisted repository rows when the snapshot is bounded or truncated. A missing stored installation count is normalized to 0 while ready remains false and recoveryAction remains refresh."},"snapshotVersion":{"type":"integer"},"snapshotUpdatedAt":{"type":["string","null"],"format":"date-time"},"hasSavedAccess":{"type":"boolean"},"projectCreateAvailable":{"type":"boolean"},"recommendedAction":{"type":"string","enum":["none","oauth","refresh","install","manage","review","disabled"]},"recoveryAction":{"$ref":"#/components/schemas/GitHubConnectAction"},"repositoryAccessAction":{"oneOf":[{"$ref":"#/components/schemas/GitHubConnectAction"},{"type":"null"}]},"navStatus":{"type":"object","required":["tone","label"],"properties":{"tone":{"type":"string","enum":["neutral","healthy","warning","danger"]},"label":{"type":"string"}}},"ready":{"type":"boolean"}}}}}}