From 478d95b35c34120d8eabbda591786bff0af7c7a1 Mon Sep 17 00:00:00 2001 From: Samir Ketema <6003000+samirketema@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:46:57 -0700 Subject: [PATCH 1/4] fix: display request body Array schema/fields in Management API Reference (#49575) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Fix/Docs Update - Fixes the Management API Reference ## What is the current behavior? Management API Reference cannot properly render request body fields of type `Array`. [Example here](https://supabase.com/docs/reference/api/v2-create-organization-invitations) CleanShot 2026-08-25 at 20 26 35 ## What is the new behavior? Properly expands the request body fields & schema: CleanShot 2026-08-25 at 20 27 09 ## Additional context N/A ## Summary by CodeRabbit * **UI Improvements** * Object and array-of-object API schemas now display summaries alongside expanded properties in clearly separated sections. * Improved handling of array item details and schema composition values for more reliable rendering. * Other schema types continue to use the existing detail-list presentation. * **Bug Fixes** * Prevented errors when displaying API specifications with incomplete array-item details or single-value schema combinations. --- apps/docs/features/docs/Reference.ui.tsx | 47 +++++++++++++++++++----- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/apps/docs/features/docs/Reference.ui.tsx b/apps/docs/features/docs/Reference.ui.tsx index 2cac82a4c0cb2..c8a2ee5704b75 100644 --- a/apps/docs/features/docs/Reference.ui.tsx +++ b/apps/docs/features/docs/Reference.ui.tsx @@ -381,6 +381,14 @@ interface ApiOperationRequestBodyDetailsInternalProps extends HTMLAttributes { + if (Array.isArray(value)) return value + if (value && typeof value === 'object') return [value] + return [] +} + function ApiOperationRequestBodyDetailsInternal({ schema, ...props @@ -389,7 +397,7 @@ function ApiOperationRequestBodyDetailsInternal({ return ( <> All of the following: - {schema.allOf.map((option, index) => ( + {asSchemaArray(schema.allOf).map((option, index) => ( ))} @@ -398,7 +406,7 @@ function ApiOperationRequestBodyDetailsInternal({ return ( <> Any of the following: - {schema.anyOf.map((option, index) => ( + {asSchemaArray(schema.anyOf).map((option, index) => ( ))} @@ -407,7 +415,7 @@ function ApiOperationRequestBodyDetailsInternal({ return ( <> One of the following: - {schema.oneOf.map((option, index) => ( + {asSchemaArray(schema.oneOf).map((option, index) => ( ))} @@ -431,10 +439,11 @@ function ApiOperationRequestBodyDetailsInternal({ return ( <> {`Array of ${displayName}`} - {!( - 'type' in schema.items && - ['string', 'boolean', 'number', 'integer'].includes(schema.items.type) - ) && } + {schema.items && + !( + 'type' in schema.items && + ['string', 'boolean', 'number', 'integer'].includes(schema.items.type) + ) && } ) } else if (schema.type === 'object') { @@ -469,13 +478,14 @@ export function ApiSchemaParamSubdetails({ (schema.type === 'string' && !('minLength' in schema || 'maxLength' in schema || 'pattern' in schema)) || (schema.type === 'array' && + schema.items && 'type' in schema.items && ['boolean', 'number', 'integer', 'string', 'file'].includes(schema.items.type))) ) { return null } - const subContent = + const rawSubContent = 'enum' in schema ? schema.enum : 'anyOf' in schema @@ -492,6 +502,7 @@ export function ApiSchemaParamSubdetails({ value: schema[key], })) : [] + const subContent = asSchemaArray(rawSubContent) return ( @@ -530,8 +541,24 @@ export function ApiSchemaParamSubdetails({ {'type' in schema && schema.type === 'object' ? ( -
- +
+
+ +
+ +
+ ) : 'type' in schema && + schema.type === 'array' && + 'items' in schema && + schema.items && + typeof schema.items === 'object' && + 'type' in schema.items && + schema.items.type === 'object' ? ( +
+
+ +
+
) : (
    From b9a4b3fa53abd1a5cc7825cc3d9457acaeaedfbc Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:01:47 -0700 Subject: [PATCH 2/4] feat: update mgmt api docs (#49128) This PR updates mgmt api docs automatically. Co-authored-by: samirketema <6003000+samirketema@users.noreply.github.com> --- apps/docs/spec/api_v1_openapi.json | 180 +- apps/docs/spec/api_v2_openapi.json | 1925 +++++++++-- apps/docs/spec/common-api-sections.json | 174 + .../transforms/api_v1_openapi_deparsed.json | 180 +- .../transforms/api_v2_openapi_deparsed.json | 2878 ++++++++++++++--- 5 files changed, 4383 insertions(+), 954 deletions(-) diff --git a/apps/docs/spec/api_v1_openapi.json b/apps/docs/spec/api_v1_openapi.json index 01b1a6ff1cfe4..f2e5cd59c0b51 100644 --- a/apps/docs/spec/api_v1_openapi.json +++ b/apps/docs/spec/api_v1_openapi.json @@ -468,7 +468,7 @@ "summary": "List all projects", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["projects_read"]], "x-oauth-scope": "projects:read" }, @@ -496,7 +496,7 @@ "summary": "Create a project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["organization_projects_create"]], "x-oauth-scope": "projects:write" } @@ -596,7 +596,7 @@ "summary": "List all organizations", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organizations_read"]], "x-oauth-scope": "organizations:read" }, @@ -628,7 +628,7 @@ "security": [{ "bearer": [] }], "summary": "Create an organization", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api", "billing"], + "x-endpoint-owners": ["control-plane", "billing"], "x-fga-permissions": [["organizations_create"]] } }, @@ -725,7 +725,7 @@ "responses": { "204": { "description": "" } }, "summary": "[Beta] Authorize user through oauth", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/token": { @@ -753,7 +753,7 @@ }, "summary": "[Beta] Exchange auth code for user's access and refresh token", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/revoke": { @@ -771,7 +771,7 @@ "responses": { "204": { "description": "" } }, "summary": "[Beta] Revoke oauth app authorization and it's corresponding tokens", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/authorize/project-claim": { @@ -853,7 +853,7 @@ "security": [{ "bearer": [] }], "summary": "Authorize user through oauth and claim a project", "tags": ["OAuth"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]] } }, @@ -910,7 +910,7 @@ "summary": "Lists SQL snippets for the logged in user", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["snippets_read"]], "x-oauth-scope": "database:read" } @@ -947,7 +947,7 @@ "summary": "Gets a specific SQL snippet", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["snippets_read"]], "x-oauth-scope": "database:read" } @@ -967,7 +967,7 @@ "security": [{ "bearer": [] }], "summary": "Gets the user's profile", "tags": ["Profile"], - "x-endpoint-owners": ["management-api"] + "x-endpoint-owners": ["control-plane"] } }, "/v1/projects/{ref}/actions": { @@ -1256,7 +1256,7 @@ "summary": "Get project api keys", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:read", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -1305,7 +1305,7 @@ "summary": "Creates a new API key for the project", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:write", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -1345,7 +1345,7 @@ "summary": "Check whether JWT based legacy (anon, service_role) API keys are enabled. This API endpoint will be removed in the future, check for HTTP 404 Not Found.", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:read", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -1390,7 +1390,7 @@ "summary": "Disable or re-enable JWT based legacy (anon, service_role) API keys. This API endpoint will be removed in the future, check for HTTP 404 Not Found.", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:write", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -1452,7 +1452,7 @@ "summary": "Updates an API key for the project", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:write", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" }, @@ -1506,7 +1506,7 @@ "summary": "Get API key", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:read", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -1573,7 +1573,7 @@ "summary": "Deletes an API key for the project", "tags": ["Secrets"], "x-badges": [{ "name": "OAuth scope: secrets:write", "position": "after" }], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -1773,7 +1773,7 @@ "summary": "[Beta] Gets project's custom hostname config", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:read", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_read"]], "x-oauth-scope": "domains:read" }, @@ -1812,7 +1812,7 @@ "summary": "[Beta] Deletes a project's custom hostname configuration", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -1861,7 +1861,7 @@ "summary": "[Beta] Updates project's custom hostname configuration", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -1902,7 +1902,7 @@ "summary": "[Beta] Attempts to verify the DNS configuration for project's custom hostname configuration", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -1943,7 +1943,7 @@ "summary": "[Beta] Activates a custom hostname for a project.", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -2013,7 +2013,7 @@ "summary": "[Beta] Get project's temporary access configuration.", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["security", "management-api"], + "x-endpoint-owners": ["security", "control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "database:read" }, @@ -2089,7 +2089,7 @@ "summary": "[Beta] Update project's temporary access configuration.", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["security", "management-api"], + "x-endpoint-owners": ["security", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "database:write" } @@ -2130,7 +2130,7 @@ "summary": "[Beta] Gets project's network bans", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_read"]], "x-oauth-scope": "projects:read" } @@ -2171,7 +2171,7 @@ "summary": "[Beta] Gets project's network bans with additional information about which databases they affect", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_read"]], "x-oauth-scope": "projects:read" } @@ -2213,7 +2213,7 @@ "summary": "[Beta] Remove network bans.", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_write"]], "x-oauth-scope": "projects:write" } @@ -2254,7 +2254,7 @@ "summary": "[Beta] Gets project's network restrictions", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_read"]], "x-oauth-scope": "projects:read" }, @@ -2301,7 +2301,7 @@ "summary": "[Alpha] Updates project's network restrictions by adding or removing CIDRs", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_write"]], "x-oauth-scope": "projects:write" } @@ -2350,7 +2350,7 @@ "summary": "[Beta] Updates project's network restrictions", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_write"]], "x-oauth-scope": "projects:write" } @@ -2479,7 +2479,7 @@ "summary": "Gets project's postgrest config", "tags": ["Rest"], "x-badges": [{ "name": "OAuth scope: rest:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["data_api_config_read"]], "x-oauth-scope": "rest:read" }, @@ -2526,7 +2526,7 @@ "summary": "Updates project's postgrest config", "tags": ["Rest"], "x-badges": [{ "name": "OAuth scope: rest:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["data_api_config_write"]], "x-oauth-scope": "rest:write" } @@ -2567,7 +2567,7 @@ "summary": "Gets a specific project that belongs to the authenticated user", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" }, @@ -2605,7 +2605,7 @@ "summary": "Deletes the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra", "dev-workflows"], + "x-endpoint-owners": ["control-plane", "infra", "dev-workflows"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" }, @@ -2650,7 +2650,7 @@ "summary": "Updates the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -2814,7 +2814,7 @@ "summary": "[Beta] Get project's SSL enforcement configuration.", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_ssl_config_read"]], "x-oauth-scope": "database:read" }, @@ -2861,7 +2861,7 @@ "summary": "[Beta] Update project's SSL enforcement configuration.", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_ssl_config_write"]], "x-oauth-scope": "database:write" } @@ -2960,7 +2960,7 @@ { "name": "OAuth scope: domains:read", "position": "after" }, { "name": "Only available on Pro, Team, Enterprise", "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_read"]], "x-oauth-scope": "domains:read" }, @@ -2992,7 +2992,7 @@ "summary": "[Beta] Deletes a project's vanity subdomain configuration", "tags": ["Domains"], "x-badges": [{ "name": "OAuth scope: domains:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -3049,7 +3049,7 @@ { "name": "OAuth scope: domains:write", "position": "after" }, { "name": "Only available on Pro, Team, Enterprise", "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -3106,7 +3106,7 @@ { "name": "OAuth scope: domains:write", "position": "after" }, { "name": "Only available on Pro, Team, Enterprise", "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -3153,7 +3153,7 @@ "summary": "[Beta] Upgrades the project's Postgres version", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write", "database_write"]], "x-oauth-scope": "projects:write" } @@ -3194,7 +3194,7 @@ "summary": "[Beta] Returns the project's eligibility for upgrades", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read", "database_read"]], "x-oauth-scope": "projects:read" } @@ -3241,7 +3241,7 @@ "summary": "[Beta] Gets the latest status of the project's upgrade", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read", "database_read"]], "x-oauth-scope": "projects:read" } @@ -3282,7 +3282,7 @@ "summary": "Returns project's readonly mode status", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra", "support-tooling"], + "x-endpoint-owners": ["control-plane", "infra", "support-tooling"], "x-fga-permissions": [["database_readonly_config_read"]], "x-oauth-scope": "database:read" } @@ -3316,7 +3316,7 @@ "summary": "Disables project's readonly mode for the next 15 minutes", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra", "support-tooling"], + "x-endpoint-owners": ["control-plane", "infra", "support-tooling"], "x-fga-permissions": [["database_readonly_config_write"]], "x-oauth-scope": "database:write" } @@ -3365,7 +3365,7 @@ "tags": ["Database"], "x-allowed-plans": ["Pro", "Team", "Enterprise"], "x-badges": [{ "name": "Only available on Pro, Team, Enterprise", "position": "before" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_read_replicas_write"]] } }, @@ -3405,7 +3405,7 @@ "security": [{ "bearer": [] }], "summary": "[Beta] Remove a read replica", "tags": ["Database"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_read_replicas_write"]] } }, @@ -3488,7 +3488,7 @@ "summary": "Gets project's service health status", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" } @@ -4111,7 +4111,7 @@ "summary": "Pauses the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -4144,7 +4144,7 @@ "summary": "Restarts the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -4186,7 +4186,7 @@ "summary": "Lists available restore versions for the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" }, @@ -4217,7 +4217,7 @@ "summary": "Restores the given project", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -4250,7 +4250,7 @@ "summary": "Cancels the given project restoration", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -4437,7 +4437,7 @@ "security": [{ "bearer": [] }], "summary": "Gets project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-internal": true }, @@ -4474,7 +4474,7 @@ "security": [{ "bearer": [] }], "summary": "Creates project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]], "x-internal": true }, @@ -4504,7 +4504,7 @@ "security": [{ "bearer": [] }], "summary": "Revokes project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]], "x-internal": true } @@ -4546,7 +4546,7 @@ "summary": "Gets project performance advisors.", "tags": ["Advisors"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["advisors_read"]], "x-oauth-scope": "database:read" } @@ -4594,7 +4594,7 @@ "summary": "Gets project security advisors.", "tags": ["Advisors"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["advisors_read"]], "x-oauth-scope": "database:read" } @@ -4602,7 +4602,7 @@ "/v1/projects/{ref}/analytics/endpoints/logs.all": { "get": { "deprecated": true, - "description": "Executes a SQL query on the project's logs.\n\nEither the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.\nIf both are not provided, only the last 1 minute of logs will be queried.\nThe timestamp range must be no more than 24 hours and is rounded to the nearest minute. If the range is more than 24 hours, a validation error will be thrown.\n\nNote: Unless the `sql` parameter is provided, only edge_logs will be queried. See the [log query docs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer:~:text=logs%20from%20the-,Sources,-drop%2Ddown%3A) for all available sources.\n", + "description": "Executes a SQL query on the project's logs.\n\nEither the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.\nIf both are not provided, only the last 1 minute of logs will be queried.\nThe timestamp range must be no more than 24 hours and is rounded to the nearest minute. If the range is more than 24 hours, a validation error will be thrown.\n\nNote: Unless the `sql` parameter is provided, only edge_logs will be queried. See the [log query docs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#logs-explorer) for all available sources.\n", "operationId": "v1-get-project-logs-all", "parameters": [ { @@ -4622,7 +4622,7 @@ "name": "sql", "required": false, "in": "query", - "description": "Custom SQL query to execute on the logs. See [querying logs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer) for more details.", + "description": "Custom SQL query to execute on the logs. See [querying logs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#querying-with-the-logs-explorer) for more details.", "schema": { "example": "select event_message from edge_logs limit 10", "type": "string" @@ -4695,7 +4695,7 @@ "name": "sql", "required": false, "in": "query", - "description": "Custom SQL query to execute on the logs. See [querying logs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer) for more details.", + "description": "Custom SQL query to execute on the logs. See [querying logs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#querying-with-the-logs-explorer) for more details.", "schema": { "example": "select event_message from edge_logs limit 10", "type": "string" @@ -4913,6 +4913,9 @@ "application/openmetrics-text": { "schema": { "type": "string" } } } }, + "400": { + "description": "Project must be active and healthy, or metrics are not available for this project" + }, "401": { "description": "Unauthorized" }, "403": { "description": "Forbidden action" }, "429": { "description": "Rate limit exceeded" }, @@ -5315,7 +5318,7 @@ "summary": "[Beta] Run sql query", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"], ["database_write"]], "x-oauth-scope": "database:write" } @@ -5356,7 +5359,7 @@ "summary": "[Beta] Run a sql query as supabase_read_only_user", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -5390,7 +5393,7 @@ "summary": "[Beta] Enables Database Webhooks on the project", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_webhooks_config_write"]], "x-oauth-scope": "database:write" } @@ -5432,7 +5435,7 @@ "summary": "Gets database metadata for the given project.", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "projects:read" } @@ -5481,7 +5484,7 @@ "summary": "Updates the database password", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_config_write"]], "x-oauth-scope": "database:write" } @@ -5874,7 +5877,7 @@ "summary": "Get PostgREST OpenAPI spec", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -6450,7 +6453,7 @@ "security": [{ "bearer": [] }], "summary": "Get database disk attributes", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] }, "post": { @@ -6486,7 +6489,7 @@ "security": [{ "bearer": [] }], "summary": "Modify database disk", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_write"]] } }, @@ -6525,7 +6528,7 @@ "security": [{ "bearer": [] }], "summary": "Get disk utilization", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] } }, @@ -6564,7 +6567,7 @@ "security": [{ "bearer": [] }], "summary": "Gets project disk autoscale config", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] } }, @@ -6680,7 +6683,7 @@ "summary": "Get project's pgbouncer config", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -6812,7 +6815,7 @@ "summary": "Gets project's Postgres config", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:read", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_config_read"]], "x-oauth-scope": "database:read" }, @@ -6859,7 +6862,7 @@ "summary": "Updates project's Postgres config", "tags": ["Database"], "x-badges": [{ "name": "OAuth scope: database:write", "position": "after" }], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_config_write"]], "x-oauth-scope": "database:write" } @@ -7658,7 +7661,7 @@ "summary": "List members of an organization", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["members_read"]], "x-oauth-scope": "organizations:read" } @@ -7696,7 +7699,7 @@ "summary": "Gets information about the organization", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_read"]], "x-oauth-scope": "organizations:read" } @@ -7739,7 +7742,7 @@ "security": [{ "bearer": [] }], "summary": "Gets project details for the specified organization and claim token", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]], "x-internal": true }, @@ -7773,7 +7776,7 @@ "security": [{ "bearer": [] }], "summary": "Claims project for the specified organization", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]], "x-internal": true } @@ -7865,7 +7868,7 @@ "summary": "Gets all projects for the given organization", "tags": ["Projects"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_projects_read"]], "x-oauth-scope": "projects:read" } @@ -13106,6 +13109,13 @@ "description": "Sets connection pool size for Realtime Authorization", "nullable": true }, + "postgres_changes_pool": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "Sets connection pool size used to create Postgres Changes subscriptions", + "nullable": true + }, "max_concurrent_users": { "type": "integer", "minimum": 1, @@ -13165,6 +13175,7 @@ "required": [ "private_only", "connection_pool", + "postgres_changes_pool", "max_concurrent_users", "max_events_per_second", "max_bytes_per_second", @@ -13189,6 +13200,12 @@ "maximum": 100, "description": "Sets connection pool size for Realtime Authorization" }, + "postgres_changes_pool": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "Sets connection pool size used to create Postgres Changes subscriptions" + }, "max_concurrent_users": { "type": "integer", "minimum": 1, @@ -13870,6 +13887,7 @@ "project_restore_after_expiry", "assistant.advance_model", "integrations.github_connections", + "integrations.github_push_webhooks_limit", "dedicated_pooler", "observability.dashboard_advanced_metrics", "api.members.invitations", diff --git a/apps/docs/spec/api_v2_openapi.json b/apps/docs/spec/api_v2_openapi.json index df7d06c60653f..89fa22760c982 100644 --- a/apps/docs/spec/api_v2_openapi.json +++ b/apps/docs/spec/api_v2_openapi.json @@ -28,10 +28,30 @@ } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to fetch log drains" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to fetch log drains", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "List project log drains", @@ -73,18 +93,36 @@ "application/json": { "schema": { "$ref": "#/components/schemas/LogDrainResponse" } } } }, - "401": { "description": "Unauthorized" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, "402": { "description": "This feature requires the Pro, Team, or Enterprise organization plan.", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PlanGateErrorBodyV2" } - } + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to create a log drain" } + "500": { + "description": "Failed to create a log drain", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Create a log drain for a project", @@ -143,10 +181,30 @@ "application/json": { "schema": { "$ref": "#/components/schemas/LogDrainResponse" } } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to update log drain" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to update log drain", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Update a project log drain", @@ -186,10 +244,30 @@ ], "responses": { "204": { "description": "" }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to delete a log drain" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to delete a log drain", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Delete a project log drain", @@ -200,6 +278,71 @@ "x-oauth-scope": "analytics_config:write" } }, + "/v2/projects/{ref}/config": { + "get": { + "description": "Returns the project's database, pooler, Auth, Data API, Realtime and Storage configuration — the same configuration a branch inherits from its base project. Each is the effective config, so a setting the project has never overridden is reported at its platform default rather than as null. Auth secrets are returned as an HMAC of their value. `storage` is read live from the storage service; the rest come from this platform's own records.", + "operationId": "v2-get-project-config", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/V2ProjectConfigResponse" } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] Get a project's service configuration", + "tags": ["Projects"], + "x-endpoint-owners": ["control-plane", "infra"], + "x-fga-permissions": [ + [ + "database_config_read", + "database_read", + "database_ssl_config_read", + "database_network_restrictions_read", + "auth_config_read", + "data_api_config_read", + "realtime_config_read", + "storage_config_read" + ] + ] + } + }, "/v2/projects/{ref}/transfers/previews": { "post": { "operationId": "v2-preview-a-project-transfer", @@ -235,14 +378,29 @@ } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Previews transferring a project to a different organizations, shows eligibility and impact", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]] } }, @@ -274,14 +432,29 @@ }, "responses": { "200": { "description": "" }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Transfers a project to a different organization", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]] } }, @@ -312,15 +485,35 @@ } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to retrieve AWS accounts for project" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to retrieve AWS accounts for project", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "List AWS accounts attached to the project PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_read"]] }, "post": { @@ -358,25 +551,43 @@ } } }, - "401": { "description": "Unauthorized" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, "402": { "description": "This feature requires the Team, or Enterprise organization plan.", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PlanGateErrorBodyV2" } - } + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to add AWS account to PrivateLink share" } + "500": { + "description": "Failed to add AWS account to PrivateLink share", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Add an AWS account to the project PrivateLink share", "tags": ["Projects"], "x-allowed-plans": ["Team", "Enterprise"], "x-badges": [{ "name": "Only available on Team, Enterprise", "position": "before" }], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, @@ -408,15 +619,35 @@ ], "responses": { "204": { "description": "" }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to remove AWS account from PrivateLink share" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to remove AWS account from PrivateLink share", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Remove an AWS account from the project PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, @@ -455,72 +686,55 @@ ], "responses": { "204": { "description": "" }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to remove AWS account from PrivateLink share" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "500": { + "description": "Failed to remove AWS account from PrivateLink share", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Remove an AWS account from a specific database PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, - "/v2/organizations/{slug}/members": { + "/v2/projects/{ref}/workers": { "get": { - "description": "Returns a cursor-paginated list of organization members including their roles and project-scoped permissions.", - "operationId": "v2-list-organization-members", + "description": "Returns all workers you've previously deployed to the specified project.", + "operationId": "v2-list-all-workers", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", "type": "string" } - }, - { - "name": "page", - "required": false, - "in": "query", - "schema": { - "properties": { - "size": { "type": "integer", "minimum": 1, "maximum": 100 }, - "after": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - }, - "before": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - } - }, - "type": "object" - }, - "style": "deepObject" - }, - { - "name": "filter", - "required": false, - "in": "query", - "schema": { - "properties": { - "username": { "type": "string" }, - "primary_email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - } - }, - "type": "object" - }, - "style": "deepObject" } ], "responses": { @@ -528,20 +742,387 @@ "description": "", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/V2ListMembersResponse" } + "schema": { "$ref": "#/components/schemas/V2ListWorkersResponse" } } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } - }, - "security": [{ "bearer": [] }], - "summary": "List members of an organization", - "tags": ["Organizations"], - "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["members_read"]], + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] List all workers", + "tags": ["Workers"], + "x-badges": [{ "name": "OAuth scope: edge_functions:read", "position": "after" }], + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_read"]], + "x-oauth-scope": "edge_functions:read" + } + }, + "/v2/projects/{ref}/workers/{name}": { + "get": { + "description": "Returns a worker along with its instance tally. Poll this after a deploy until `build_state` leaves `building`.", + "operationId": "v2-get-a-worker", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/V2WorkerResponse" } } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] Retrieve a worker", + "tags": ["Workers"], + "x-badges": [{ "name": "OAuth scope: edge_functions:read", "position": "after" }], + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_read"]], + "x-oauth-scope": "edge_functions:read" + }, + "delete": { + "description": "Tombstones the worker. Its instances and image are torn down asynchronously.", + "operationId": "v2-delete-a-worker", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", + "type": "string" + } + } + ], + "responses": { + "204": { "description": "" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] Delete a worker", + "tags": ["Workers"], + "x-badges": [{ "name": "OAuth scope: edge_functions:write", "position": "after" }], + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" + } + }, + "/v2/projects/{ref}/workers/{name}/uploads": { + "post": { + "description": "PUT the `.tar.gz` build context to the returned `url` before `expires_at`, then deploy with the upload id as `context_upload_id`. The bytes go straight to storage — no management API request carries them.", + "operationId": "v2-create-worker-upload", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/V2WorkerUploadResponse" } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] Mint a presigned slot for a build-context upload", + "tags": ["Workers"], + "x-badges": [{ "name": "OAuth scope: edge_functions:write", "position": "after" }], + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" + } + }, + "/v2/projects/{ref}/workers/{name}/deploy": { + "post": { + "description": "Creates the worker if it does not exist, building from a context staged through the uploads endpoint. The build runs asynchronously: this answers 202 and the worker reaches `build_state` `active` or `failed` later.", + "operationId": "v2-deploy-a-worker", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/V2DeployWorkerRequest" } + } + } + }, + "responses": { + "202": { + "description": "", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/V2WorkerResponse" } } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "[Alpha] Deploy a worker", + "tags": ["Workers"], + "x-badges": [{ "name": "OAuth scope: edge_functions:write", "position": "after" }], + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" + } + }, + "/v2/organizations/{slug}/members": { + "get": { + "description": "Returns a cursor-paginated list of organization members including their roles and project-scoped permissions.", + "operationId": "v2-list-organization-members", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "properties": { + "size": { "type": "integer", "minimum": 1, "maximum": 100 }, + "after": { + "type": "string", + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" + }, + "before": { + "type": "string", + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" + } + }, + "type": "object" + }, + "style": "deepObject" + }, + { + "name": "filter", + "required": false, + "in": "query", + "schema": { + "properties": { + "username": { "type": "string" }, + "primary_email": { + "type": "string", + "format": "email", + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + } + }, + "type": "object" + }, + "style": "deepObject" + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/V2ListMembersResponse" } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } + }, + "security": [{ "bearer": [] }], + "summary": "List members of an organization", + "tags": ["Organizations"], + "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["members_read"]], "x-oauth-scope": "organizations:read" } }, @@ -589,25 +1170,43 @@ } } }, - "401": { "description": "Unauthorized" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, "402": { "description": "This feature requires the Enterprise organization plan.", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PlanGateErrorBodyV2" } - } + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" }, - "500": { "description": "Failed to assign organization member role" } + "500": { + "description": "Failed to assign organization member role", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Assign or change an organization member role", "tags": ["Organizations"], "x-allowed-plans": ["Enterprise"], "x-badges": [{ "name": "Only available on Enterprise", "position": "before" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]] } }, @@ -637,15 +1236,30 @@ } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "List roles of an organization", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: organizations:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["members_read"]], "x-oauth-scope": "organizations:read" } @@ -684,17 +1298,30 @@ } } }, - "401": { "description": "Unauthorized" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, "402": { "description": "This feature requires the Enterprise organization plan.", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PlanGateErrorBodyV2" } - } + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Creates organization invitations", @@ -704,7 +1331,7 @@ { "name": "OAuth scope: organizations:write", "position": "after" }, { "name": "Only available on Enterprise", "position": "before" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["members_write"]], "x-oauth-scope": "organizations:write" }, @@ -741,17 +1368,30 @@ } } }, - "401": { "description": "Unauthorized" }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, "402": { "description": "This feature requires the Enterprise organization plan.", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PlanGateErrorBodyV2" } - } + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "Deletes organization invitations by email", @@ -761,7 +1401,7 @@ { "name": "OAuth scope: organizations:write", "position": "after" }, { "name": "Only available on Enterprise", "position": "before" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["members_write"]], "x-oauth-scope": "organizations:write" } @@ -819,20 +1459,35 @@ "200": { "description": "", "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/V2ListProjectsResponse" } - } + "application/json": { + "schema": { "$ref": "#/components/schemas/V2ListProjectsResponse" } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "List projects of an organization", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_projects_read"]], "x-oauth-scope": "projects:read" } @@ -910,22 +1565,37 @@ } } }, - "401": { "description": "Unauthorized" }, - "403": { "description": "Forbidden action" }, - "429": { "description": "Rate limit exceeded" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponseBody" } } + } + } }, "security": [{ "bearer": [] }], "summary": "List GitHub connections of an organization", "tags": ["Organizations"], "x-badges": [{ "name": "OAuth scope: projects:read", "position": "after" }], - "x-endpoint-owners": ["management-api", "dev-workflows"], + "x-endpoint-owners": ["control-plane", "dev-workflows"], "x-fga-permissions": [["organization_projects_read"]], "x-oauth-scope": "projects:read" } }, "/v2/projects/{ref}/webhooks/endpoints": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-get", "parameters": [ { "in": "path", @@ -1604,7 +2274,7 @@ "description": "List all Webhook endpoints based on a project's ref or an organization's slug." }, "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-post", "parameters": [ { "in": "path", @@ -2341,7 +3011,7 @@ } }, "delete": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-delete", "parameters": [ { "in": "path", @@ -2984,7 +3654,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-get", "parameters": [ { "in": "path", @@ -3693,7 +4363,7 @@ "description": "Get details of a specific endpoint." }, "patch": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-patch", "parameters": [ { "in": "path", @@ -4502,7 +5172,7 @@ } }, "delete": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-delete", "parameters": [ { "in": "path", @@ -5213,7 +5883,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}/deliveries": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-deliveries-get", "parameters": [ { "in": "path", @@ -5952,7 +6622,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}/test": { "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-test-post", "parameters": [ { "in": "path", @@ -6744,7 +7414,7 @@ }, "/v2/projects/{ref}/webhooks/deliveries/{id}": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-deliveries-id-get", "parameters": [ { "in": "path", @@ -7515,7 +8185,7 @@ }, "/v2/projects/{ref}/webhooks/deliveries/{id}/retry": { "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-deliveries-id-retry-post", "parameters": [ { "in": "path", @@ -8121,7 +8791,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-get", "parameters": [ { "in": "path", @@ -8798,7 +9468,7 @@ "description": "List all Webhook endpoints based on a project's ref or an organization's slug." }, "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-post", "parameters": [ { "in": "path", @@ -9533,7 +10203,7 @@ } }, "delete": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-delete", "parameters": [ { "in": "path", @@ -10174,7 +10844,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-get", "parameters": [ { "in": "path", @@ -10881,7 +11551,7 @@ "description": "Get details of a specific endpoint." }, "patch": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-patch", "parameters": [ { "in": "path", @@ -11688,7 +12358,7 @@ } }, "delete": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-delete", "parameters": [ { "in": "path", @@ -12397,7 +13067,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}/deliveries": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-deliveries-get", "parameters": [ { "in": "path", @@ -13134,7 +13804,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}/test": { "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-test-post", "parameters": [ { "in": "path", @@ -13924,7 +14594,7 @@ }, "/v2/organizations/{slug}/webhooks/deliveries/{id}": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-deliveries-id-get", "parameters": [ { "in": "path", @@ -14693,7 +15363,7 @@ }, "/v2/organizations/{slug}/webhooks/deliveries/{id}/retry": { "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-deliveries-id-retry-post", "parameters": [ { "in": "path", @@ -15447,6 +16117,44 @@ }, "required": ["data"] }, + "ErrorResponseBodyAPIErrorObject": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "code": { "type": "string" }, + "message": { "type": "string" }, + "description": { "type": "string" }, + "links": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "href": { "type": "string" }, + "rel": { "type": "string" }, + "title": { "type": "string" }, + "type": { "type": "string" }, + "describedby": { "type": "string" }, + "meta": { "type": "object", "additionalProperties": {} } + }, + "required": ["href"] + } + }, + "meta": { "type": "object", "additionalProperties": {} }, + "issues": { + "type": "array", + "items": { "$ref": "#/components/schemas/ErrorResponseBodyAPIErrorObject" } + } + }, + "required": ["code", "message"], + "ref": "APIErrorObject" + }, + "ErrorResponseBody": { + "type": "object", + "properties": { + "error": { "$ref": "#/components/schemas/ErrorResponseBodyAPIErrorObject" } + }, + "required": ["error"] + }, "CreateLogDrainRequestOpenApi": { "type": "object", "properties": { @@ -15712,27 +16420,6 @@ }, "required": ["data"] }, - "PlanGateErrorBodyV2": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "HTTP status-derived error code, e.g. \"payment_required\"" - }, - "message": { - "type": "string", - "description": "Human-readable explanation of the plan gate" - } - }, - "required": ["code", "message"], - "description": "Plan-gate error object" - } - }, - "required": ["error"] - }, "UpdateLogDrainRequestOpenApi": { "type": "object", "properties": { @@ -15760,107 +16447,538 @@ "additionalProperties": false, "title": "postgres" }, - { - "type": "object", - "properties": { - "url": { "type": "string" }, - "http": { "type": "string", "enum": ["http1", "http2"] }, - "gzip": { "type": "boolean" }, - "headers": { - "type": "object", - "additionalProperties": { "type": "string" } - } - }, - "additionalProperties": false, - "title": "webhook" + { + "type": "object", + "properties": { + "url": { "type": "string" }, + "http": { "type": "string", "enum": ["http1", "http2"] }, + "gzip": { "type": "boolean" }, + "headers": { + "type": "object", + "additionalProperties": { "type": "string" } + } + }, + "additionalProperties": false, + "title": "webhook" + }, + { + "type": "object", + "properties": { + "project_id": { "type": "string" }, + "dataset_id": { "type": "string" } + }, + "additionalProperties": false, + "title": "bigquery" + }, + { + "type": "object", + "properties": { + "api_key": { "type": "string" }, + "region": { "type": "string" } + }, + "additionalProperties": false, + "title": "datadog" + }, + { + "type": "object", + "properties": { + "url": { "type": "string" }, + "username": { "type": "string", "nullable": true }, + "password": { "type": "string", "nullable": true }, + "headers": { + "type": "object", + "additionalProperties": { "type": "string" } + } + }, + "additionalProperties": false, + "title": "loki" + }, + { + "type": "object", + "properties": { "dsn": { "type": "string" } }, + "additionalProperties": false, + "title": "sentry" + }, + { + "type": "object", + "properties": { + "domain": { "type": "string" }, + "api_token": { "type": "string" }, + "dataset_name": { "type": "string" } + }, + "additionalProperties": false, + "title": "axiom" + }, + { + "type": "object", + "properties": { + "host": { "type": "string" }, + "port": { "type": "integer", "minimum": 0, "maximum": 65535 }, + "tls": { "default": false, "type": "boolean" }, + "structured_data": { "type": "string" }, + "cipher_key": { "type": "string" }, + "ca_cert": { "type": "string" }, + "client_cert": { "type": "string" }, + "client_key": { "type": "string" } + }, + "additionalProperties": false, + "title": "syslog" + } + ] + }, + "backend_type": { + "type": "string", + "enum": [ + "postgres", + "bigquery", + "clickhouse", + "webhook", + "datadog", + "loki", + "sentry", + "s3", + "axiom", + "last9", + "otlp", + "syslog" + ] + } + }, + "required": ["backend_type"] + } + }, + "required": ["type", "attributes"] + } + }, + "required": ["data"] + }, + "V2ProjectConfigResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_config"] + }, + "id": { "type": "string", "description": "Project ref." }, + "attributes": { + "type": "object", + "properties": { + "database": { + "type": "object", + "properties": { + "major_version": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "The major Postgres version the database runs. `17` covers both Postgres 17 and Oriole on 17, since Oriole is a storage engine rather than a version." + }, + "ssl_enforced": { + "type": "boolean", + "description": "Whether the database rejects plaintext connections" + }, + "network_restrictions": { + "type": "object", + "properties": { + "entitlement": { "type": "string", "enum": ["disallowed", "allowed"] }, + "status": { + "type": "string", + "enum": ["stored", "applied"], + "description": "Whether the allowlist below is applied to the project or only stored." + }, + "allowed_cidrs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "address": { "type": "string" }, + "type": { "type": "string", "enum": ["v4", "v6"] } + }, + "required": ["address", "type"] + } + }, + "updated_at": { "type": "string" }, + "applied_at": { "type": "string" } + }, + "required": ["entitlement", "status", "allowed_cidrs"] + }, + "postgres_settings": { + "type": "object", + "properties": { + "effective_cache_size": { "type": "string" }, + "logical_decoding_work_mem": { "type": "string" }, + "log_autovacuum_min_duration": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "log_checkpoints": { "type": "boolean" }, + "log_connections": { "type": "boolean" }, + "log_disconnections": { "type": "boolean" }, + "log_duration": { "type": "boolean" }, + "log_lock_waits": { "type": "boolean" }, + "log_recovery_conflict_waits": { "type": "boolean" }, + "log_replication_commands": { "type": "boolean" }, + "log_startup_progress_interval": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "log_temp_files": { "type": "string" }, + "maintenance_work_mem": { "type": "string" }, + "track_activity_query_size": { "type": "string" }, + "max_connections": { "type": "integer", "minimum": 1, "maximum": 262143 }, + "max_locks_per_transaction": { + "type": "integer", + "minimum": 10, + "maximum": 2147483640 + }, + "max_logical_replication_workers": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "max_parallel_maintenance_workers": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_parallel_workers": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_parallel_workers_per_gather": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_replication_slots": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_slot_wal_keep_size": { "type": "string" }, + "max_standby_archive_delay": { "type": "string" }, + "max_standby_streaming_delay": { "type": "string" }, + "max_sync_workers_per_subscription": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "max_wal_size": { "type": "string" }, + "max_wal_senders": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_worker_processes": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "session_replication_role": { + "type": "string", + "enum": ["origin", "replica", "local"] + }, + "shared_buffers": { "type": "string" }, + "statement_timeout": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "track_commit_timestamp": { "type": "boolean" }, + "wal_keep_size": { "type": "string" }, + "wal_sender_timeout": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "work_mem": { "type": "string" }, + "checkpoint_timeout": { + "type": "string", + "description": "Default unit: s", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "hot_standby_feedback": { "type": "boolean" }, + "cron_log_statement": { "type": "boolean" } + }, + "description": "Postgres parameter overrides. Empty when the project runs entirely on defaults." + } + }, + "required": [ + "major_version", + "ssl_enforced", + "network_restrictions", + "postgres_settings" + ] + }, + "pooler": { + "type": "object", + "properties": { + "pool_mode": { + "type": "string", + "enum": ["transaction", "session", "statement"] + }, + "ignore_startup_parameters": { "type": "string" }, + "server_idle_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "server_lifetime": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "query_wait_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "reserve_pool_size": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "default_pool_size": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to the pooler's size for the project's compute when not overridden." + }, + "max_client_conn": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to the pooler's size for the project's compute when not overridden." + } + }, + "required": [ + "pool_mode", + "ignore_startup_parameters", + "server_idle_timeout", + "server_lifetime", + "query_wait_timeout", + "reserve_pool_size", + "default_pool_size", + "max_client_conn" + ] + }, + "auth": { + "type": "object", + "additionalProperties": {}, + "description": "Effective Auth config, keyed by lowercased GoTrue setting name and resolved through the `gotrue_config` view, so a setting the project has never overridden is reported at its platform default. Secrets are returned as an HMAC of their value, never in plaintext." + }, + "api": { + "type": "object", + "properties": { + "db_schema": { + "type": "string", + "description": "Schemas exposed through the Data API" + }, + "db_extra_search_path": { "type": "string" }, + "max_rows": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "db_pool_acquisition_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "db_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "If `null`, no pool size is written to the project's PostgREST config and PostgREST's own default applies. The platform does not pick a value here.", + "nullable": true + } + }, + "required": [ + "db_schema", + "db_extra_search_path", + "max_rows", + "db_pool_acquisition_timeout", + "db_pool" + ] + }, + "realtime": { + "type": "object", + "properties": { + "private_only": { "type": "boolean" }, + "max_concurrent_users": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_events_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - { - "type": "object", - "properties": { - "project_id": { "type": "string" }, - "dataset_id": { "type": "string" } - }, - "additionalProperties": false, - "title": "bigquery" + "max_bytes_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - { - "type": "object", - "properties": { - "api_key": { "type": "string" }, - "region": { "type": "string" } - }, - "additionalProperties": false, - "title": "datadog" + "max_channels_per_client": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - { + "max_joins_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_presence_events_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_payload_size_in_kb": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "presence_enabled": { "type": "boolean" }, + "suspend": { "type": "boolean" }, + "connection_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to Realtime's pool size for the project's compute when not overridden." + }, + "postgres_changes_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "If `null`, no override is stored and Realtime applies its own default.", + "nullable": true + } + }, + "required": [ + "private_only", + "max_concurrent_users", + "max_events_per_second", + "max_bytes_per_second", + "max_channels_per_client", + "max_joins_per_second", + "max_presence_events_per_second", + "max_payload_size_in_kb", + "presence_enabled", + "suspend", + "connection_pool", + "postgres_changes_pool" + ] + }, + "storage": { + "type": "object", + "properties": { + "file_size_limit": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "format": "int64" + }, + "features": { "type": "object", "properties": { - "url": { "type": "string" }, - "username": { "type": "string", "nullable": true }, - "password": { "type": "string", "nullable": true }, - "headers": { + "image_transformation": { "type": "object", - "additionalProperties": { "type": "string" } + "properties": { "enabled": { "type": "boolean" } }, + "required": ["enabled"] + }, + "s3_protocol": { + "type": "object", + "properties": { "enabled": { "type": "boolean" } }, + "required": ["enabled"] + }, + "purge_cache": { + "type": "object", + "properties": { "enabled": { "type": "boolean" } }, + "required": ["enabled"] + }, + "iceberg_catalog": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "max_namespaces": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_tables": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_catalogs": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["enabled", "max_namespaces", "max_tables", "max_catalogs"] + }, + "vector_buckets": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "max_buckets": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_indexes": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["enabled", "max_buckets", "max_indexes"] } }, - "additionalProperties": false, - "title": "loki" - }, - { - "type": "object", - "properties": { "dsn": { "type": "string" } }, - "additionalProperties": false, - "title": "sentry" + "required": [ + "image_transformation", + "s3_protocol", + "purge_cache", + "iceberg_catalog", + "vector_buckets" + ] }, - { + "capabilities": { "type": "object", "properties": { - "domain": { "type": "string" }, - "api_token": { "type": "string" }, - "dataset_name": { "type": "string" } + "list_v2": { "type": "boolean" }, + "iceberg_catalog": { "type": "boolean" } }, - "additionalProperties": false, - "title": "axiom" + "required": ["list_v2", "iceberg_catalog"] }, - { - "type": "object", - "properties": { - "host": { "type": "string" }, - "port": { "type": "integer", "minimum": 0, "maximum": 65535 }, - "tls": { "default": false, "type": "boolean" }, - "structured_data": { "type": "string" }, - "cipher_key": { "type": "string" }, - "ca_cert": { "type": "string" }, - "client_cert": { "type": "string" }, - "client_key": { "type": "string" } - }, - "additionalProperties": false, - "title": "syslog" - } - ] - }, - "backend_type": { - "type": "string", - "enum": [ - "postgres", - "bigquery", - "clickhouse", - "webhook", - "datadog", - "loki", - "sentry", - "s3", - "axiom", - "last9", - "otlp", - "syslog" - ] + "upstream_target": { "type": "string", "enum": ["main", "canary"] }, + "migration_version": { "type": "string" }, + "database_pool_mode": { "type": "string" } + }, + "required": [ + "file_size_limit", + "features", + "capabilities", + "upstream_target", + "migration_version", + "database_pool_mode" + ], + "description": "Read from the storage service's admin API rather than the middleware DB, so unlike the rest of this resource it reflects the tenant's live config." } }, - "required": ["backend_type"] + "required": ["database", "pooler", "auth", "api", "realtime", "storage"] } }, - "required": ["type", "attributes"] + "required": ["type", "id", "attributes"] } }, "required": ["data"] @@ -15999,6 +17117,18 @@ "database_identifier": { "type": "string", "description": "Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier." + }, + "resource_access_manager_resource_config_id": { + "description": "ID of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_resource_config_arn": { + "description": "ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_share_arn": { + "description": "ARN of the AWS Resource Access Manager resource share for this association.", + "type": "string" } }, "required": [ @@ -16108,6 +17238,18 @@ "database_identifier": { "type": "string", "description": "Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier." + }, + "resource_access_manager_resource_config_id": { + "description": "ID of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_resource_config_arn": { + "description": "ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_share_arn": { + "description": "ARN of the AWS Resource Access Manager resource share for this association.", + "type": "string" } }, "required": [ @@ -16124,6 +17266,230 @@ }, "required": ["data"] }, + "V2ListWorkersResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "id": { "type": "string", "description": "Worker name.", "example": "hello-world" }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { "example": "node", "type": "string" }, + "size": { "type": "string", "example": "2gb-1vcpu" }, + "exposure": { "type": "string", "example": "public" }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "build_state": { "type": "string", "enum": ["building", "active", "failed"] }, + "secret_generation": { "type": "string" }, + "state_reason": { "type": "string" }, + "image_version": { "type": "string" }, + "deleting": { "type": "boolean" }, + "instances": { + "type": "object", + "properties": { + "declared": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "live": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "ready": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "stale": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["declared", "live", "ready", "stale"] + }, + "instances_error": { "type": "string" } + }, + "required": ["spec", "build_state", "secret_generation"] + } + }, + "required": ["type", "id", "attributes"] + } + } + }, + "required": ["data"] + }, + "V2WorkerResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "id": { "type": "string", "description": "Worker name.", "example": "hello-world" }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { "example": "node", "type": "string" }, + "size": { "type": "string", "example": "2gb-1vcpu" }, + "exposure": { "type": "string", "example": "public" }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "build_state": { "type": "string", "enum": ["building", "active", "failed"] }, + "secret_generation": { "type": "string" }, + "state_reason": { "type": "string" }, + "image_version": { "type": "string" }, + "deleting": { "type": "boolean" }, + "instances": { + "type": "object", + "properties": { + "declared": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "live": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "ready": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "stale": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["declared", "live", "ready", "stale"] + }, + "instances_error": { "type": "string" } + }, + "required": ["spec", "build_state", "secret_generation"] + } + }, + "required": ["type", "id", "attributes"] + } + }, + "required": ["data"] + }, + "V2WorkerUploadResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker_upload"] + }, + "id": { + "type": "string", + "description": "Upload id to pass to the deploy endpoint as `context_upload_id`.", + "example": "cafe0000000000000000000000000000" + }, + "attributes": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "Presigned destination for the `.tar.gz` build context." + }, + "method": { "type": "string", "example": "PUT" }, + "expires_at": { + "type": "string", + "description": "When the slot stops accepting the upload." + } + }, + "required": ["url", "method", "expires_at"] + } + }, + "required": ["type", "id", "attributes"] + } + }, + "required": ["data"] + }, + "V2DeployWorkerRequest": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { "example": "node", "type": "string" }, + "size": { "type": "string", "example": "2gb-1vcpu" }, + "exposure": { "type": "string", "example": "public" }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "context_upload_id": { + "description": "Id of a build context staged through the uploads endpoint. Required unless `runtime` is set.", + "type": "string" + } + }, + "required": ["spec"] + } + }, + "required": ["type", "attributes"] + } + }, + "required": ["data"] + }, "V2ListMembersResponse": { "type": "object", "properties": { @@ -16386,7 +17752,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" }, "role": { "type": "string", @@ -16396,6 +17764,7 @@ }, "projects": { "description": "The projects to limit a user to. If omitted, user will have org-wide access with the provided role.", + "examples": [{ "ref": "abcjuqabhgwjjutfvtpa" }], "minItems": 1, "type": "array", "items": { @@ -16477,7 +17846,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -16505,7 +17876,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -16538,7 +17911,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -16569,7 +17944,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] diff --git a/apps/docs/spec/common-api-sections.json b/apps/docs/spec/common-api-sections.json index 9421f19a16b03..8fbecc4a95c6b 100644 --- a/apps/docs/spec/common-api-sections.json +++ b/apps/docs/spec/common-api-sections.json @@ -732,6 +732,72 @@ } ] }, + { + "type": "category", + "title": "Organization webhooks", + "items": [ + { + "id": "v2-organizations-slug-webhooks-deliveries-id-get", + "title": "Organizations slug webhooks deliveries id get", + "slug": "v2-organizations-slug-webhooks-deliveries-id-get", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-deliveries-id-retry-post", + "title": "Organizations slug webhooks deliveries id retry post", + "slug": "v2-organizations-slug-webhooks-deliveries-id-retry-post", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-delete", + "title": "Organizations slug webhooks endpoints delete", + "slug": "v2-organizations-slug-webhooks-endpoints-delete", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-get", + "title": "Organizations slug webhooks endpoints get", + "slug": "v2-organizations-slug-webhooks-endpoints-get", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-id-delete", + "title": "Organizations slug webhooks endpoints id delete", + "slug": "v2-organizations-slug-webhooks-endpoints-id-delete", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-id-deliveries-get", + "title": "Organizations slug webhooks endpoints id deliveries get", + "slug": "v2-organizations-slug-webhooks-endpoints-id-deliveries-get", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-id-get", + "title": "Organizations slug webhooks endpoints id get", + "slug": "v2-organizations-slug-webhooks-endpoints-id-get", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-id-patch", + "title": "Organizations slug webhooks endpoints id patch", + "slug": "v2-organizations-slug-webhooks-endpoints-id-patch", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-id-test-post", + "title": "Organizations slug webhooks endpoints id test post", + "slug": "v2-organizations-slug-webhooks-endpoints-id-test-post", + "type": "operation" + }, + { + "id": "v2-organizations-slug-webhooks-endpoints-post", + "title": "Organizations slug webhooks endpoints post", + "slug": "v2-organizations-slug-webhooks-endpoints-post", + "type": "operation" + } + ] + }, { "type": "category", "title": "Organizations", @@ -828,6 +894,72 @@ } ] }, + { + "type": "category", + "title": "Project webhooks", + "items": [ + { + "id": "v2-projects-ref-webhooks-deliveries-id-get", + "title": "Projects ref webhooks deliveries id get", + "slug": "v2-projects-ref-webhooks-deliveries-id-get", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-deliveries-id-retry-post", + "title": "Projects ref webhooks deliveries id retry post", + "slug": "v2-projects-ref-webhooks-deliveries-id-retry-post", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-delete", + "title": "Projects ref webhooks endpoints delete", + "slug": "v2-projects-ref-webhooks-endpoints-delete", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-get", + "title": "Projects ref webhooks endpoints get", + "slug": "v2-projects-ref-webhooks-endpoints-get", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-id-delete", + "title": "Projects ref webhooks endpoints id delete", + "slug": "v2-projects-ref-webhooks-endpoints-id-delete", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-id-deliveries-get", + "title": "Projects ref webhooks endpoints id deliveries get", + "slug": "v2-projects-ref-webhooks-endpoints-id-deliveries-get", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-id-get", + "title": "Projects ref webhooks endpoints id get", + "slug": "v2-projects-ref-webhooks-endpoints-id-get", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-id-patch", + "title": "Projects ref webhooks endpoints id patch", + "slug": "v2-projects-ref-webhooks-endpoints-id-patch", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-id-test-post", + "title": "Projects ref webhooks endpoints id test post", + "slug": "v2-projects-ref-webhooks-endpoints-id-test-post", + "type": "operation" + }, + { + "id": "v2-projects-ref-webhooks-endpoints-post", + "title": "Projects ref webhooks endpoints post", + "slug": "v2-projects-ref-webhooks-endpoints-post", + "type": "operation" + } + ] + }, { "type": "category", "title": "Projects", @@ -922,6 +1054,12 @@ "slug": "v1-get-project", "type": "operation" }, + { + "id": "v2-get-project-config", + "title": "Get project config", + "slug": "v2-get-project-config", + "type": "operation" + }, { "id": "v1-get-project-disk-autoscale-config", "title": "Get project disk autoscale config", @@ -1169,5 +1307,41 @@ "type": "operation" } ] + }, + { + "type": "category", + "title": "Workers", + "items": [ + { + "id": "v2-create-worker-upload", + "title": "Create worker upload", + "slug": "v2-create-worker-upload", + "type": "operation" + }, + { + "id": "v2-delete-a-worker", + "title": "Delete a worker", + "slug": "v2-delete-a-worker", + "type": "operation" + }, + { + "id": "v2-deploy-a-worker", + "title": "Deploy a worker", + "slug": "v2-deploy-a-worker", + "type": "operation" + }, + { + "id": "v2-get-a-worker", + "title": "Get a worker", + "slug": "v2-get-a-worker", + "type": "operation" + }, + { + "id": "v2-list-all-workers", + "title": "List all workers", + "slug": "v2-list-all-workers", + "type": "operation" + } + ] } ] diff --git a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json index 15a255feb5454..831388c88cf9e 100644 --- a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json +++ b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json @@ -685,7 +685,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["projects_read"]], "x-oauth-scope": "projects:read" }, @@ -736,7 +736,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["organization_projects_create"]], "x-oauth-scope": "projects:write" } @@ -871,7 +871,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organizations_read"]], "x-oauth-scope": "organizations:read" }, @@ -919,7 +919,7 @@ ], "summary": "Create an organization", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api", "billing"], + "x-endpoint-owners": ["control-plane", "billing"], "x-fga-permissions": [["organizations_create"]] } }, @@ -1041,7 +1041,7 @@ }, "summary": "[Beta] Authorize user through oauth", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/token": { @@ -1073,7 +1073,7 @@ }, "summary": "[Beta] Exchange auth code for user's access and refresh token", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/revoke": { @@ -1097,7 +1097,7 @@ }, "summary": "[Beta] Revoke oauth app authorization and it's corresponding tokens", "tags": ["OAuth"], - "x-endpoint-owners": ["auth", "management-api"] + "x-endpoint-owners": ["auth", "control-plane"] } }, "/v1/oauth/authorize/project-claim": { @@ -1207,7 +1207,7 @@ ], "summary": "Authorize user through oauth and claim a project", "tags": ["OAuth"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]] } }, @@ -1302,7 +1302,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["snippets_read"]], "x-oauth-scope": "database:read" } @@ -1360,7 +1360,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["snippets_read"]], "x-oauth-scope": "database:read" } @@ -1388,7 +1388,7 @@ ], "summary": "Gets the user's profile", "tags": ["Profile"], - "x-endpoint-owners": ["management-api"] + "x-endpoint-owners": ["control-plane"] } }, "/v1/projects/{ref}/actions": { @@ -1821,7 +1821,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -1896,7 +1896,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -1953,7 +1953,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -2018,7 +2018,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -2106,7 +2106,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" }, @@ -2182,7 +2182,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_read"]], "x-oauth-scope": "secrets:read" }, @@ -2277,7 +2277,7 @@ "position": "after" } ], - "x-endpoint-owners": ["auth", "management-api"], + "x-endpoint-owners": ["auth", "control-plane"], "x-fga-permissions": [["api_gateway_keys_write"]], "x-oauth-scope": "secrets:write" } @@ -2565,7 +2565,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_read"]], "x-oauth-scope": "domains:read" }, @@ -2625,7 +2625,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -2695,7 +2695,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -2755,7 +2755,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -2815,7 +2815,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["custom_domain_write"]], "x-oauth-scope": "domains:write" } @@ -2910,7 +2910,7 @@ "position": "after" } ], - "x-endpoint-owners": ["security", "management-api"], + "x-endpoint-owners": ["security", "control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "database:read" }, @@ -3013,7 +3013,7 @@ "position": "after" } ], - "x-endpoint-owners": ["security", "management-api"], + "x-endpoint-owners": ["security", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "database:write" } @@ -3073,7 +3073,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_read"]], "x-oauth-scope": "projects:read" } @@ -3133,7 +3133,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_read"]], "x-oauth-scope": "projects:read" } @@ -3196,7 +3196,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_network_bans_write"]], "x-oauth-scope": "projects:write" } @@ -3256,7 +3256,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_read"]], "x-oauth-scope": "projects:read" }, @@ -3324,7 +3324,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_write"]], "x-oauth-scope": "projects:write" } @@ -3394,7 +3394,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_network_restrictions_write"]], "x-oauth-scope": "projects:write" } @@ -3582,7 +3582,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["data_api_config_read"]], "x-oauth-scope": "rest:read" }, @@ -3650,7 +3650,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["data_api_config_write"]], "x-oauth-scope": "rest:write" } @@ -3710,7 +3710,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" }, @@ -3765,7 +3765,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra", "dev-workflows"], + "x-endpoint-owners": ["control-plane", "infra", "dev-workflows"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" }, @@ -3833,7 +3833,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -4081,7 +4081,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_ssl_config_read"]], "x-oauth-scope": "database:read" }, @@ -4149,7 +4149,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_ssl_config_write"]], "x-oauth-scope": "database:write" } @@ -4295,7 +4295,7 @@ "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_read"]], "x-oauth-scope": "domains:read" }, @@ -4346,7 +4346,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -4431,7 +4431,7 @@ "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -4516,7 +4516,7 @@ "position": "before" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["vanity_subdomain_write"]], "x-oauth-scope": "domains:write" } @@ -4586,7 +4586,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write", "database_write"]], "x-oauth-scope": "projects:write" } @@ -4646,7 +4646,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read", "database_read"]], "x-oauth-scope": "projects:read" } @@ -4715,7 +4715,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read", "database_read"]], "x-oauth-scope": "projects:read" } @@ -4775,7 +4775,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra", "support-tooling"], + "x-endpoint-owners": ["control-plane", "infra", "support-tooling"], "x-fga-permissions": [["database_readonly_config_read"]], "x-oauth-scope": "database:read" } @@ -4828,7 +4828,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra", "support-tooling"], + "x-endpoint-owners": ["control-plane", "infra", "support-tooling"], "x-fga-permissions": [["database_readonly_config_write"]], "x-oauth-scope": "database:write" } @@ -4902,7 +4902,7 @@ "position": "before" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_read_replicas_write"]] } }, @@ -4958,7 +4958,7 @@ ], "summary": "[Beta] Remove a read replica", "tags": ["Database"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_read_replicas_write"]] } }, @@ -5065,7 +5065,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" } @@ -5939,7 +5939,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -5989,7 +5989,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -6046,7 +6046,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_read"]], "x-oauth-scope": "projects:read" }, @@ -6094,7 +6094,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -6144,7 +6144,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["project_admin_write"]], "x-oauth-scope": "projects:write" } @@ -6396,7 +6396,7 @@ ], "summary": "Gets project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]], "x-internal": true }, @@ -6445,7 +6445,7 @@ ], "summary": "Creates project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]], "x-internal": true }, @@ -6487,7 +6487,7 @@ ], "summary": "Revokes project claim token", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write", "project_admin_write"]], "x-internal": true } @@ -6546,7 +6546,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["advisors_read"]], "x-oauth-scope": "database:read" } @@ -6615,7 +6615,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["advisors_read"]], "x-oauth-scope": "database:read" } @@ -6623,7 +6623,7 @@ "/v1/projects/{ref}/analytics/endpoints/logs.all": { "get": { "deprecated": true, - "description": "Executes a SQL query on the project's logs.\n\nEither the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.\nIf both are not provided, only the last 1 minute of logs will be queried.\nThe timestamp range must be no more than 24 hours and is rounded to the nearest minute. If the range is more than 24 hours, a validation error will be thrown.\n\nNote: Unless the `sql` parameter is provided, only edge_logs will be queried. See the [log query docs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer:~:text=logs%20from%20the-,Sources,-drop%2Ddown%3A) for all available sources.\n", + "description": "Executes a SQL query on the project's logs.\n\nEither the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.\nIf both are not provided, only the last 1 minute of logs will be queried.\nThe timestamp range must be no more than 24 hours and is rounded to the nearest minute. If the range is more than 24 hours, a validation error will be thrown.\n\nNote: Unless the `sql` parameter is provided, only edge_logs will be queried. See the [log query docs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#logs-explorer) for all available sources.\n", "operationId": "v1-get-project-logs-all", "parameters": [ { @@ -6643,7 +6643,7 @@ "name": "sql", "required": false, "in": "query", - "description": "Custom SQL query to execute on the logs. See [querying logs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer) for more details.", + "description": "Custom SQL query to execute on the logs. See [querying logs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#querying-with-the-logs-explorer) for more details.", "schema": { "example": "select event_message from edge_logs limit 10", "type": "string" @@ -6737,7 +6737,7 @@ "name": "sql", "required": false, "in": "query", - "description": "Custom SQL query to execute on the logs. See [querying logs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer) for more details.", + "description": "Custom SQL query to execute on the logs. See [querying logs](https://supabase.com/docs/guides/monitoring-and-debugging/logs#querying-with-the-logs-explorer) for more details.", "schema": { "example": "select event_message from edge_logs limit 10", "type": "string" @@ -7031,6 +7031,9 @@ } } }, + "400": { + "description": "Project must be active and healthy, or metrics are not available for this project" + }, "401": { "description": "Unauthorized" }, @@ -7651,7 +7654,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"], ["database_write"]], "x-oauth-scope": "database:write" } @@ -7715,7 +7718,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -7768,7 +7771,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_webhooks_config_write"]], "x-oauth-scope": "database:write" } @@ -7827,7 +7830,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "projects:read" } @@ -7897,7 +7900,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["database_config_write"]], "x-oauth-scope": "database:write" } @@ -8448,7 +8451,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -9294,7 +9297,7 @@ ], "summary": "Get database disk attributes", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] }, "post": { @@ -9348,7 +9351,7 @@ ], "summary": "Modify database disk", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_write"]] } }, @@ -9401,7 +9404,7 @@ ], "summary": "Get disk utilization", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] } }, @@ -9454,7 +9457,7 @@ ], "summary": "Gets project disk autoscale config", "tags": ["Projects"], - "x-endpoint-owners": ["management-api", "infra"], + "x-endpoint-owners": ["control-plane", "infra"], "x-fga-permissions": [["infra_disk_config_read"]] } }, @@ -9615,7 +9618,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_read"]], "x-oauth-scope": "database:read" } @@ -9806,7 +9809,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_config_read"]], "x-oauth-scope": "database:read" }, @@ -9874,7 +9877,7 @@ "position": "after" } ], - "x-endpoint-owners": ["infra", "management-api"], + "x-endpoint-owners": ["infra", "control-plane"], "x-fga-permissions": [["database_config_write"]], "x-oauth-scope": "database:write" } @@ -11019,7 +11022,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["members_read"]], "x-oauth-scope": "organizations:read" } @@ -11074,7 +11077,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_read"]], "x-oauth-scope": "organizations:read" } @@ -11132,7 +11135,7 @@ ], "summary": "Gets project details for the specified organization and claim token", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]], "x-internal": true }, @@ -11181,7 +11184,7 @@ ], "summary": "Claims project for the specified organization", "tags": ["Organizations"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]], "x-internal": true } @@ -11298,7 +11301,7 @@ "position": "after" } ], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_projects_read"]], "x-oauth-scope": "projects:read" } @@ -19487,6 +19490,13 @@ "description": "Sets connection pool size for Realtime Authorization", "nullable": true }, + "postgres_changes_pool": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "Sets connection pool size used to create Postgres Changes subscriptions", + "nullable": true + }, "max_concurrent_users": { "type": "integer", "minimum": 1, @@ -19549,6 +19559,7 @@ "required": [ "private_only", "connection_pool", + "postgres_changes_pool", "max_concurrent_users", "max_events_per_second", "max_bytes_per_second", @@ -19573,6 +19584,12 @@ "maximum": 100, "description": "Sets connection pool size for Realtime Authorization" }, + "postgres_changes_pool": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "Sets connection pool size used to create Postgres Changes subscriptions" + }, "max_concurrent_users": { "type": "integer", "minimum": 1, @@ -20536,6 +20553,7 @@ "project_restore_after_expiry", "assistant.advance_model", "integrations.github_connections", + "integrations.github_push_webhooks_limit", "dedicated_pooler", "observability.dashboard_advanced_metrics", "api.members.invitations", diff --git a/apps/docs/spec/transforms/api_v2_openapi_deparsed.json b/apps/docs/spec/transforms/api_v2_openapi_deparsed.json index c99d176c4b00c..6a476ef664c6c 100644 --- a/apps/docs/spec/transforms/api_v2_openapi_deparsed.json +++ b/apps/docs/spec/transforms/api_v2_openapi_deparsed.json @@ -39,16 +39,44 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to fetch log drains" + "description": "Failed to fetch log drains", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -107,26 +135,54 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "402": { "description": "This feature requires the Pro, Team, or Enterprise organization plan.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanGateErrorBodyV2" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to create a log drain" + "description": "Failed to create a log drain", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -203,16 +259,44 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to update log drain" + "description": "Failed to update log drain", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -265,16 +349,44 @@ "description": "" }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to delete a log drain" + "description": "Failed to delete a log drain", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -295,6 +407,89 @@ "x-oauth-scope": "analytics_config:write" } }, + "/v2/projects/{ref}/config": { + "get": { + "description": "Returns the project's database, pooler, Auth, Data API, Realtime and Storage configuration — the same configuration a branch inherits from its base project. Each is the effective config, so a setting the project has never overridden is reported at its platform default rather than as null. Auth secrets are returned as an HMAC of their value. `storage` is read live from the storage service; the rest come from this platform's own records.", + "operationId": "v2-get-project-config", + "parameters": [ + { + "name": "ref", + "required": true, + "in": "path", + "description": "Project ref", + "schema": { + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2ProjectConfigResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "[Alpha] Get a project's service configuration", + "tags": ["Projects"], + "x-endpoint-owners": ["control-plane", "infra"], + "x-fga-permissions": [ + [ + "database_config_read", + "database_read", + "database_ssl_config_read", + "database_network_restrictions_read", + "auth_config_read", + "data_api_config_read", + "realtime_config_read", + "storage_config_read" + ] + ] + } + }, "/v2/projects/{ref}/transfers/previews": { "post": { "operationId": "v2-preview-a-project-transfer", @@ -335,13 +530,34 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -351,7 +567,7 @@ ], "summary": "Previews transferring a project to a different organizations, shows eligibility and impact", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["project_admin_read"]] } }, @@ -388,13 +604,34 @@ "description": "" }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -404,7 +641,7 @@ ], "summary": "Transfers a project to a different organization", "tags": ["Projects"], - "x-endpoint-owners": ["management-api"], + "x-endpoint-owners": ["control-plane"], "x-fga-permissions": [["organization_admin_write"]] } }, @@ -438,16 +675,44 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to retrieve AWS accounts for project" + "description": "Failed to retrieve AWS accounts for project", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -457,7 +722,7 @@ ], "summary": "List AWS accounts attached to the project PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_read"]] }, "post": { @@ -500,26 +765,54 @@ } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "402": { "description": "This feature requires the Team, or Enterprise organization plan.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanGateErrorBodyV2" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to add AWS account to PrivateLink share" + "description": "Failed to add AWS account to PrivateLink share", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -536,7 +829,7 @@ "position": "before" } ], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, @@ -573,26 +866,54 @@ "description": "" }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" - }, - "500": { - "description": "Failed to remove AWS account from PrivateLink share" - } - }, - "security": [ + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "500": { + "description": "Failed to remove AWS account from PrivateLink share", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ { "bearer": [] } ], "summary": "Remove an AWS account from the project PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, @@ -638,16 +959,44 @@ "description": "" }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "500": { - "description": "Failed to remove AWS account from PrivateLink share" + "description": "Failed to remove AWS account from PrivateLink share", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -657,70 +1006,27 @@ ], "summary": "Remove an AWS account from a specific database PrivateLink share", "tags": ["Projects"], - "x-endpoint-owners": ["platform-networking", "management-api"], + "x-endpoint-owners": ["platform-networking", "control-plane"], "x-fga-permissions": [["project_admin_write"]] } }, - "/v2/organizations/{slug}/members": { + "/v2/projects/{ref}/workers": { "get": { - "description": "Returns a cursor-paginated list of organization members including their roles and project-scoped permissions.", - "operationId": "v2-list-organization-members", + "description": "Returns all workers you've previously deployed to the specified project.", + "operationId": "v2-list-all-workers", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", "type": "string" } - }, - { - "name": "page", - "required": false, - "in": "query", - "schema": { - "properties": { - "size": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "after": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - }, - "before": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - } - }, - "type": "object" - }, - "style": "deepObject" - }, - { - "name": "filter", - "required": false, - "in": "query", - "schema": { - "properties": { - "username": { - "type": "string" - }, - "primary_email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - } - }, - "type": "object" - }, - "style": "deepObject" } ], "responses": { @@ -729,19 +1035,40 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2ListMembersResponse" + "$ref": "#/components/schemas/V2ListWorkersResponse" } } } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -749,88 +1076,88 @@ "bearer": [] } ], - "summary": "List members of an organization", - "tags": ["Organizations"], + "summary": "[Alpha] List all workers", + "tags": ["Workers"], "x-badges": [ { - "name": "OAuth scope: organizations:read", + "name": "OAuth scope: edge_functions:read", "position": "after" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["members_read"]], - "x-oauth-scope": "organizations:read" + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_read"]], + "x-oauth-scope": "edge_functions:read" } }, - "/v2/organizations/{slug}/members/{user_id}/roles": { - "patch": { - "description": "Assigns an org-wide role when projects is omitted, or creates a project-scoped assignment when projects is provided. Uses an org-level role template id from GET /v2/organizations/{slug}/roles. Stale role assignments are automatically cleaned up: if a role no longer has any projects, it is deleted; overlapping project assignments in other roles are automatically removed to avoid duplication.", - "operationId": "v2-assign-organization-member-role", + "/v2/projects/{ref}/workers/{name}": { + "get": { + "description": "Returns a worker along with its instance tally. Poll this after a deploy until `build_state` leaves `building`.", + "operationId": "v2-get-a-worker", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", "type": "string" } }, { - "name": "user_id", + "name": "name", "required": true, "in": "path", "schema": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", "type": "string" } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V2AssignOrganizationMemberRoleRequest" - } - } - } - }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OrganizationMemberRoleResponse" + "$ref": "#/components/schemas/V2WorkerResponse" } } } }, "401": { - "description": "Unauthorized" - }, - "402": { - "description": "This feature requires the Enterprise organization plan.", + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanGateErrorBodyV2" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" - }, - "500": { - "description": "Failed to assign organization member role" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -838,55 +1165,79 @@ "bearer": [] } ], - "summary": "Assign or change an organization member role", - "tags": ["Organizations"], - "x-allowed-plans": ["Enterprise"], + "summary": "[Alpha] Retrieve a worker", + "tags": ["Workers"], "x-badges": [ { - "name": "Only available on Enterprise", - "position": "before" + "name": "OAuth scope: edge_functions:read", + "position": "after" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["organization_admin_write"]] - } - }, - "/v2/organizations/{slug}/roles": { - "get": { - "description": "Returns a list of org-level roles for the organization.", - "operationId": "v2-list-organization-roles", + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_read"]], + "x-oauth-scope": "edge_functions:read" + }, + "delete": { + "description": "Tombstones the worker. Its instances and image are torn down asynchronously.", + "operationId": "v2-delete-a-worker", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", "type": "string" } } ], "responses": { - "200": { - "description": "", + "204": { + "description": "" + }, + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2ListRolesResponse" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, - "401": { - "description": "Unauthorized" - }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -894,75 +1245,88 @@ "bearer": [] } ], - "summary": "List roles of an organization", - "tags": ["Organizations"], + "summary": "[Alpha] Delete a worker", + "tags": ["Workers"], "x-badges": [ { - "name": "OAuth scope: organizations:read", + "name": "OAuth scope: edge_functions:write", "position": "after" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["members_read"]], - "x-oauth-scope": "organizations:read" + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" } }, - "/v2/organizations/{slug}/members/invitations": { + "/v2/projects/{ref}/workers/{name}/uploads": { "post": { - "description": "Creates member invitations for an organization. Each invitation can have different role and project scope settings.", - "operationId": "v2-create-organization-invitations", + "description": "PUT the `.tar.gz` build context to the returned `url` before `expires_at`, then deploy with the upload id as `context_upload_id`. The bytes go straight to storage — no management API request carries them.", + "operationId": "v2-create-worker-upload", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", "type": "string" } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V2CreateInvitationsRequest" - } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", + "type": "string" } } - }, + ], "responses": { "201": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2CreateInvitationsResponse" + "$ref": "#/components/schemas/V2WorkerUploadResponse" } } } }, "401": { - "description": "Unauthorized" - }, - "402": { - "description": "This feature requires the Enterprise organization plan.", + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanGateErrorBodyV2" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -970,35 +1334,44 @@ "bearer": [] } ], - "summary": "Creates organization invitations", - "tags": ["Organizations Members Invitations"], - "x-allowed-plans": ["Enterprise"], + "summary": "[Alpha] Mint a presigned slot for a build-context upload", + "tags": ["Workers"], "x-badges": [ { - "name": "OAuth scope: organizations:write", + "name": "OAuth scope: edge_functions:write", "position": "after" - }, - { - "name": "Only available on Enterprise", - "position": "before" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["members_write"]], - "x-oauth-scope": "organizations:write" - }, - "delete": { - "description": "Bulk delete member invitations for an organization by email address.", - "operationId": "v2-delete-organization-invitations", + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" + } + }, + "/v2/projects/{ref}/workers/{name}/deploy": { + "post": { + "description": "Creates the worker if it does not exist, building from a context staged through the uploads endpoint. The build runs asynchronously: this answers 202 and the worker reaches `build_state` `active` or `failed` later.", + "operationId": "v2-deploy-a-worker", "parameters": [ { - "name": "slug", + "name": "ref", "required": true, "in": "path", - "description": "Organization slug", + "description": "Project ref", "schema": { - "pattern": "^[\\w-]+$", - "example": "tsrqponmlkjihgfedcba", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "example": "abcdefghijklmnopqrst", + "type": "string" + } + }, + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$", + "example": "hello-world", "type": "string" } } @@ -1008,40 +1381,51 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2DeleteInvitationsRequest" + "$ref": "#/components/schemas/V2DeployWorkerRequest" } } } }, "responses": { - "200": { + "202": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2DeleteInvitationsResponse" + "$ref": "#/components/schemas/V2WorkerResponse" } } } }, "401": { - "description": "Unauthorized" - }, - "402": { - "description": "This feature requires the Enterprise organization plan.", + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanGateErrorBodyV2" + "$ref": "#/components/schemas/ErrorResponseBody" } } } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -1049,28 +1433,23 @@ "bearer": [] } ], - "summary": "Deletes organization invitations by email", - "tags": ["Organizations Members Invitations"], - "x-allowed-plans": ["Enterprise"], + "summary": "[Alpha] Deploy a worker", + "tags": ["Workers"], "x-badges": [ { - "name": "OAuth scope: organizations:write", + "name": "OAuth scope: edge_functions:write", "position": "after" - }, - { - "name": "Only available on Enterprise", - "position": "before" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["members_write"]], - "x-oauth-scope": "organizations:write" + "x-endpoint-owners": ["functions"], + "x-fga-permissions": [["workers_write"]], + "x-oauth-scope": "edge_functions:write" } }, - "/v2/organizations/{slug}/projects": { + "/v2/organizations/{slug}/members": { "get": { - "description": "Returns a cursor-paginated list of projects for the specified organization, including their databases.\n\nUse `page[after]` and `page[before]` to navigate pages and `page[size]` to control the number of projects returned per page.", - "operationId": "v2-list-organization-projects", + "description": "Returns a cursor-paginated list of organization members including their roles and project-scoped permissions.", + "operationId": "v2-list-organization-members", "parameters": [ { "name": "slug", @@ -1096,11 +1475,13 @@ }, "after": { "type": "string", - "minLength": 1 + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, "before": { "type": "string", - "minLength": 1 + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" } }, "type": "object" @@ -1108,25 +1489,23 @@ "style": "deepObject" }, { - "name": "sort", - "required": false, - "in": "query", - "description": "Sort order by creation time: `inserted_at` (oldest first) or `-inserted_at` (newest first). Defaults to `inserted_at`.", - "schema": { - "example": "-inserted_at", - "type": "string", - "enum": ["inserted_at", "-inserted_at"] - } - }, - { - "name": "search", + "name": "filter", "required": false, "in": "query", - "description": "Case-insensitive substring match on the project name.", "schema": { - "minLength": 1, - "type": "string" - } + "properties": { + "username": { + "type": "string" + }, + "primary_email": { + "type": "string", + "format": "email", + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + } + }, + "type": "object" + }, + "style": "deepObject" } ], "responses": { @@ -1135,19 +1514,40 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2ListProjectsResponse" + "$ref": "#/components/schemas/V2ListMembersResponse" } } } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } } }, "security": [ @@ -1155,23 +1555,23 @@ "bearer": [] } ], - "summary": "List projects of an organization", + "summary": "List members of an organization", "tags": ["Organizations"], "x-badges": [ { - "name": "OAuth scope: projects:read", + "name": "OAuth scope: organizations:read", "position": "after" } ], - "x-endpoint-owners": ["management-api"], - "x-fga-permissions": [["organization_projects_read"]], - "x-oauth-scope": "projects:read" + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["members_read"]], + "x-oauth-scope": "organizations:read" } }, - "/v2/organizations/{slug}/integrations/github/connections": { - "get": { - "description": "Returns a cursor-paginated list of the GitHub connections of the organization's projects.\n\nUse `page[after]` and `page[before]` to navigate pages and `page[size]` to control the page size.\nPaging walks the organization projects, so a page holds at most `page[size]` connections and can hold fewer (or none) when some of its projects are not connected.\nFollow `links.next` until it is `null` rather than stopping on a short page.\n\nUse `filter[project_ref]` to narrow the list down to a single project.", - "operationId": "v2-list-organization-github-connections", + "/v2/organizations/{slug}/members/{user_id}/roles": { + "patch": { + "description": "Assigns an org-wide role when projects is omitted, or creates a project-scoped assignment when projects is provided. Uses an org-level role template id from GET /v2/organizations/{slug}/roles. Stale role assignments are automatically cleaned up: if a role no longer has any projects, it is deleted; overlapping project assignments in other roles are automatically removed to avoid duplication.", + "operationId": "v2-assign-organization-member-role", "parameters": [ { "name": "slug", @@ -1185,99 +1585,638 @@ } }, { - "name": "page", - "required": false, - "in": "query", - "schema": { - "properties": { - "size": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "after": { - "type": "string", - "minLength": 20, - "maxLength": 20, - "pattern": "^[a-z]+$", - "description": "Project ref", - "example": "abcdefghijklmnopqrst" - }, - "before": { - "type": "string", - "minLength": 20, - "maxLength": 20, - "pattern": "^[a-z]+$", - "description": "Project ref", - "example": "abcdefghijklmnopqrst" - } - }, - "type": "object" - }, - "style": "deepObject" - }, - { - "name": "filter", - "required": false, - "in": "query", + "name": "user_id", + "required": true, + "in": "path", "schema": { - "properties": { - "project_ref": { - "type": "string", - "minLength": 20, - "maxLength": 20, - "pattern": "^[a-z]+$", - "description": "Project ref", - "example": "abcdefghijklmnopqrst" - } - }, - "type": "object" - }, - "style": "deepObject" + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2AssignOrganizationMemberRoleRequest" + } + } + } + }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2ListGitHubConnectionsResponse" + "$ref": "#/components/schemas/OrganizationMemberRoleResponse" } } } }, "401": { - "description": "Unauthorized" + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "402": { + "description": "This feature requires the Enterprise organization plan.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "403": { - "description": "Forbidden action" + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } }, "429": { - "description": "Rate limit exceeded" - } - }, - "security": [ - { - "bearer": [] - } - ], - "summary": "List GitHub connections of an organization", - "tags": ["Organizations"], - "x-badges": [ - { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "500": { + "description": "Failed to assign organization member role", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Assign or change an organization member role", + "tags": ["Organizations"], + "x-allowed-plans": ["Enterprise"], + "x-badges": [ + { + "name": "Only available on Enterprise", + "position": "before" + } + ], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["organization_admin_write"]] + } + }, + "/v2/organizations/{slug}/roles": { + "get": { + "description": "Returns a list of org-level roles for the organization.", + "operationId": "v2-list-organization-roles", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2ListRolesResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List roles of an organization", + "tags": ["Organizations"], + "x-badges": [ + { + "name": "OAuth scope: organizations:read", + "position": "after" + } + ], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["members_read"]], + "x-oauth-scope": "organizations:read" + } + }, + "/v2/organizations/{slug}/members/invitations": { + "post": { + "description": "Creates member invitations for an organization. Each invitation can have different role and project scope settings.", + "operationId": "v2-create-organization-invitations", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2CreateInvitationsRequest" + } + } + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2CreateInvitationsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "402": { + "description": "This feature requires the Enterprise organization plan.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Creates organization invitations", + "tags": ["Organizations Members Invitations"], + "x-allowed-plans": ["Enterprise"], + "x-badges": [ + { + "name": "OAuth scope: organizations:write", + "position": "after" + }, + { + "name": "Only available on Enterprise", + "position": "before" + } + ], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["members_write"]], + "x-oauth-scope": "organizations:write" + }, + "delete": { + "description": "Bulk delete member invitations for an organization by email address.", + "operationId": "v2-delete-organization-invitations", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2DeleteInvitationsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2DeleteInvitationsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "402": { + "description": "This feature requires the Enterprise organization plan.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Deletes organization invitations by email", + "tags": ["Organizations Members Invitations"], + "x-allowed-plans": ["Enterprise"], + "x-badges": [ + { + "name": "OAuth scope: organizations:write", + "position": "after" + }, + { + "name": "Only available on Enterprise", + "position": "before" + } + ], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["members_write"]], + "x-oauth-scope": "organizations:write" + } + }, + "/v2/organizations/{slug}/projects": { + "get": { + "description": "Returns a cursor-paginated list of projects for the specified organization, including their databases.\n\nUse `page[after]` and `page[before]` to navigate pages and `page[size]` to control the number of projects returned per page.", + "operationId": "v2-list-organization-projects", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "properties": { + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "after": { + "type": "string", + "minLength": 1 + }, + "before": { + "type": "string", + "minLength": 1 + } + }, + "type": "object" + }, + "style": "deepObject" + }, + { + "name": "sort", + "required": false, + "in": "query", + "description": "Sort order by creation time: `inserted_at` (oldest first) or `-inserted_at` (newest first). Defaults to `inserted_at`.", + "schema": { + "example": "-inserted_at", + "type": "string", + "enum": ["inserted_at", "-inserted_at"] + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Case-insensitive substring match on the project name.", + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2ListProjectsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List projects of an organization", + "tags": ["Organizations"], + "x-badges": [ + { + "name": "OAuth scope: projects:read", + "position": "after" + } + ], + "x-endpoint-owners": ["control-plane"], + "x-fga-permissions": [["organization_projects_read"]], + "x-oauth-scope": "projects:read" + } + }, + "/v2/organizations/{slug}/integrations/github/connections": { + "get": { + "description": "Returns a cursor-paginated list of the GitHub connections of the organization's projects.\n\nUse `page[after]` and `page[before]` to navigate pages and `page[size]` to control the page size.\nPaging walks the organization projects, so a page holds at most `page[size]` connections and can hold fewer (or none) when some of its projects are not connected.\nFollow `links.next` until it is `null` rather than stopping on a short page.\n\nUse `filter[project_ref]` to narrow the list down to a single project.", + "operationId": "v2-list-organization-github-connections", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Organization slug", + "schema": { + "pattern": "^[\\w-]+$", + "example": "tsrqponmlkjihgfedcba", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "properties": { + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "after": { + "type": "string", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "description": "Project ref", + "example": "abcdefghijklmnopqrst" + }, + "before": { + "type": "string", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "description": "Project ref", + "example": "abcdefghijklmnopqrst" + } + }, + "type": "object" + }, + "style": "deepObject" + }, + { + "name": "filter", + "required": false, + "in": "query", + "schema": { + "properties": { + "project_ref": { + "type": "string", + "minLength": 20, + "maxLength": 20, + "pattern": "^[a-z]+$", + "description": "Project ref", + "example": "abcdefghijklmnopqrst" + } + }, + "type": "object" + }, + "style": "deepObject" + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2ListGitHubConnectionsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "403": { + "description": "Forbidden action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List GitHub connections of an organization", + "tags": ["Organizations"], + "x-badges": [ + { "name": "OAuth scope: projects:read", "position": "after" } ], - "x-endpoint-owners": ["management-api", "dev-workflows"], + "x-endpoint-owners": ["control-plane", "dev-workflows"], "x-fga-permissions": [["organization_projects_read"]], "x-oauth-scope": "projects:read" } }, "/v2/projects/{ref}/webhooks/endpoints": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-get", "parameters": [ { "in": "path", @@ -2257,7 +3196,7 @@ "description": "List all Webhook endpoints based on a project's ref or an organization's slug." }, "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-post", "parameters": [ { "in": "path", @@ -3283,7 +4222,7 @@ } }, "delete": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-delete", "parameters": [ { "in": "path", @@ -4191,7 +5130,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-get", "parameters": [ { "in": "path", @@ -5200,7 +6139,7 @@ "description": "Get details of a specific endpoint." }, "patch": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-patch", "parameters": [ { "in": "path", @@ -6330,7 +7269,7 @@ } }, "delete": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-delete", "parameters": [ { "in": "path", @@ -7341,7 +8280,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}/deliveries": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-deliveries-get", "parameters": [ { "in": "path", @@ -8406,7 +9345,7 @@ }, "/v2/projects/{ref}/webhooks/endpoints/{id}/test": { "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-endpoints-id-test-post", "parameters": [ { "in": "path", @@ -9526,7 +10465,7 @@ }, "/v2/projects/{ref}/webhooks/deliveries/{id}": { "get": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-deliveries-id-get", "parameters": [ { "in": "path", @@ -10593,7 +11532,7 @@ }, "/v2/projects/{ref}/webhooks/deliveries/{id}/retry": { "post": { - "operationId": "allV2ProjectsByRefWebhooks", + "operationId": "v2-projects-ref-webhooks-deliveries-id-retry-post", "parameters": [ { "in": "path", @@ -11483,7 +12422,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-get", "parameters": [ { "in": "path", @@ -12461,7 +13400,7 @@ "description": "List all Webhook endpoints based on a project's ref or an organization's slug." }, "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-post", "parameters": [ { "in": "path", @@ -13485,7 +14424,7 @@ } }, "delete": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-delete", "parameters": [ { "in": "path", @@ -14391,7 +15330,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-get", "parameters": [ { "in": "path", @@ -15398,7 +16337,7 @@ "description": "Get details of a specific endpoint." }, "patch": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-patch", "parameters": [ { "in": "path", @@ -16526,7 +17465,7 @@ } }, "delete": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-delete", "parameters": [ { "in": "path", @@ -17535,7 +18474,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}/deliveries": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-deliveries-get", "parameters": [ { "in": "path", @@ -18598,7 +19537,7 @@ }, "/v2/organizations/{slug}/webhooks/endpoints/{id}/test": { "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-endpoints-id-test-post", "parameters": [ { "in": "path", @@ -19716,7 +20655,7 @@ }, "/v2/organizations/{slug}/webhooks/deliveries/{id}": { "get": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-deliveries-id-get", "parameters": [ { "in": "path", @@ -20781,7 +21720,7 @@ }, "/v2/organizations/{slug}/webhooks/deliveries/{id}/retry": { "post": { - "operationId": "allV2OrganizationsBySlugWebhooks", + "operationId": "v2-organizations-slug-webhooks-deliveries-id-retry-post", "parameters": [ { "in": "path", @@ -21889,11 +22828,77 @@ "required": ["name", "config", "backend_type"] } }, - "required": ["type", "id", "attributes"] + "required": ["type", "id", "attributes"] + } + } + }, + "required": ["data"] + }, + "ErrorResponseBodyAPIErrorObject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "description": { + "type": "string" + }, + "links": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "href": { + "type": "string" + }, + "rel": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + }, + "describedby": { + "type": "string" + }, + "meta": { + "type": "object", + "additionalProperties": {} + } + }, + "required": ["href"] + } + }, + "meta": { + "type": "object", + "additionalProperties": {} + }, + "issues": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ErrorResponseBodyAPIErrorObject" } } }, - "required": ["data"] + "required": ["code", "message"], + "ref": "APIErrorObject" + }, + "ErrorResponseBody": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorResponseBodyAPIErrorObject" + } + }, + "required": ["error"] }, "CreateLogDrainRequestOpenApi": { "type": "object", @@ -22322,28 +23327,219 @@ }, "required": ["data"] }, - "PlanGateErrorBodyV2": { + "UpdateLogDrainRequestOpenApi": { "type": "object", "properties": { - "error": { + "data": { "type": "object", "properties": { - "code": { + "type": { "type": "string", - "description": "HTTP status-derived error code, e.g. \"payment_required\"" + "description": "Resource type.", + "enum": ["log_drain"] }, - "message": { - "type": "string", - "description": "Human-readable explanation of the plan gate" + "attributes": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "config": { + "anyOf": [ + { + "type": "object", + "properties": { + "url": { + "type": "string", + "nullable": true + }, + "schema": { + "type": "string" + }, + "username": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string", + "nullable": true + }, + "port": { + "type": "number", + "nullable": true + }, + "hostname": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "postgres" + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "http": { + "type": "string", + "enum": ["http1", "http2"] + }, + "gzip": { + "type": "boolean" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false, + "title": "webhook" + }, + { + "type": "object", + "properties": { + "project_id": { + "type": "string" + }, + "dataset_id": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "bigquery" + }, + { + "type": "object", + "properties": { + "api_key": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "datadog" + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "username": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string", + "nullable": true + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false, + "title": "loki" + }, + { + "type": "object", + "properties": { + "dsn": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "sentry" + }, + { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "api_token": { + "type": "string" + }, + "dataset_name": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "axiom" + }, + { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "tls": { + "default": false, + "type": "boolean" + }, + "structured_data": { + "type": "string" + }, + "cipher_key": { + "type": "string" + }, + "ca_cert": { + "type": "string" + }, + "client_cert": { + "type": "string" + }, + "client_key": { + "type": "string" + } + }, + "additionalProperties": false, + "title": "syslog" + } + ] + }, + "backend_type": { + "type": "string", + "enum": [ + "postgres", + "bigquery", + "clickhouse", + "webhook", + "datadog", + "loki", + "sentry", + "s3", + "axiom", + "last9", + "otlp", + "syslog" + ] + } + }, + "required": ["backend_type"] } }, - "required": ["code", "message"], - "description": "Plan-gate error object" + "required": ["type", "attributes"] } }, - "required": ["error"] + "required": ["data"] }, - "UpdateLogDrainRequestOpenApi": { + "V2ProjectConfigResponse": { "type": "object", "properties": { "data": { @@ -22352,205 +23548,524 @@ "type": { "type": "string", "description": "Resource type.", - "enum": ["log_drain"] + "enum": ["project_config"] + }, + "id": { + "type": "string", + "description": "Project ref." }, "attributes": { "type": "object", "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "config": { - "anyOf": [ - { + "database": { + "type": "object", + "properties": { + "major_version": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "The major Postgres version the database runs. `17` covers both Postgres 17 and Oriole on 17, since Oriole is a storage engine rather than a version." + }, + "ssl_enforced": { + "type": "boolean", + "description": "Whether the database rejects plaintext connections" + }, + "network_restrictions": { "type": "object", "properties": { - "url": { + "entitlement": { "type": "string", - "nullable": true - }, - "schema": { - "type": "string" + "enum": ["disallowed", "allowed"] }, - "username": { + "status": { "type": "string", - "nullable": true + "enum": ["stored", "applied"], + "description": "Whether the allowlist below is applied to the project or only stored." }, - "password": { - "type": "string", - "nullable": true + "allowed_cidrs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["v4", "v6"] + } + }, + "required": ["address", "type"] + } }, - "port": { - "type": "number", - "nullable": true + "updated_at": { + "type": "string" }, - "hostname": { + "applied_at": { "type": "string" } }, - "additionalProperties": false, - "title": "postgres" + "required": ["entitlement", "status", "allowed_cidrs"] }, - { + "postgres_settings": { "type": "object", "properties": { - "url": { + "effective_cache_size": { "type": "string" }, - "http": { + "logical_decoding_work_mem": { + "type": "string" + }, + "log_autovacuum_min_duration": { "type": "string", - "enum": ["http1", "http2"] + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" }, - "gzip": { + "log_checkpoints": { "type": "boolean" }, - "headers": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - }, - "additionalProperties": false, - "title": "webhook" - }, - { - "type": "object", - "properties": { - "project_id": { + "log_connections": { + "type": "boolean" + }, + "log_disconnections": { + "type": "boolean" + }, + "log_duration": { + "type": "boolean" + }, + "log_lock_waits": { + "type": "boolean" + }, + "log_recovery_conflict_waits": { + "type": "boolean" + }, + "log_replication_commands": { + "type": "boolean" + }, + "log_startup_progress_interval": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "log_temp_files": { "type": "string" }, - "dataset_id": { + "maintenance_work_mem": { "type": "string" - } - }, - "additionalProperties": false, - "title": "bigquery" - }, - { - "type": "object", - "properties": { - "api_key": { + }, + "track_activity_query_size": { "type": "string" }, - "region": { + "max_connections": { + "type": "integer", + "minimum": 1, + "maximum": 262143 + }, + "max_locks_per_transaction": { + "type": "integer", + "minimum": 10, + "maximum": 2147483640 + }, + "max_logical_replication_workers": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "max_parallel_maintenance_workers": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_parallel_workers": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_parallel_workers_per_gather": { + "type": "integer", + "minimum": 0, + "maximum": 1024 + }, + "max_replication_slots": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_slot_wal_keep_size": { "type": "string" - } - }, - "additionalProperties": false, - "title": "datadog" - }, - { - "type": "object", - "properties": { - "url": { + }, + "max_standby_archive_delay": { "type": "string" }, - "username": { + "max_standby_streaming_delay": { + "type": "string" + }, + "max_sync_workers_per_subscription": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "max_wal_size": { + "type": "string" + }, + "max_wal_senders": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_worker_processes": { + "type": "integer", + "minimum": 0, + "maximum": 262143 + }, + "session_replication_role": { "type": "string", - "nullable": true + "enum": ["origin", "replica", "local"] }, - "password": { + "shared_buffers": { + "type": "string" + }, + "statement_timeout": { "type": "string", - "nullable": true + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" }, - "headers": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - }, - "additionalProperties": false, - "title": "loki" - }, - { - "type": "object", - "properties": { - "dsn": { + "track_commit_timestamp": { + "type": "boolean" + }, + "wal_keep_size": { + "type": "string" + }, + "wal_sender_timeout": { + "type": "string", + "description": "Default unit: ms", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "work_mem": { "type": "string" + }, + "checkpoint_timeout": { + "type": "string", + "description": "Default unit: s", + "pattern": "^(-?[0-9]+(?:\\.[0-9]+)?)(us|ms|s|min|h|d)?$" + }, + "hot_standby_feedback": { + "type": "boolean" + }, + "cron_log_statement": { + "type": "boolean" } }, - "additionalProperties": false, - "title": "sentry" + "description": "Postgres parameter overrides. Empty when the project runs entirely on defaults." + } + }, + "required": [ + "major_version", + "ssl_enforced", + "network_restrictions", + "postgres_settings" + ] + }, + "pooler": { + "type": "object", + "properties": { + "pool_mode": { + "type": "string", + "enum": ["transaction", "session", "statement"] }, - { + "ignore_startup_parameters": { + "type": "string" + }, + "server_idle_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "server_lifetime": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "query_wait_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "reserve_pool_size": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "default_pool_size": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to the pooler's size for the project's compute when not overridden." + }, + "max_client_conn": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to the pooler's size for the project's compute when not overridden." + } + }, + "required": [ + "pool_mode", + "ignore_startup_parameters", + "server_idle_timeout", + "server_lifetime", + "query_wait_timeout", + "reserve_pool_size", + "default_pool_size", + "max_client_conn" + ] + }, + "auth": { + "type": "object", + "additionalProperties": {}, + "description": "Effective Auth config, keyed by lowercased GoTrue setting name and resolved through the `gotrue_config` view, so a setting the project has never overridden is reported at its platform default. Secrets are returned as an HMAC of their value, never in plaintext." + }, + "api": { + "type": "object", + "properties": { + "db_schema": { + "type": "string", + "description": "Schemas exposed through the Data API" + }, + "db_extra_search_path": { + "type": "string" + }, + "max_rows": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "db_pool_acquisition_timeout": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "db_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "If `null`, no pool size is written to the project's PostgREST config and PostgREST's own default applies. The platform does not pick a value here.", + "nullable": true + } + }, + "required": [ + "db_schema", + "db_extra_search_path", + "max_rows", + "db_pool_acquisition_timeout", + "db_pool" + ] + }, + "realtime": { + "type": "object", + "properties": { + "private_only": { + "type": "boolean" + }, + "max_concurrent_users": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_events_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_bytes_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_channels_per_client": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_joins_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_presence_events_per_second": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_payload_size_in_kb": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "presence_enabled": { + "type": "boolean" + }, + "suspend": { + "type": "boolean" + }, + "connection_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Defaults to Realtime's pool size for the project's compute when not overridden." + }, + "postgres_changes_pool": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "If `null`, no override is stored and Realtime applies its own default.", + "nullable": true + } + }, + "required": [ + "private_only", + "max_concurrent_users", + "max_events_per_second", + "max_bytes_per_second", + "max_channels_per_client", + "max_joins_per_second", + "max_presence_events_per_second", + "max_payload_size_in_kb", + "presence_enabled", + "suspend", + "connection_pool", + "postgres_changes_pool" + ] + }, + "storage": { + "type": "object", + "properties": { + "file_size_limit": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "format": "int64" + }, + "features": { "type": "object", "properties": { - "domain": { - "type": "string" + "image_transformation": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": ["enabled"] }, - "api_token": { - "type": "string" + "s3_protocol": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": ["enabled"] + }, + "purge_cache": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": ["enabled"] + }, + "iceberg_catalog": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "max_namespaces": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_tables": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_catalogs": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["enabled", "max_namespaces", "max_tables", "max_catalogs"] }, - "dataset_name": { - "type": "string" + "vector_buckets": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "max_buckets": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "max_indexes": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["enabled", "max_buckets", "max_indexes"] } }, - "additionalProperties": false, - "title": "axiom" + "required": [ + "image_transformation", + "s3_protocol", + "purge_cache", + "iceberg_catalog", + "vector_buckets" + ] }, - { + "capabilities": { "type": "object", "properties": { - "host": { - "type": "string" - }, - "port": { - "type": "integer", - "minimum": 0, - "maximum": 65535 - }, - "tls": { - "default": false, + "list_v2": { "type": "boolean" }, - "structured_data": { - "type": "string" - }, - "cipher_key": { - "type": "string" - }, - "ca_cert": { - "type": "string" - }, - "client_cert": { - "type": "string" - }, - "client_key": { - "type": "string" + "iceberg_catalog": { + "type": "boolean" } }, - "additionalProperties": false, - "title": "syslog" + "required": ["list_v2", "iceberg_catalog"] + }, + "upstream_target": { + "type": "string", + "enum": ["main", "canary"] + }, + "migration_version": { + "type": "string" + }, + "database_pool_mode": { + "type": "string" } - ] - }, - "backend_type": { - "type": "string", - "enum": [ - "postgres", - "bigquery", - "clickhouse", - "webhook", - "datadog", - "loki", - "sentry", - "s3", - "axiom", - "last9", - "otlp", - "syslog" - ] + }, + "required": [ + "file_size_limit", + "features", + "capabilities", + "upstream_target", + "migration_version", + "database_pool_mode" + ], + "description": "Read from the storage service's admin API rather than the middleware DB, so unlike the rest of this resource it reflects the tenant's live config." } }, - "required": ["backend_type"] + "required": ["database", "pooler", "auth", "api", "realtime", "storage"] } }, - "required": ["type", "attributes"] + "required": ["type", "id", "attributes"] } }, "required": ["data"] @@ -22709,6 +24224,18 @@ "database_identifier": { "type": "string", "description": "Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier." + }, + "resource_access_manager_resource_config_id": { + "description": "ID of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_resource_config_arn": { + "description": "ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_share_arn": { + "description": "ARN of the AWS Resource Access Manager resource share for this association.", + "type": "string" } }, "required": [ @@ -22820,6 +24347,18 @@ "database_identifier": { "type": "string", "description": "Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier." + }, + "resource_access_manager_resource_config_id": { + "description": "ID of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_resource_config_arn": { + "description": "ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share.", + "type": "string" + }, + "resource_access_manager_share_arn": { + "description": "ARN of the AWS Resource Access Manager resource share for this association.", + "type": "string" } }, "required": [ @@ -22836,6 +24375,294 @@ }, "required": ["data"] }, + "V2ListWorkersResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "id": { + "type": "string", + "description": "Worker name.", + "example": "hello-world" + }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { + "example": "node", + "type": "string" + }, + "size": { + "type": "string", + "example": "2gb-1vcpu" + }, + "exposure": { + "type": "string", + "example": "public" + }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "build_state": { + "type": "string", + "enum": ["building", "active", "failed"] + }, + "secret_generation": { + "type": "string" + }, + "state_reason": { + "type": "string" + }, + "image_version": { + "type": "string" + }, + "deleting": { + "type": "boolean" + }, + "instances": { + "type": "object", + "properties": { + "declared": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "live": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "ready": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "stale": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["declared", "live", "ready", "stale"] + }, + "instances_error": { + "type": "string" + } + }, + "required": ["spec", "build_state", "secret_generation"] + } + }, + "required": ["type", "id", "attributes"] + } + } + }, + "required": ["data"] + }, + "V2WorkerResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "id": { + "type": "string", + "description": "Worker name.", + "example": "hello-world" + }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { + "example": "node", + "type": "string" + }, + "size": { + "type": "string", + "example": "2gb-1vcpu" + }, + "exposure": { + "type": "string", + "example": "public" + }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "build_state": { + "type": "string", + "enum": ["building", "active", "failed"] + }, + "secret_generation": { + "type": "string" + }, + "state_reason": { + "type": "string" + }, + "image_version": { + "type": "string" + }, + "deleting": { + "type": "boolean" + }, + "instances": { + "type": "object", + "properties": { + "declared": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "live": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "ready": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "stale": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": ["declared", "live", "ready", "stale"] + }, + "instances_error": { + "type": "string" + } + }, + "required": ["spec", "build_state", "secret_generation"] + } + }, + "required": ["type", "id", "attributes"] + } + }, + "required": ["data"] + }, + "V2WorkerUploadResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker_upload"] + }, + "id": { + "type": "string", + "description": "Upload id to pass to the deploy endpoint as `context_upload_id`.", + "example": "cafe0000000000000000000000000000" + }, + "attributes": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "Presigned destination for the `.tar.gz` build context." + }, + "method": { + "type": "string", + "example": "PUT" + }, + "expires_at": { + "type": "string", + "description": "When the slot stops accepting the upload." + } + }, + "required": ["url", "method", "expires_at"] + } + }, + "required": ["type", "id", "attributes"] + } + }, + "required": ["data"] + }, + "V2DeployWorkerRequest": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Resource type.", + "enum": ["project_worker"] + }, + "attributes": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "runtime": { + "example": "node", + "type": "string" + }, + "size": { + "type": "string", + "example": "2gb-1vcpu" + }, + "exposure": { + "type": "string", + "example": "public" + }, + "instances": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "example": 1 + } + }, + "required": ["size", "exposure", "instances"] + }, + "context_upload_id": { + "description": "Id of a build context staged through the uploads endpoint. Required unless `runtime` is set.", + "type": "string" + } + }, + "required": ["spec"] + } + }, + "required": ["type", "attributes"] + } + }, + "required": ["data"] + }, "V2ListMembersResponse": { "type": "object", "properties": { @@ -23109,7 +24936,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" }, "role": { "type": "string", @@ -23119,6 +24948,11 @@ }, "projects": { "description": "The projects to limit a user to. If omitted, user will have org-wide access with the provided role.", + "examples": [ + { + "ref": "abcjuqabhgwjjutfvtpa" + } + ], "minItems": 1, "type": "array", "items": { @@ -23247,7 +25081,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -23275,7 +25111,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -23308,7 +25146,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] @@ -23339,7 +25179,9 @@ "email": { "type": "string", "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "description": "Email address of the invitation receipient.", + "example": "hello@example.com" } }, "required": ["email"] From f09d35cfd5effe8b82c9ad4ca28d3f94d0ff5da7 Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko Date: Wed, 26 Aug 2026 10:43:40 -0700 Subject: [PATCH 3/4] fix(docs): make code blocks reachable and readable by keyboard and screen reader (#49562) Closes DOCS-1283 https://github.com/user-attachments/assets/6e55a27f-6f73-453b-b98f-e91d3c14a9e4 ## Problem Three defects in the docs code block: - The scroll container has no `tabindex`. On `/guides/database/tables`, 18 blocks, none focusable, 2 overflowing at 1280px. Tab skips the scroll region, so a keyboard-only user cannot scroll code that runs off the edge. - The container has `role="group"` with no accessible name, so it announces as bare "group". - The line-number gutter has no `aria-hidden`, so digits are read inline with the code. A block linearizes as `1import { createClient } from '@supabase/supabase-js'23const supabase = ...`, with lines 2 and 3 collapsing into "23". Four more surfaced while testing the fix: - The wrap and copy buttons were absolutely positioned inside the element that scrolls, so `right-2` measured against the scrollable content box. Scrolling dragged them out of the corner into the middle of the code. This one predates the PR. - The buttons preceded the code in the DOM, so a screen reader read two actions before naming what they act on. - `focus-within` only fired for the buttons, so focusing the block left the controls invisible. - Both buttons set an `aria-label` identical to their tooltip text, and Radix points `aria-describedby` at the tooltip on focus, producing "Copy code, button, Copy code". ## Solution Keyboard: - Split the scroll region out of the positioning container, so the controls stay pinned. - Give the scroll region a `tabIndex` and a focus ring. - Reveal the controls on `group-focus-within`. Screen reader: - Name the region `, lines`. Code content stays readable; the summary goes in the name so the group can be skipped or stepped into. - Map fence aliases to spoken names, so `ts` announces as TypeScript. Only the ambiguous ones; `bash`, `python`, `kotlin`, `dart`, `swift` already read fine. - `aria-hidden` the gutter. The numbers are already `select-none`, and copy takes its content from the source string rather than the DOM, so copy behavior is unchanged. - Order the controls after the code. - Announce the word wrap toggle through a live region, matching the copy button. - Opt both buttons out of Radix's generated description. Also moved the `data-wrapped` side effect out of the `setIsWrapped` updater, since React calls updaters twice under StrictMode. ## Manual testing 1. Open `/docs/guides/database/tables`. 2. Run `document.querySelectorAll('.code-scroll[tabindex="0"]').length` in the console. Expect `18`. 3. Run `[...document.querySelectorAll('.code-scroll')].map(b => b.getAttribute('aria-label'))`. Expect entries like `SQL, 11 lines` and `bash, 2 lines`, plus one bare `2 lines` for the fence with no language. 4. Tab to a code block. Expect a visible focus ring, and the wrap and copy buttons to appear. 5. Press ArrowRight on the block under "Basic data loading", which overflows. Expect it to scroll, and the buttons to stay in the top-right corner. 6. Press Enter on the wrap button. Expect the code to wrap and a screen reader to announce "Word wrap enabled". 7. With VoiceOver on, focus a code block. Expect "SQL, 11 lines, code block", then the code read without line numbers interleaved. Focus each button and expect its name once, not twice. ## Summary by CodeRabbit - **Accessibility** - Improved code block labels for screen readers, including programming language and line count. - Added announcements when word wrap is enabled or disabled. - Enhanced keyboard focus behavior for code block controls. - **Usability** - Kept code block controls visible while scrolling through code. - Improved wrapped-code overflow handling. - Removed redundant tooltip descriptions for copy and word-wrap controls. --- .../ui/CodeBlock/CodeBlock.client.tsx | 36 ++++--- apps/docs/features/ui/CodeBlock/CodeBlock.tsx | 98 ++++++++++--------- .../features/ui/CodeBlock/CodeBlock.utils.ts | 27 ++++- apps/docs/styles/globals.css | 2 +- 4 files changed, 100 insertions(+), 63 deletions(-) diff --git a/apps/docs/features/ui/CodeBlock/CodeBlock.client.tsx b/apps/docs/features/ui/CodeBlock/CodeBlock.client.tsx index 2db18ab15c46b..4ec13d2478a46 100644 --- a/apps/docs/features/ui/CodeBlock/CodeBlock.client.tsx +++ b/apps/docs/features/ui/CodeBlock/CodeBlock.client.tsx @@ -119,6 +119,8 @@ export function CodeCopyButton({ className, content }: { className?: string; con className )} aria-label="Copy code" + // Tooltip repeats the label; the description would read the name twice + aria-describedby={undefined} > {copied ? ( @@ -135,29 +137,33 @@ export function CodeCopyButton({ className, content }: { className?: string; con export function CodeBlockControls({ content }: { content: string }) { const [isWrapped, setIsWrapped] = useState(false) + // Empty until the first toggle, so nothing is announced on mount + const [wrapStatus, setWrapStatus] = useState('') const wrapperRef = useRef(null) const toggleWrap = useCallback(() => { - setIsWrapped((prev) => { - const newValue = !prev - // Find the parent code block and toggle the wrap data attribute - const codeBlock = wrapperRef.current?.closest('.shiki') - if (codeBlock) { - if (newValue) { - codeBlock.setAttribute('data-wrapped', 'true') - } else { - codeBlock.removeAttribute('data-wrapped') - } + const newValue = !isWrapped + setIsWrapped(newValue) + setWrapStatus(newValue ? 'Word wrap enabled' : 'Word wrap disabled') + + const codeBlock = wrapperRef.current?.closest('.shiki') + if (codeBlock) { + if (newValue) { + codeBlock.setAttribute('data-wrapped', 'true') + } else { + codeBlock.removeAttribute('data-wrapped') } - return newValue - }) - }, []) + } + }, [isWrapped]) return (
    + + {wrapStatus} +
    ) } diff --git a/apps/docs/features/ui/CodeBlock/CodeBlock.utils.ts b/apps/docs/features/ui/CodeBlock/CodeBlock.utils.ts index 2202c2a5193c4..b3046183a388f 100644 --- a/apps/docs/features/ui/CodeBlock/CodeBlock.utils.ts +++ b/apps/docs/features/ui/CodeBlock/CodeBlock.utils.ts @@ -1,8 +1,6 @@ import { type CSSProperties } from 'react' -/* - * As defined in @shikijs/core/dist/chunk-tokens.d.mts - */ +// As defined in @shikijs/core/dist/chunk-tokens.d.mts enum FontStyle { NotSet = -1, None = 0, @@ -28,3 +26,26 @@ export function getFontStyle(styleFlags: number): CSSProperties { return style } + +// Fence aliases a screen reader would otherwise read letter by letter +const LANGUAGE_LABELS: Record = { + c: 'C', + html: 'HTML', + js: 'JavaScript', + json: 'JSON', + jsx: 'JavaScript', + py: 'Python', + sh: 'Shell', + shell: 'Shell', + sql: 'SQL', + toml: 'TOML', + ts: 'TypeScript', + tsx: 'TypeScript', + yaml: 'YAML', +} + +export function getCodeBlockLabel(lang: string | null, lineCount: number): string { + const lines = `${lineCount} ${lineCount === 1 ? 'line' : 'lines'}` + if (!lang) return lines + return `${LANGUAGE_LABELS[lang] ?? lang}, ${lines}` +} diff --git a/apps/docs/styles/globals.css b/apps/docs/styles/globals.css index 4064aaa21992c..42266e52e4065 100644 --- a/apps/docs/styles/globals.css +++ b/apps/docs/styles/globals.css @@ -452,7 +452,7 @@ th code { } /* Word wrap styles for code blocks */ -.shiki[data-wrapped='true'] { +.shiki[data-wrapped='true'] .code-scroll { overflow-x: hidden !important; } From 272a288c9b8c4517e6d5ae2f5e5c98ec61fe33ef Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 26 Aug 2026 13:28:16 -0500 Subject: [PATCH 4/4] chore(docs): add Simon Tomlinson to humans.txt (#49547) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Add my name to humans.txt ## What is the current behavior? Please link any relevant issues here. ## What is the new behavior? Feel free to include screenshots if it includes visual changes. ## Additional context Add any other context or screenshots. ## Summary by CodeRabbit * **Documentation** * Added Simon Tomlinson to the team information listed in the project documentation. --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 0f40c00761bdf..964214306f51e 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -283,6 +283,7 @@ Shane E Shaun Newman Shardul Borhade Shreekar Shetty +Simon Tomlinson Sreyas Udayavarman Stephanie Jackson (stejacks) Stephen Morgan