Repository: supabase/cli
Pull request #2916 (2024-11-26 02:29:45)

Prod deploy
- **feat: diff auth and storage config on link**
- **fix: update postgres image if linked project is healthy**
- **chore: adjust default sms template to match platform**
- **chore: update api/beta.yaml from staging v1-yaml (#2906)**
- **fix: bump edge-runtime to 1.64.1 (#2911)**
- **chore(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#2913)**
- **chore: remove trailing semicolon from role_configs.sql (#2907)**
- **fix(realtime): bump realtime image to 2.33.51 (#2905)**
- **fix(reset): ensure _supabase connections disconnect before reset (#2904)**
- **feat(config): allow custom admin and sendername for inbucket (#2908)**



Patch:
diff --git a/api/beta.yaml b/api/beta.yaml
index 257a46e8..cd6c20a1 100644
--- a/api/beta.yaml
+++ b/api/beta.yaml
@@ -118,7 +118,7 @@ paths:
               schema:
                 type: array
                 items:
-                  $ref: '#/components/schemas/V1ProjectResponse'
+                  $ref: '#/components/schemas/V1ProjectWithDatabaseResponse'
       tags:
         - Projects
       security:
@@ -132,7 +132,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/V1CreateProjectBody'
+              $ref: '#/components/schemas/V1CreateProjectBodyDto'
       responses:
         '201':
           description: ''
@@ -174,7 +174,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/CreateOrganizationBodyV1'
+              $ref: '#/components/schemas/CreateOrganizationV1Dto'
       responses:
         '201':
           description: ''
@@ -331,6 +331,11 @@ paths:
             minLength: 20
             maxLength: 20
             type: string
+        - name: reveal
+          required: true
+          in: query
+          schema:
+            type: boolean
       responses:
         '200':
           description: ''
@@ -356,6 +361,11 @@ paths:
             minLength: 20
             maxLength: 20
             type: string
+        - name: reveal
+          required: true
+          in: query
+          schema:
+            type: boolean
       requestBody:
         required: true
         content:
@@ -391,6 +401,11 @@ paths:
           in: path
           schema:
             type: string
+        - name: reveal
+          required: true
+          in: query
+          schema:
+            type: boolean
       requestBody:
         required: true
         content:
@@ -408,6 +423,39 @@ paths:
         - Secrets
       security:
         - bearer: []
+    get:
+      operationId: getApiKey
+      summary: '[Alpha] Get API key'
+      parameters:
+        - name: ref
+          required: true
+          in: path
+          description: Project ref
+          schema:
+            minLength: 20
+            maxLength: 20
+            type: string
+        - name: id
+          required: true
+          in: path
+          schema:
+            type: string
+        - name: reveal
+          required: true
+          in: query
+          schema:
+            type: boolean
+      responses:
+        '200':
+          description: ''
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiKeyResponse'
+      tags:
+        - Secrets
+      security:
+        - bearer: []
     delete:
       operationId: deleteApiKey
       summary: '[Alpha] Deletes an API key for the project'
@@ -425,6 +473,11 @@ paths:
           in: path
           schema:
             type: string
+        - name: reveal
+          required: true
+          in: query
+          schema:
+            type: boolean
       responses:
         '200':
           description: ''
@@ -927,7 +980,7 @@ paths:
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/V1ProjectResponse'
+                $ref: '#/components/schemas/V1ProjectWithDatabaseResponse'
         '500':
           description: Failed to retrieve project
       tags:
@@ -2012,6 +2065,13 @@ paths:
           in: query
           schema:
             type: string
+        - name: compute_multiplier
+          required: false
+          in: query
+          schema:
+            minimum: 1
+            maximum: 4
+            type: number
       requestBody:
         required: true
         content:
@@ -2153,6 +2213,13 @@ paths:
           in: query
           schema:
             type: string
+        - name: compute_multiplier
+          required: false
+          in: query
+          schema:
+            minimum: 1
+            maximum: 4
+            type: number
       requestBody:
         required: true
         content:
@@ -2728,7 +2795,7 @@ components:
         - version
         - postgres_engine
         - release_channel
-    V1ProjectResponse:
+    V1ProjectWithDatabaseResponse:
       type: object
       properties:
         id:
@@ -2774,36 +2841,9 @@ components:
         - name
         - region
         - created_at
+        - database
         - status
-    DesiredInstanceSize:
-      type: string
-      enum:
-        - micro
-        - small
-        - medium
-        - large
-        - xlarge
-        - 2xlarge
-        - 4xlarge
-        - 8xlarge
-        - 12xlarge
-        - 16xlarge
-    ReleaseChannel:
-      type: string
-      enum:
-        - internal
-        - alpha
-        - beta
-        - ga
-        - withdrawn
-    PostgresEngine:
-      type: string
-      description: >-
-        Postgres engine version. If not provided, the latest version will be
-        used.
-      enum:
-        - '15'
-    V1CreateProjectBody:
+    V1CreateProjectBodyDto:
       type: object
       properties:
         db_pass:
@@ -2820,13 +2860,13 @@ components:
           enum:
             - free
             - pro
+          deprecated: true
           description: >-
             Subscription Plan is now set on organization level and is ignored in
             this request
-          example: free
-          deprecated: true
         region:
           type: string
+          description: Region you want your server to reside in
           enum:
             - us-east-1
             - us-east-2
@@ -2846,28 +2886,96 @@ components:
             - ca-central-1
             - ap-south-1
             - sa-east-1
-          description: Region you want your server to reside in
-          example: us-east-1
         kps_enabled:
           type: boolean
           deprecated: true
           description: This field is deprecated and is ignored in this request
         desired_instance_size:
-          $ref: '#/components/schemas/DesiredInstanceSize'
+          type: string
+          enum:
+            - micro
+            - small
+            - medium
+            - large
+            - xlarge
+            - 2xlarge
+            - 4xlarge
+            - 8xlarge
+            - 12xlarge
+            - 16xlarge
         template_url:
           type: string
+          format: uri
           description: Template URL used to create the project from the CLI.
           example: >-
             https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone
         release_channel:
-          $ref: '#/components/schemas/ReleaseChannel'
+          type: string
+          enum:
+            - internal
+            - alpha
+            - beta
+            - ga
+            - withdrawn
+          description: Release channel. If not provided, GA will be used.
         postgres_engine:
-          $ref: '#/components/schemas/PostgresEngine'
+          type: string
+          enum:
+            - '15'
+          description: >-
+            Postgres engine version. If not provided, the latest version will be
+            used.
       required:
         - db_pass
         - name
         - organization_id
         - region
+      additionalProperties: false
+    V1ProjectResponse:
+      type: object
+      properties:
+        id:
+          type: string
+          description: Id of your project
+        organization_id:
+          type: string
+          description: Slug of your organization
+        name:
+          type: string
+          description: Name of your project
+        region:
+          type: string
+          description: Region of your project
+          example: us-east-1
+        created_at:
+          type: string
+          description: Creation timestamp
+          example: '2023-03-29T16:32:59Z'
+        status:
+          enum:
+            - ACTIVE_HEALTHY
+            - ACTIVE_UNHEALTHY
+            - COMING_UP
+            - GOING_DOWN
+            - INACTIVE
+            - INIT_FAILED
+            - REMOVED
+            - RESTARTING
+            - UNKNOWN
+            - UPGRADING
+            - PAUSING
+            - RESTORING
+            - RESTORE_FAILED
+            - PAUSE_FAILED
+            - RESIZING
+          type: string
+      required:
+        - id
+        - organization_id
+        - name
+        - region
+        - created_at
+        - status
     OrganizationResponseV1:
       type: object
       properties:
@@ -2878,13 +2986,14 @@ components:
       required:
         - id
         - name
-    CreateOrganizationBodyV1:
+    CreateOrganizationV1Dto:
       type: object
       properties:
         name:
           type: string
       required:
         - name
+      additionalProperties: false
     OAuthTokenBody:
       type: object
       properties:
@@ -3128,6 +3237,34 @@ components:
           nullable: true
           allOf:
             - $ref: '#/components/schemas/ApiKeySecretJWTTemplate'
+    DesiredInstanceSize:
+      type: string
+      enum:
+        - micro
+        - small
+        - medium
+        - large
+        - xlarge
+        - 2xlarge
+        - 4xlarge
+        - 8xlarge
+        - 12xlarge
+        - 16xlarge
+    ReleaseChannel:
+      type: string
+      enum:
+        - internal
+        - alpha
+        - beta
+        - ga
+        - withdrawn
+    PostgresEngine:
+      type: string
+      description: >-
+        Postgres engine version. If not provided, the latest version will be
+        used.
+      enum:
+        - '15'
     CreateBranchBody:
       type: object
       properties:
@@ -5090,6 +5227,10 @@ components:
           type: string
         verify_jwt:
           type: boolean
+        compute_multiplier:
+          type: number
+          minimum: 1
+          maximum: 4
       required:
         - slug
         - name
@@ -5125,6 +5266,8 @@ components:
           type: string
         import_map_path:
           type: string
+        compute_multiplier:
+          type: number
       required:
         - version
         - created_at
@@ -5164,6 +5307,8 @@ components:
           type: string
         import_map_path:
           type: string
+        compute_multiplier:
+          type: number
       required:
         - version
         - created_at
@@ -5181,6 +5326,10 @@ components:
           type: string
         verify_jwt:
           type: boolean
+        compute_multiplier:
+          type: number
+          minimum: 1
+          maximum: 4
     V1StorageBucketResponse:
       type: object
       properties:
diff --git a/cmd/projects.go b/cmd/projects.go
index 08ec10dd..c119e717 100644
--- a/cmd/projects.go
+++ b/cmd/projects.go
@@ -33,21 +33,21 @@ var (
 		Allowed: awsRegions(),
 	}
 	plan = utils.EnumFlag{
-		Allowed: []string{string(api.V1CreateProjectBodyPlanFree), string(api.V1CreateProjectBodyPlanPro)},
-		Value:   string(api.V1CreateProjectBodyPlanFree),
+		Allowed: []string{string(api.V1CreateProjectBodyDtoPlanFree), string(api.V1CreateProjectBodyDtoPlanPro)},
+		Value:   string(api.V1CreateProjectBodyDtoPlanFree),
 	}
 	size = utils.EnumFlag{
 		Allowed: []string{
-			string(api.Micro),
-			string(api.Small),
-			string(api.Medium),
-			string(api.Large),
-			string(api.Xlarge),
-			string(api.N2xlarge),
-			string(api.N4xlarge),
-			string(api.N8xlarge),
-			string(api.N12xlarge),
-			string(api.N16xlarge),
+			string(api.DesiredInstanceSizeMicro),
+			string(api.DesiredInstanceSizeSmall),
+			string(api.DesiredInstanceSizeMedium),
+			string(api.DesiredInstanceSizeLarge),
+			string(api.DesiredInstanceSizeXlarge),
+			string(api.DesiredInstanceSizeN2xlarge),
+			string(api.DesiredInstanceSizeN4xlarge),
+			string(api.DesiredInstanceSizeN8xlarge),
+			string(api.DesiredInstanceSizeN12xlarge),
+			string(api.DesiredInstanceSizeN16xlarge),
 		},
 	}
 
@@ -69,14 +69,14 @@ var (
 			if len(args) > 0 {
 				projectName = args[0]
 			}
-			body := api.V1CreateProjectBody{
+			body := api.V1CreateProjectBodyDto{
 				Name:           projectName,
 				OrganizationId: orgId,
 				DbPass:         dbPassword,
-				Region:         api.V1CreateProjectBodyRegion(region.Value),
+				Region:         api.V1CreateProjectBodyDtoRegion(region.Value),
 			}
 			if cmd.Flags().Changed("size") {
-				body.DesiredInstanceSize = (*api.DesiredInstanceSize)(&size.Value)
+				body.DesiredInstanceSize = (*api.V1CreateProjectBodyDtoDesiredInstanceSize)(&size.Value)
 			}
 			return create.Run(cmd.Context(), body, afero.NewOsFs())
 		},
diff --git a/docs/supabase/db/reset.md b/docs/supabase/db/reset.md
index 98a8003c..acb9b983 100644
--- a/docs/supabase/db/reset.md
+++ b/docs/supabase/db/reset.md
@@ -6,4 +6,4 @@ Requires the local development stack to be started by running `supabase start`.
 
 Recreates the local Postgres container and applies all local migrations found in `supabase/migrations` directory. If test data is defined in `supabase/seed.sql`, it will be seeded after the migrations are run. Any other data or schema changes made during local development will be discarded.
 
-Note that since Postgres roles are cluster level entities, those changes will persist between resets. In order to reset custom roles, you need to restart the local development stack.
+When running db reset with `--linked` or `--db-url` flag, a SQL script is executed to identify and drop all user created entities in the remote database. Since Postgres roles are cluster level entities, any custom roles created through the dashboard or `supabase/roles.sql` will not be deleted by remote reset.
diff --git a/go.mod b/go.mod
index 4e58e456..d8bfd627 100644
--- a/go.mod
+++ b/go.mod
@@ -21,9 +21,9 @@ require (
 	github.com/gin-gonic/gin v1.10.0
 	github.com/go-errors/errors v1.5.1
 	github.com/go-git/go-git/v5 v5.12.0
-	github.com/go-xmlfmt/xmlfmt v1.1.2
+	github.com/go-xmlfmt/xmlfmt v1.1.3
 	github.com/golang-jwt/jwt/v5 v5.2.1
-	github.com/golangci/golangci-lint v1.62.0
+	github.com/golangci/golangci-lint v1.62.2
 	github.com/google/go-github/v62 v62.0.0
 	github.com/google/go-querystring v1.1.0
 	github.com/google/uuid v1.6.0
@@ -44,8 +44,8 @@ require (
 	github.com/spf13/cobra v1.8.1
 	github.com/spf13/pflag v1.0.5
 	github.com/spf13/viper v1.19.0
-	github.com/stretchr/testify v1.9.0
-	github.com/stripe/pg-schema-diff v0.7.0
+	github.com/stretchr/testify v1.10.0
+	github.com/stripe/pg-schema-diff v0.8.0
 	github.com/withfig/autocomplete-tools/packages/cobra v1.2.0
 	github.com/zalando/go-keyring v0.2.6
 	go.opentelemetry.io/otel v1.32.0
@@ -66,9 +66,9 @@ require (
 	github.com/Abirdcfly/dupword v0.1.3 // indirect
 	github.com/Antonboom/errname v1.0.0 // indirect
 	github.com/Antonboom/nilnil v1.0.0 // indirect
-	github.com/Antonboom/testifylint v1.5.0 // indirect
+	github.com/Antonboom/testifylint v1.5.2 // indirect
 	github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
-	github.com/Crocmagnon/fatcontext v0.5.2 // indirect
+	github.com/Crocmagnon/fatcontext v0.5.3 // indirect
 	github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
 	github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect
 	github.com/Masterminds/semver/v3 v3.3.0 // indirect
@@ -226,7 +226,7 @@ require (
 	github.com/mattn/go-localereader v0.0.1 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
-	github.com/mgechev/revive v1.5.0 // indirect
+	github.com/mgechev/revive v1.5.1 // indirect
 	github.com/microcosm-cc/bluemonday v1.0.25 // indirect
 	github.com/miekg/pkcs11 v1.1.1 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
@@ -245,7 +245,7 @@ require (
 	github.com/nakabonne/nestif v0.3.1 // indirect
 	github.com/nishanths/exhaustive v0.12.0 // indirect
 	github.com/nishanths/predeclared v0.2.2 // indirect
-	github.com/nunnatsa/ginkgolinter v0.18.0 // indirect
+	github.com/nunnatsa/ginkgolinter v0.18.3 // indirect
 	github.com/olekukonko/tablewriter v0.0.5 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
@@ -254,7 +254,7 @@ require (
 	github.com/pjbgf/sha1cd v0.3.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
-	github.com/polyfloyd/go-errorlint v1.6.0 // indirect
+	github.com/polyfloyd/go-errorlint v1.7.0 // indirect
 	github.com/prometheus/client_golang v1.12.1 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
 	github.com/prometheus/common v0.32.1 // indirect
@@ -303,7 +303,7 @@ require (
 	github.com/ultraware/funlen v0.1.0 // indirect
 	github.com/ultraware/whitespace v0.1.1 // indirect
 	github.com/uudashr/gocognit v1.1.3 // indirect
-	github.com/uudashr/iface v1.2.0 // indirect
+	github.com/uudashr/iface v1.2.1 // indirect
 	github.com/xanzy/ssh-agent v0.3.3 // indirect
 	github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
@@ -334,7 +334,7 @@ require (
 	golang.org/x/arch v0.8.0 // indirect
 	golang.org/x/crypto v0.29.0 // indirect
 	golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
-	golang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0 // indirect
+	golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f // indirect
 	golang.org/x/net v0.31.0 // indirect
 	golang.org/x/sync v0.9.0 // indirect
 	golang.org/x/sys v0.27.0 // indirect
diff --git a/go.sum b/go.sum
index e224d065..28de4b7e 100644
--- a/go.sum
+++ b/go.sum
@@ -47,16 +47,16 @@ github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoT
 github.com/Antonboom/errname v1.0.0/go.mod h1:gMOBFzK/vrTiXN9Oh+HFs+e6Ndl0eTFbtsRTSRdXyGI=
 github.com/Antonboom/nilnil v1.0.0 h1:n+v+B12dsE5tbAqRODXmEKfZv9j2KcTBrp+LkoM4HZk=
 github.com/Antonboom/nilnil v1.0.0/go.mod h1:fDJ1FSFoLN6yoG65ANb1WihItf6qt9PJVTn/s2IrcII=
-github.com/Antonboom/testifylint v1.5.0 h1:dlUIsDMtCrZWUnvkaCz3quJCoIjaGi41GzjPBGkkJ8A=
-github.com/Antonboom/testifylint v1.5.0/go.mod h1:wqaJbu0Blb5Wag2wv7Z5xt+CIV+eVLxtGZrlK13z3AE=
+github.com/Antonboom/testifylint v1.5.2 h1:4s3Xhuv5AvdIgbd8wOOEeo0uZG7PbDKQyKY5lGoQazk=
+github.com/Antonboom/testifylint v1.5.2/go.mod h1:vxy8VJ0bc6NavlYqjZfmp6EfqXMtBgQ4+mhCojwC1P8=
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
 github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/Crocmagnon/fatcontext v0.5.2 h1:vhSEg8Gqng8awhPju2w7MKHqMlg4/NI+gSDHtR3xgwA=
-github.com/Crocmagnon/fatcontext v0.5.2/go.mod h1:87XhRMaInHP44Q7Tlc7jkgKKB7kZAOPiDkFMdKCC+74=
+github.com/Crocmagnon/fatcontext v0.5.3 h1:zCh/wjc9oyeF+Gmp+V60wetm8ph2tlsxocgg/J0hOps=
+github.com/Crocmagnon/fatcontext v0.5.3/go.mod h1:XoCQYY1J+XTfyv74qLXvNw4xFunr3L1wkopIIKG7wGM=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
 github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU=
@@ -371,8 +371,8 @@ github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUN
 github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
 github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
 github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
-github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
-github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
+github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY=
+github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
 github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
@@ -427,8 +427,8 @@ github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUP
 github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
 github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME=
 github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9/go.mod h1:Oesb/0uFAyWoaw1U1qS5zyjCg5NP9C9iwjnI4tIsXEE=
-github.com/golangci/golangci-lint v1.62.0 h1:/G0g+bi1BhmGJqLdNQkKBWjcim8HjOPc4tsKuHDOhcI=
-github.com/golangci/golangci-lint v1.62.0/go.mod h1:jtoOhQcKTz8B6dGNFyfQV3WZkQk+YvBDewDtNpiAJts=
+github.com/golangci/golangci-lint v1.62.2 h1:b8K5K9PN+rZN1+mKLtsZHz2XXS9aYKzQ9i25x3Qnxxw=
+github.com/golangci/golangci-lint v1.62.2/go.mod h1:ILWWyeFUrctpHVGMa1dg2xZPKoMUTc5OIMgW7HZr34g=
 github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
 github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
 github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA=
@@ -703,8 +703,8 @@ github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
 github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mgechev/revive v1.5.0 h1:oaSmjA7rP8+HyoRuCgC531VHwnLH1AlJdjj+1AnQceQ=
-github.com/mgechev/revive v1.5.0/go.mod h1:L6T3H8EoerRO86c7WuGpvohIUmiploGiyoYbtIWFmV8=
+github.com/mgechev/revive v1.5.1 h1:hE+QPeq0/wIzJwOphdVyUJ82njdd8Khp4fUIHGZHW3M=
+github.com/mgechev/revive v1.5.1/go.mod h1:lC9AhkJIBs5zwx8wkudyHrU+IJkrEKmpCmGMnIJPk4o=
 github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
 github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
 github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
@@ -755,8 +755,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK
 github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
 github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
 github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
-github.com/nunnatsa/ginkgolinter v0.18.0 h1:ZXO1wKhPg3A6LpbN5dMuqwhfOjN5c3ous8YdKOuqk9k=
-github.com/nunnatsa/ginkgolinter v0.18.0/go.mod h1:vPrWafSULmjMGCMsfGA908if95VnHQNAahvSBOjTuWs=
+github.com/nunnatsa/ginkgolinter v0.18.3 h1:WgS7X3zzmni3vwHSBhvSgqrRgUecN6PQUcfB0j1noDw=
+github.com/nunnatsa/ginkgolinter v0.18.3/go.mod h1:BE1xyB/PNtXXG1azrvrqJW5eFH0hSRylNzFy8QHPwzs=
 github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
 github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@@ -801,8 +801,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg8/OwcYY=
-github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw=
+github.com/polyfloyd/go-errorlint v1.7.0 h1:Zp6lzCK4hpBDj8y8a237YK4EPrMXQWvOe3nGoH4pFrU=
+github.com/polyfloyd/go-errorlint v1.7.0/go.mod h1:dGWKu85mGHnegQ2SWpEybFityCg3j7ZbwsVUxAOk9gY=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
 github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -947,10 +947,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/stripe/pg-schema-diff v0.7.0 h1:00Z+LGGe9GhMsN5gLtx/ZwF/+xPOMgod/g8x8H1JmV4=
-github.com/stripe/pg-schema-diff v0.7.0/go.mod h1:HuTBuWLuvnY9g9nptbSD58xugN19zSJNkF4w/sYRtdU=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stripe/pg-schema-diff v0.8.0 h1:Ggm4yDbPtaflYQLV3auEMTLxQPaentV/wmDEoCF5jxQ=
+github.com/stripe/pg-schema-diff v0.8.0/go.mod h1:HuTBuWLuvnY9g9nptbSD58xugN19zSJNkF4w/sYRtdU=
 github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
 github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM=
@@ -981,8 +981,8 @@ github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/
 github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
 github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM=
 github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U=
-github.com/uudashr/iface v1.2.0 h1:ECJjh5q/1Zmnv/2yFpWV6H3oMg5+Mo+vL0aqw9Gjazo=
-github.com/uudashr/iface v1.2.0/go.mod h1:Ux/7d/rAF3owK4m53cTVXL4YoVHKNqnoOeQHn2xrlp0=
+github.com/uudashr/iface v1.2.1 h1:vHHyzAUmWZ64Olq6NZT3vg/z1Ws56kyPdBOd5kTXDF8=
+github.com/uudashr/iface v1.2.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg=
 github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 h1:MzD3XeOOSO3mAjOPpF07jFteSKZxsRHvlIcAR9RQzKM=
 github.com/withfig/autocomplete-tools/packages/cobra v1.2.0/go.mod h1:RoXh7+7qknOXL65uTzdzE1mPxqcPwS7FLCE9K5GfmKo=
 github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
@@ -1117,8 +1117,8 @@ golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBn
 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
 golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0 h1:bVwtbF629Xlyxk6xLQq2TDYmqP0uiWaet5LwRebuY0k=
-golang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f h1:WTyX8eCCyfdqiPYkRGm0MqElSfYFH3yR1+rl/mct9sA=
+golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go
index 4769a81d..677ef153 100644
--- a/internal/bootstrap/bootstrap.go
+++ b/internal/bootstrap/bootstrap.go
@@ -77,7 +77,7 @@ func Run(ctx context.Context, starter StarterTemplate, fsys afero.Fs, options ..
 		return err
 	}
 	// 2. Create project
-	params := api.V1CreateProjectBody{
+	params := api.V1CreateProjectBodyDto{
 		Name:        filepath.Base(workdir),
 		TemplateUrl: &starter.Url,
 	}
diff --git a/internal/db/diff/diff.go b/internal/db/diff/diff.go
index 38a3bed5..6c5faa89 100644
--- a/internal/db/diff/diff.go
+++ b/internal/db/diff/diff.go
@@ -146,12 +146,12 @@ func CreateShadowDatabase(ctx context.Context, port uint16) (string, error) {
 
 func ConnectShadowDatabase(ctx context.Context, timeout time.Duration, options ...func(*pgx.ConnConfig)) (conn *pgx.Conn, err error) {
 	// Retry until connected, cancelled, or timeout
-	policy := backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), uint64(timeout.Seconds()))
+	policy := start.NewBackoffPolicy(ctx, timeout)
 	config := pgconn.Config{Port: utils.Config.Db.ShadowPort}
 	connect := func() (*pgx.Conn, error) {
 		return utils.ConnectLocalPostgres(ctx, config, options...)
 	}
-	return backoff.RetryWithData(connect, backoff.WithContext(policy, ctx))
+	return backoff.RetryWithData(connect, policy)
 }
 
 func MigrateShadowDatabase(ctx context.Context, container string, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
diff --git a/internal/db/reset/reset.go b/internal/db/reset/reset.go
index a9d2f4f4..a475ca80 100644
--- a/internal/db/reset/reset.go
+++ b/internal/db/reset/reset.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/cenkalti/backoff/v4"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/network"
@@ -164,20 +165,40 @@ func recreateDatabase(ctx context.Context, options ...func(*pgx.ConnConfig)) err
 	return sql.ExecBatch(ctx, conn)
 }
 
+const (
+	TERMINATE_BACKENDS      = "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IN ('postgres', '_supabase')"
+	COUNT_REPLICATION_SLOTS = "SELECT COUNT(*) FROM pg_replication_slots WHERE database IN ('postgres', '_supabase')"
+)
+
 func DisconnectClients(ctx context.Context, conn *pgx.Conn) error {
-	// Must be executed separately because running in transaction is unsupported
-	disconn := "ALTER DATABASE postgres ALLOW_CONNECTIONS false;"
-	if _, err := conn.Exec(ctx, disconn); err != nil {
+	// Must be executed separately because looping in transaction is unsupported
+	// https://dba.stackexchange.com/a/11895
+	disconn := migration.MigrationFile{
+		Statements: []string{
+			"ALTER DATABASE postgres ALLOW_CONNECTIONS false",
+			"ALTER DATABASE _supabase ALLOW_CONNECTIONS false",
+			TERMINATE_BACKENDS,
+		},
+	}
+	if err := disconn.ExecBatch(ctx, conn); err != nil {
 		var pgErr *pgconn.PgError
 		if errors.As(err, &pgErr) && pgErr.Code != pgerrcode.InvalidCatalogName {
 			return errors.Errorf("failed to disconnect clients: %w", err)
 		}
 	}
-	term := fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")
-	if _, err := conn.Exec(ctx, term); err != nil {
-		return errors.Errorf("failed to terminate backend: %w", err)
+	// Wait for WAL senders to drop their replication slots
+	policy := start.NewBackoffPolicy(ctx, 10*time.Second)
+	waitForDrop := func() error {
+		var count int
+		if err := conn.QueryRow(ctx, COUNT_REPLICATION_SLOTS).Scan(&count); err != nil {
+			err = errors.Errorf("failed to count replication slots: %w", err)
+			return &backoff.PermanentError{Err: err}
+		} else if count > 0 {
+			return errors.Errorf("replication slots still active: %d", count)
+		}
+		return nil
 	}
-	return nil
+	return backoff.Retry(waitForDrop, policy)
 }
 
 func RestartDatabase(ctx context.Context, w io.Writer) error {
diff --git a/internal/db/start/start.go b/internal/db/start/start.go
index a300f559..c4722f22 100644
--- a/internal/db/start/start.go
+++ b/internal/db/start/start.go
@@ -160,6 +160,14 @@ EOF`}
 	return initCurrentBranch(fsys)
 }
 
+func NewBackoffPolicy(ctx context.Context, timeout time.Duration) backoff.BackOff {
+	policy := backoff.WithMaxRetries(
+		backoff.NewConstantBackOff(time.Second),
+		uint64(timeout.Seconds()),
+	)
+	return backoff.WithContext(policy, ctx)
+}
+
 func WaitForHealthyService(ctx context.Context, timeout time.Duration, started ...string) error {
 	probe := func() error {
 		var errHealth []error
@@ -173,10 +181,7 @@ func WaitForHealthyService(ctx context.Context, timeout time.Duration, started .
 		started = unhealthy
 		return errors.Join(errHealth...)
 	}
-	policy := backoff.WithContext(backoff.WithMaxRetries(
-		backoff.NewConstantBackOff(time.Second),
-		uint64(timeout.Seconds()),
-	), ctx)
+	policy := NewBackoffPolicy(ctx, timeout)
 	err := backoff.Retry(probe, policy)
 	if err != nil && !errors.Is(err, context.Canceled) {
 		// Print container logs for easier debugging
@@ -251,6 +256,7 @@ func initRealtimeJob(host string) utils.DockerJob {
 			"DNS_NODES=''",
 			"RLIMIT_NOFILE=",
 			"SEED_SELF_HOST=true",
+			"RUN_JANITOR=true",
 			fmt.Sprintf("MAX_HEADER_LENGTH=%d", utils.Config.Realtime.MaxHeaderLength),
 		},
 		Cmd: []string{"/app/bin/realtime", "eval", fmt.Sprintf(`{:ok, _} = Application.ensure_all_started(:realtime)
diff --git a/internal/inspect/role_configs/role_configs.sql b/internal/inspect/role_configs/role_configs.sql
index d568d686..fd7f964d 100644
--- a/internal/inspect/role_configs/role_configs.sql
+++ b/internal/inspect/role_configs/role_configs.sql
@@ -2,4 +2,4 @@ select
   rolname as role_name,
   array_to_string(rolconfig, ',', '*') as custom_config
 from
-  pg_roles where rolconfig is not null;
+  pg_roles where rolconfig is not null
diff --git a/internal/link/link.go b/internal/link/link.go
index 9d72302c..e791271b 100644
--- a/internal/link/link.go
+++ b/internal/link/link.go
@@ -6,7 +6,6 @@ import (
 	"net/http"
 	"os"
 	"strconv"
-	"strings"
 	"sync"
 
 	"github.com/go-errors/errors"
@@ -26,15 +25,14 @@ import (
 )
 
 func Run(ctx context.Context, projectRef string, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
-	original, err := cliConfig.ToTomlBytes(map[string]interface{}{
-		"api": utils.Config.Api,
-		"db":  utils.Config.Db,
-	})
+	copy := utils.Config.Clone()
+	copy.Auth.HashSecrets(projectRef)
+	original, err := cliConfig.ToTomlBytes(copy)
 	if err != nil {
 		fmt.Fprintln(utils.GetDebugLogger(), err)
 	}
 
-	if err := checkRemoteProjectStatus(ctx, projectRef); err != nil {
+	if err := checkRemoteProjectStatus(ctx, projectRef, fsys); err != nil {
 		return err
 	}
 
@@ -64,10 +62,7 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs, options ...func(
 	fmt.Fprintln(os.Stdout, "Finished "+utils.Aqua("supabase link")+".")
 
 	// 4. Suggest config update
-	updated, err := cliConfig.ToTomlBytes(map[string]interface{}{
-		"api": utils.Config.Api,
-		"db":  utils.Config.Db,
-	})
+	updated, err := cliConfig.ToTomlBytes(utils.Config.Clone())
 	if err != nil {
 		fmt.Fprintln(utils.GetDebugLogger(), err)
 	}
@@ -82,10 +77,10 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs, options ...func(
 func LinkServices(ctx context.Context, projectRef, anonKey string, fsys afero.Fs) {
 	// Ignore non-fatal errors linking services
 	var wg sync.WaitGroup
-	wg.Add(6)
+	wg.Add(8)
 	go func() {
 		defer wg.Done()
-		if err := linkDatabaseVersion(ctx, projectRef, fsys); err != nil && viper.GetBool("DEBUG") {
+		if err := linkDatabaseSettings(ctx, projectRef); err != nil && viper.GetBool("DEBUG") {
 			fmt.Fprintln(os.Stderr, err)
 		}
 	}()
@@ -95,6 +90,18 @@ func LinkServices(ctx context.Context, projectRef, anonKey string, fsys afero.Fs
 			fmt.Fprintln(os.Stderr, err)
 		}
 	}()
+	go func() {
+		defer wg.Done()
+		if err := linkGotrue(ctx, projectRef); err != nil && viper.GetBool("DEBUG") {
+			fmt.Fprintln(os.Stderr, err)
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		if err := linkStorage(ctx, projectRef); err != nil && viper.GetBool("DEBUG") {
+			fmt.Fprintln(os.Stderr, err)
+		}
+	}()
 	go func() {
 		defer wg.Done()
 		if err := linkPooler(ctx, projectRef, fsys); err != nil && viper.GetBool("DEBUG") {
@@ -126,12 +133,11 @@ func LinkServices(ctx context.Context, projectRef, anonKey string, fsys afero.Fs
 func linkPostgrest(ctx context.Context, projectRef string) error {
 	resp, err := utils.GetSupabase().V1GetPostgrestServiceConfigWithResponse(ctx, projectRef)
 	if err != nil {
-		return errors.Errorf("failed to get postgrest config: %w", err)
-	}
-	if resp.JSON200 == nil {
-		return errors.Errorf("%w: %s", tenant.ErrAuthToken, string(resp.Body))
+		return errors.Errorf("failed to read API config: %w", err)
+	} else if resp.JSON200 == nil {
+		return errors.Errorf("unexpected API config status %d: %s", resp.StatusCode(), string(resp.Body))
 	}
-	updateApiConfig(*resp.JSON200)
+	utils.Config.Api.FromRemoteApiConfig(*resp.JSON200)
 	return nil
 }
 
@@ -143,22 +149,15 @@ func linkPostgrestVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.
 	return utils.WriteFile(utils.RestVersionPath, []byte(version), fsys)
 }
 
-func updateApiConfig(config api.PostgrestConfigWithJWTSecretResponse) {
-	utils.Config.Api.MaxRows = cast.IntToUint(config.MaxRows)
-	utils.Config.Api.ExtraSearchPath = readCsv(config.DbExtraSearchPath)
-	utils.Config.Api.Schemas = readCsv(config.DbSchema)
-}
-
-func readCsv(line string) []string {
-	var result []string
-	tokens := strings.Split(line, ",")
-	for _, t := range tokens {
-		trimmed := strings.TrimSpace(t)
-		if len(trimmed) > 0 {
-			result = append(result, trimmed)
-		}
+func linkGotrue(ctx context.Context, projectRef string) error {
+	resp, err := utils.GetSupabase().V1GetAuthServiceConfigWithResponse(ctx, projectRef)
+	if err != nil {
+		return errors.Errorf("failed to read Auth config: %w", err)
+	} else if resp.JSON200 == nil {
+		return errors.Errorf("unexpected Auth config status %d: %s", resp.StatusCode(), string(resp.Body))
 	}
-	return result
+	utils.Config.Auth.FromRemoteAuthConfig(*resp.JSON200)
+	return nil
 }
 
 func linkGotrueVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs) error {
@@ -169,6 +168,17 @@ func linkGotrueVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs)
 	return utils.WriteFile(utils.GotrueVersionPath, []byte(version), fsys)
 }
 
+func linkStorage(ctx context.Context, projectRef string) error {
+	resp, err := utils.GetSupabase().V1GetStorageConfigWithResponse(ctx, projectRef)
+	if err != nil {
+		return errors.Errorf("failed to read Storage config: %w", err)
+	} else if resp.JSON200 == nil {
+		return errors.Errorf("unexpected Storage config status %d: %s", resp.StatusCode(), string(resp.Body))
+	}
+	utils.Config.Storage.FromRemoteStorageConfig(*resp.JSON200)
+	return nil
+}
+
 func linkStorageVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs) error {
 	version, err := api.GetStorageVersion(ctx)
 	if err != nil {
@@ -177,6 +187,17 @@ func linkStorageVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs
 	return utils.WriteFile(utils.StorageVersionPath, []byte(version), fsys)
 }
 
+func linkDatabaseSettings(ctx context.Context, projectRef string) error {
+	resp, err := utils.GetSupabase().V1GetPostgresConfigWithResponse(ctx, projectRef)
+	if err != nil {
+		return errors.Errorf("failed to read DB config: %w", err)
+	} else if resp.JSON200 == nil {
+		return errors.Errorf("unexpected DB config status %d: %s", resp.StatusCode(), string(resp.Body))
+	}
+	utils.Config.Db.Settings.FromRemotePostgresConfig(*resp.JSON200)
+	return nil
+}
+
 func linkDatabase(ctx context.Context, config pgconn.Config, options ...func(*pgx.ConnConfig)) error {
 	conn, err := utils.ConnectByConfig(ctx, config, options...)
 	if err != nil {
@@ -191,14 +212,6 @@ func linkDatabase(ctx context.Context, config pgconn.Config, options ...func(*pg
 	return migration.CreateSeedTable(ctx, conn)
 }
 
-func linkDatabaseVersion(ctx context.Context, projectRef string, fsys afero.Fs) error {
-	version, err := tenant.GetDatabaseVersion(ctx, projectRef)
-	if err != nil {
-		return err
-	}
-	return utils.WriteFile(utils.PostgresVersionPath, []byte(version), fsys)
-}
-
 func updatePostgresConfig(conn *pgx.Conn) {
 	serverVersion := conn.PgConn().ParameterStatus("server_version")
 	// Safe to assume that supported Postgres version is 10.0 <= n < 100.0
@@ -241,7 +254,7 @@ func updatePoolerConfig(config api.SupavisorConfigResponse) {
 
 var errProjectPaused = errors.New("project is paused")
 
-func checkRemoteProjectStatus(ctx context.Context, projectRef string) error {
+func checkRemoteProjectStatus(ctx context.Context, projectRef string, fsys afero.Fs) error {
 	resp, err := utils.GetSupabase().V1GetProjectWithResponse(ctx, projectRef)
 	if err != nil {
 		return errors.Errorf("failed to retrieve remote project status: %w", err)
@@ -257,14 +270,18 @@ func checkRemoteProjectStatus(ctx context.Context, projectRef string) error {
 	}
 
 	switch resp.JSON200.Status {
-	case api.V1ProjectResponseStatusINACTIVE:
+	case api.V1ProjectWithDatabaseResponseStatusINACTIVE:
 		utils.CmdSuggestion = fmt.Sprintf("An admin must unpause it from the Supabase dashboard at %s", utils.Aqua(fmt.Sprintf("%s/project/%s", utils.GetSupabaseDashboardURL(), projectRef)))
 		return errors.New(errProjectPaused)
-	case api.V1ProjectResponseStatusACTIVEHEALTHY:
+	case api.V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY:
 		// Project is in the desired state, do nothing
 	default:
 		fmt.Fprintf(os.Stderr, "%s: Project status is %s instead of Active Healthy. Some operations might fail.\n", utils.Yellow("WARNING"), resp.JSON200.Status)
 	}
 
+	// Update postgres image version to match the remote project
+	if version := resp.JSON200.Database.Version; len(version) > 0 {
+		return utils.WriteFile(utils.PostgresVersionPath, []byte(version), fsys)
+	}
 	return nil
 }
diff --git a/internal/projects/apiKeys/api_keys.go b/internal/projects/apiKeys/api_keys.go
index 4fcbfe06..7daddce2 100644
--- a/internal/projects/apiKeys/api_keys.go
+++ b/internal/projects/apiKeys/api_keys.go
@@ -34,7 +34,7 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error {
 }
 
 func RunGetApiKeys(ctx context.Context, projectRef string) ([]api.ApiKeyResponse, error) {
-	resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef)
+	resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef, &api.V1GetProjectApiKeysParams{})
 	if err != nil {
 		return nil, errors.Errorf("failed to get api keys: %w", err)
 	}
diff --git a/internal/projects/create/create.go b/internal/projects/create/create.go
index 01ebf630..ddbd46b4 100644
--- a/internal/projects/create/create.go
+++ b/internal/projects/create/create.go
@@ -15,7 +15,7 @@ import (
 	"github.com/supabase/cli/pkg/api"
 )
 
-func Run(ctx context.Context, params api.V1CreateProjectBody, fsys afero.Fs) error {
+func Run(ctx context.Context, params api.V1CreateProjectBodyDto, fsys afero.Fs) error {
 	if err := promptMissingParams(ctx, &params); err != nil {
 		return err
 	}
@@ -49,7 +49,7 @@ func printKeyValue(key, value string) string {
 	return key + ":" + spaces + value
 }
 
-func promptMissingParams(ctx context.Context, body *api.V1CreateProjectBody) error {
+func promptMissingParams(ctx context.Context, body *api.V1CreateProjectBodyDto) error {
 	var err error
 	if len(body.Name) == 0 {
 		if body.Name, err = promptProjectName(ctx); err != nil {
@@ -106,7 +106,7 @@ func promptOrgId(ctx context.Context) (string, error) {
 	return choice.Details, nil
 }
 
-func promptProjectRegion(ctx context.Context) (api.V1CreateProjectBodyRegion, error) {
+func promptProjectRegion(ctx context.Context) (api.V1CreateProjectBodyDtoRegion, error) {
 	title := "Which region do you want to host the project in?"
 	items := make([]utils.PromptItem, len(utils.RegionMap))
 	i := 0
@@ -118,5 +118,5 @@ func promptProjectRegion(ctx context.Context) (api.V1CreateProjectBodyRegion, er
 	if err != nil {
 		return "", err
 	}
-	return api.V1CreateProjectBodyRegion(choice.Summary), nil
+	return api.V1CreateProjectBodyDtoRegion(choice.Summary), nil
 }
diff --git a/internal/projects/list/list.go b/internal/projects/list/list.go
index b16b6d4f..d211f71e 100644
--- a/internal/projects/list/list.go
+++ b/internal/projects/list/list.go
@@ -15,8 +15,8 @@ import (
 )
 
 type linkedProject struct {
-	api.V1ProjectResponse `yaml:",inline"`
-	Linked                bool `json:"linked"`
+	api.V1ProjectWithDatabaseResponse `yaml:",inline"`
+	Linked                            bool `json:"linked"`
 }
 
 func Run(ctx context.Context, fsys afero.Fs) error {
@@ -37,8 +37,8 @@ func Run(ctx context.Context, fsys afero.Fs) error {
 	var projects []linkedProject
 	for _, project := range *resp.JSON200 {
 		projects = append(projects, linkedProject{
-			V1ProjectResponse: project,
-			Linked:            project.Id == projectRef,
+			V1ProjectWithDatabaseResponse: project,
+			Linked:                        project.Id == projectRef,
 		})
 	}
 
diff --git a/internal/start/start.go b/internal/start/start.go
index bdb0989a..5521161f 100644
--- a/internal/start/start.go
+++ b/internal/start/start.go
@@ -506,6 +506,8 @@ EOF
 			fmt.Sprintf("GOTRUE_SMS_TEMPLATE=%v", utils.Config.Auth.Sms.Template),
 			"GOTRUE_SMS_TEST_OTP=" + testOTP.String(),
 
+			fmt.Sprintf("GOTRUE_PASSWORD_MIN_LENGTH=%v", utils.Config.Auth.MinimumPasswordLength),
+			fmt.Sprintf("GOTRUE_PASSWORD_REQUIRED_CHARACTERS=%v", utils.Config.Auth.PasswordRequirements.ToChar()),
 			fmt.Sprintf("GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED=%v", utils.Config.Auth.EnableRefreshTokenRotation),
 			fmt.Sprintf("GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL=%v", utils.Config.Auth.RefreshTokenReuseInterval),
 			fmt.Sprintf("GOTRUE_SECURITY_MANUAL_LINKING_ENABLED=%v", utils.Config.Auth.EnableManualLinking),
@@ -532,7 +534,8 @@ EOF
 			env = append(env,
 				"GOTRUE_SMTP_HOST="+utils.InbucketId,
 				"GOTRUE_SMTP_PORT=2500",
-				"GOTRUE_SMTP_ADMIN_EMAIL=admin@email.com",
+				fmt.Sprintf("GOTRUE_SMTP_ADMIN_EMAIL=%s", utils.Config.Inbucket.AdminEmail),
+				fmt.Sprintf("GOTRUE_SMTP_SENDER_NAME=%s", utils.Config.Inbucket.SenderName),
 			)
 		}
 
@@ -765,6 +768,7 @@ EOF
 					"DNS_NODES=''",
 					"RLIMIT_NOFILE=",
 					"SEED_SELF_HOST=true",
+					"RUN_JANITOR=true",
 					fmt.Sprintf("MAX_HEADER_LENGTH=%d", utils.Config.Realtime.MaxHeaderLength),
 				},
 				ExposedPorts: nat.PortSet{"4000/tcp": {}},
@@ -1055,6 +1059,7 @@ EOF
 					"API_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
 					"METRICS_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
 					"REGION=local",
+					"RUN_JANITOR=true",
 					"ERL_AFLAGS=-proto_dist inet_tcp",
 				},
 				Cmd: []string{
diff --git a/internal/utils/misc.go b/internal/utils/misc.go
index 0993ae80..202d80d0 100644
--- a/internal/utils/misc.go
+++ b/internal/utils/misc.go
@@ -31,17 +31,7 @@ func ShortContainerImageName(imageName string) string {
 	return matches[1]
 }
 
-const (
-	// https://dba.stackexchange.com/a/11895
-	// Args: dbname
-	TerminateDbSqlFmt = `
-SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '%[1]s';
--- Wait for WAL sender to drop replication slot.
-DO 'BEGIN WHILE (
-	SELECT COUNT(*) FROM pg_replication_slots WHERE database = ''%[1]s''
-) > 0 LOOP END LOOP; END';`
-	SuggestDebugFlag = "Try rerunning the command with --debug to troubleshoot the error."
-)
+const SuggestDebugFlag = "Try rerunning the command with --debug to troubleshoot the error."
 
 var (
 	CmdSuggestion string
diff --git a/internal/utils/tenant/client.go b/internal/utils/tenant/client.go
index 9fc86a67..ad0ef6aa 100644
--- a/internal/utils/tenant/client.go
+++ b/internal/utils/tenant/client.go
@@ -39,7 +39,7 @@ func NewApiKey(resp []api.ApiKeyResponse) ApiKey {
 }
 
 func GetApiKeys(ctx context.Context, projectRef string) (ApiKey, error) {
-	resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef)
+	resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef, &api.V1GetProjectApiKeysParams{})
 	if err != nil {
 		return ApiKey{}, errors.Errorf("failed to get api keys: %w", err)
 	}
diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go
index 05ed7670..fcbe8eae 100644
--- a/pkg/api/client.gen.go
+++ b/pkg/api/client.gen.go
@@ -140,20 +140,23 @@ type ClientInterface interface {
 	V1GetProject(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	// V1GetProjectApiKeys request
-	V1GetProjectApiKeys(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error)
+	V1GetProjectApiKeys(ctx context.Context, ref string, params *V1GetProjectApiKeysParams, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	// CreateApiKeyWithBody request with any body
-	CreateApiKeyWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
+	CreateApiKeyWithBody(ctx context.Context, ref string, params *CreateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
 
-	CreateApiKey(ctx context.Context, ref string, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
+	CreateApiKey(ctx context.Context, ref string, params *CreateApiKeyParams, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	// DeleteApiKey request
-	DeleteApiKey(ctx context.Context, ref string, id string, reqEditors ...RequestEditorFn) (*http.Response, error)
+	DeleteApiKey(ctx context.Context, ref string, id string, params *DeleteApiKeyParams, reqEditors ...RequestEditorFn) (*http.Response, error)
+
+	// GetApiKey request
+	GetApiKey(ctx context.Context, ref string, id string, params *GetApiKeyParams, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	// UpdateApiKeyWithBody request with any body
-	UpdateApiKeyWithBody(ctx context.Context, ref string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
+	UpdateApiKeyWithBody(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
 
-	UpdateApiKey(ctx context.Context, ref string, id string, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
+	UpdateApiKey(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	// V1DisablePreviewBranching request
 	V1DisablePreviewBranching(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error)
@@ -617,8 +620,20 @@ func (c *Client) V1GetProject(ctx context.Context, ref string, reqEditors ...Req
 	return c.Client.Do(req)
 }
 
-func (c *Client) V1GetProjectApiKeys(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewV1GetProjectApiKeysRequest(c.Server, ref)
+func (c *Client) V1GetProjectApiKeys(ctx context.Context, ref string, params *V1GetProjectApiKeysParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewV1GetProjectApiKeysRequest(c.Server, ref, params)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	if err := c.applyEditors(ctx, req, reqEditors); err != nil {
+		return nil, err
+	}
+	return c.Client.Do(req)
+}
+
+func (c *Client) CreateApiKeyWithBody(ctx context.Context, ref string, params *CreateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewCreateApiKeyRequestWithBody(c.Server, ref, params, contentType, body)
 	if err != nil {
 		return nil, err
 	}
@@ -629,8 +644,8 @@ func (c *Client) V1GetProjectApiKeys(ctx context.Context, ref string, reqEditors
 	return c.Client.Do(req)
 }
 
-func (c *Client) CreateApiKeyWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewCreateApiKeyRequestWithBody(c.Server, ref, contentType, body)
+func (c *Client) CreateApiKey(ctx context.Context, ref string, params *CreateApiKeyParams, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewCreateApiKeyRequest(c.Server, ref, params, body)
 	if err != nil {
 		return nil, err
 	}
@@ -641,8 +656,8 @@ func (c *Client) CreateApiKeyWithBody(ctx context.Context, ref string, contentTy
 	return c.Client.Do(req)
 }
 
-func (c *Client) CreateApiKey(ctx context.Context, ref string, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewCreateApiKeyRequest(c.Server, ref, body)
+func (c *Client) DeleteApiKey(ctx context.Context, ref string, id string, params *DeleteApiKeyParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewDeleteApiKeyRequest(c.Server, ref, id, params)
 	if err != nil {
 		return nil, err
 	}
@@ -653,8 +668,8 @@ func (c *Client) CreateApiKey(ctx context.Context, ref string, body CreateApiKey
 	return c.Client.Do(req)
 }
 
-func (c *Client) DeleteApiKey(ctx context.Context, ref string, id string, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewDeleteApiKeyRequest(c.Server, ref, id)
+func (c *Client) GetApiKey(ctx context.Context, ref string, id string, params *GetApiKeyParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewGetApiKeyRequest(c.Server, ref, id, params)
 	if err != nil {
 		return nil, err
 	}
@@ -665,8 +680,8 @@ func (c *Client) DeleteApiKey(ctx context.Context, ref string, id string, reqEdi
 	return c.Client.Do(req)
 }
 
-func (c *Client) UpdateApiKeyWithBody(ctx context.Context, ref string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewUpdateApiKeyRequestWithBody(c.Server, ref, id, contentType, body)
+func (c *Client) UpdateApiKeyWithBody(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewUpdateApiKeyRequestWithBody(c.Server, ref, id, params, contentType, body)
 	if err != nil {
 		return nil, err
 	}
@@ -677,8 +692,8 @@ func (c *Client) UpdateApiKeyWithBody(ctx context.Context, ref string, id string
 	return c.Client.Do(req)
 }
 
-func (c *Client) UpdateApiKey(ctx context.Context, ref string, id string, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
-	req, err := NewUpdateApiKeyRequest(c.Server, ref, id, body)
+func (c *Client) UpdateApiKey(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewUpdateApiKeyRequest(c.Server, ref, id, params, body)
 	if err != nil {
 		return nil, err
 	}
@@ -2378,7 +2393,7 @@ func NewV1GetProjectRequest(server string, ref string) (*http.Request, error) {
 }
 
 // NewV1GetProjectApiKeysRequest generates requests for V1GetProjectApiKeys
-func NewV1GetProjectApiKeysRequest(server string, ref string) (*http.Request, error) {
+func NewV1GetProjectApiKeysRequest(server string, ref string, params *V1GetProjectApiKeysParams) (*http.Request, error) {
 	var err error
 
 	var pathParam0 string
@@ -2403,6 +2418,24 @@ func NewV1GetProjectApiKeysRequest(server string, ref string) (*http.Request, er
 		return nil, err
 	}
 
+	if params != nil {
+		queryValues := queryURL.Query()
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "reveal", runtime.ParamLocationQuery, params.Reveal); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
+
 	req, err := http.NewRequest("GET", queryURL.String(), nil)
 	if err != nil {
 		return nil, err
@@ -2412,18 +2445,18 @@ func NewV1GetProjectApiKeysRequest(server string, ref string) (*http.Request, er
 }
 
 // NewCreateApiKeyRequest calls the generic CreateApiKey builder with application/json body
-func NewCreateApiKeyRequest(server string, ref string, body CreateApiKeyJSONRequestBody) (*http.Request, error) {
+func NewCreateApiKeyRequest(server string, ref string, params *CreateApiKeyParams, body CreateApiKeyJSONRequestBody) (*http.Request, error) {
 	var bodyReader io.Reader
 	buf, err := json.Marshal(body)
 	if err != nil {
 		return nil, err
 	}
 	bodyReader = bytes.NewReader(buf)
-	return NewCreateApiKeyRequestWithBody(server, ref, "application/json", bodyReader)
+	return NewCreateApiKeyRequestWithBody(server, ref, params, "application/json", bodyReader)
 }
 
 // NewCreateApiKeyRequestWithBody generates requests for CreateApiKey with any type of body
-func NewCreateApiKeyRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) {
+func NewCreateApiKeyRequestWithBody(server string, ref string, params *CreateApiKeyParams, contentType string, body io.Reader) (*http.Request, error) {
 	var err error
 
 	var pathParam0 string
@@ -2448,6 +2481,24 @@ func NewCreateApiKeyRequestWithBody(server string, ref string, contentType strin
 		return nil, err
 	}
 
+	if params != nil {
+		queryValues := queryURL.Query()
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "reveal", runtime.ParamLocationQuery, params.Reveal); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
+
 	req, err := http.NewRequest("POST", queryURL.String(), body)
 	if err != nil {
 		return nil, err
@@ -2459,7 +2510,7 @@ func NewCreateApiKeyRequestWithBody(server string, ref string, contentType strin
 }
 
 // NewDeleteApiKeyRequest generates requests for DeleteApiKey
-func NewDeleteApiKeyRequest(server string, ref string, id string) (*http.Request, error) {
+func NewDeleteApiKeyRequest(server string, ref string, id string, params *DeleteApiKeyParams) (*http.Request, error) {
 	var err error
 
 	var pathParam0 string
@@ -2491,6 +2542,24 @@ func NewDeleteApiKeyRequest(server string, ref string, id string) (*http.Request
 		return nil, err
 	}
 
+	if params != nil {
+		queryValues := queryURL.Query()
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "reveal", runtime.ParamLocationQuery, params.Reveal); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
+
 	req, err := http.NewRequest("DELETE", queryURL.String(), nil)
 	if err != nil {
 		return nil, err
@@ -2499,19 +2568,78 @@ func NewDeleteApiKeyRequest(server string, ref string, id string) (*http.Request
 	return req, nil
 }
 
+// NewGetApiKeyRequest generates requests for GetApiKey
+func NewGetApiKeyRequest(server string, ref string, id string, params *GetApiKeyParams) (*http.Request, error) {
+	var err error
+
+	var pathParam0 string
+
+	pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref)
+	if err != nil {
+		return nil, err
+	}
+
+	var pathParam1 string
+
+	pathParam1, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id)
+	if err != nil {
+		return nil, err
+	}
+
+	serverURL, err := url.Parse(server)
+	if err != nil {
+		return nil, err
+	}
+
+	operationPath := fmt.Sprintf("/v1/projects/%s/api-keys/%s", pathParam0, pathParam1)
+	if operationPath[0] == '/' {
+		operationPath = "." + operationPath
+	}
+
+	queryURL, err := serverURL.Parse(operationPath)
+	if err != nil {
+		return nil, err
+	}
+
+	if params != nil {
+		queryValues := queryURL.Query()
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "reveal", runtime.ParamLocationQuery, params.Reveal); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
+
+	req, err := http.NewRequest("GET", queryURL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return req, nil
+}
+
 // NewUpdateApiKeyRequest calls the generic UpdateApiKey builder with application/json body
-func NewUpdateApiKeyRequest(server string, ref string, id string, body UpdateApiKeyJSONRequestBody) (*http.Request, error) {
+func NewUpdateApiKeyRequest(server string, ref string, id string, params *UpdateApiKeyParams, body UpdateApiKeyJSONRequestBody) (*http.Request, error) {
 	var bodyReader io.Reader
 	buf, err := json.Marshal(body)
 	if err != nil {
 		return nil, err
 	}
 	bodyReader = bytes.NewReader(buf)
-	return NewUpdateApiKeyRequestWithBody(server, ref, id, "application/json", bodyReader)
+	return NewUpdateApiKeyRequestWithBody(server, ref, id, params, "application/json", bodyReader)
 }
 
 // NewUpdateApiKeyRequestWithBody generates requests for UpdateApiKey with any type of body
-func NewUpdateApiKeyRequestWithBody(server string, ref string, id string, contentType string, body io.Reader) (*http.Request, error) {
+func NewUpdateApiKeyRequestWithBody(server string, ref string, id string, params *UpdateApiKeyParams, contentType string, body io.Reader) (*http.Request, error) {
 	var err error
 
 	var pathParam0 string
@@ -2543,6 +2671,24 @@ func NewUpdateApiKeyRequestWithBody(server string, ref string, id string, conten
 		return nil, err
 	}
 
+	if params != nil {
+		queryValues := queryURL.Query()
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "reveal", runtime.ParamLocationQuery, params.Reveal); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
+
 	req, err := http.NewRequest("PATCH", queryURL.String(), body)
 	if err != nil {
 		return nil, err
@@ -3921,6 +4067,22 @@ func NewV1CreateAFunctionRequestWithBody(server string, ref string, params *V1Cr
 
 		}
 
+		if params.ComputeMultiplier != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "compute_multiplier", runtime.ParamLocationQuery, *params.ComputeMultiplier); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
+
 		queryURL.RawQuery = queryValues.Encode()
 	}
 
@@ -4159,6 +4321,22 @@ func NewV1UpdateAFunctionRequestWithBody(server string, ref string, functionSlug
 
 		}
 
+		if params.ComputeMultiplier != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "compute_multiplier", runtime.ParamLocationQuery, *params.ComputeMultiplier); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
+
 		queryURL.RawQuery = queryValues.Encode()
 	}
 
@@ -5542,20 +5720,23 @@ type ClientWithResponsesInterface interface {
 	V1GetProjectWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetProjectResponse, error)
 
 	// V1GetProjectApiKeysWithResponse request
-	V1GetProjectApiKeysWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetProjectApiKeysResponse, error)
+	V1GetProjectApiKeysWithResponse(ctx context.Context, ref string, params *V1GetProjectApiKeysParams, reqEditors ...RequestEditorFn) (*V1GetProjectApiKeysResponse, error)
 
 	// CreateApiKeyWithBodyWithResponse request with any body
-	CreateApiKeyWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error)
+	CreateApiKeyWithBodyWithResponse(ctx context.Context, ref string, params *CreateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error)
 
-	CreateApiKeyWithResponse(ctx context.Context, ref string, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error)
+	CreateApiKeyWithResponse(ctx context.Context, ref string, params *CreateApiKeyParams, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error)
 
 	// DeleteApiKeyWithResponse request
-	DeleteApiKeyWithResponse(ctx context.Context, ref string, id string, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error)
+	DeleteApiKeyWithResponse(ctx context.Context, ref string, id string, params *DeleteApiKeyParams, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error)
+
+	// GetApiKeyWithResponse request
+	GetApiKeyWithResponse(ctx context.Context, ref string, id string, params *GetApiKeyParams, reqEditors ...RequestEditorFn) (*GetApiKeyResponse, error)
 
 	// UpdateApiKeyWithBodyWithResponse request with any body
-	UpdateApiKeyWithBodyWithResponse(ctx context.Context, ref string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error)
+	UpdateApiKeyWithBodyWithResponse(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error)
 
-	UpdateApiKeyWithResponse(ctx context.Context, ref string, id string, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error)
+	UpdateApiKeyWithResponse(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error)
 
 	// V1DisablePreviewBranchingWithResponse request
 	V1DisablePreviewBranchingWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1DisablePreviewBranchingResponse, error)
@@ -6025,7 +6206,7 @@ func (r V1ListOrganizationMembersResponse) StatusCode() int {
 type V1ListAllProjectsResponse struct {
 	Body         []byte
 	HTTPResponse *http.Response
-	JSON200      *[]V1ProjectResponse
+	JSON200      *[]V1ProjectWithDatabaseResponse
 }
 
 // Status returns HTTPResponse.Status
@@ -6091,7 +6272,7 @@ func (r V1DeleteAProjectResponse) StatusCode() int {
 type V1GetProjectResponse struct {
 	Body         []byte
 	HTTPResponse *http.Response
-	JSON200      *V1ProjectResponse
+	JSON200      *V1ProjectWithDatabaseResponse
 }
 
 // Status returns HTTPResponse.Status
@@ -6176,6 +6357,28 @@ func (r DeleteApiKeyResponse) StatusCode() int {
 	return 0
 }
 
+type GetApiKeyResponse struct {
+	Body         []byte
+	HTTPResponse *http.Response
+	JSON200      *ApiKeyResponse
+}
+
+// Status returns HTTPResponse.Status
+func (r GetApiKeyResponse) Status() string {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.Status
+	}
+	return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r GetApiKeyResponse) StatusCode() int {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.StatusCode
+	}
+	return 0
+}
+
 type UpdateApiKeyResponse struct {
 	Body         []byte
 	HTTPResponse *http.Response
@@ -7774,8 +7977,8 @@ func (c *ClientWithResponses) V1GetProjectWithResponse(ctx context.Context, ref
 }
 
 // V1GetProjectApiKeysWithResponse request returning *V1GetProjectApiKeysResponse
-func (c *ClientWithResponses) V1GetProjectApiKeysWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetProjectApiKeysResponse, error) {
-	rsp, err := c.V1GetProjectApiKeys(ctx, ref, reqEditors...)
+func (c *ClientWithResponses) V1GetProjectApiKeysWithResponse(ctx context.Context, ref string, params *V1GetProjectApiKeysParams, reqEditors ...RequestEditorFn) (*V1GetProjectApiKeysResponse, error) {
+	rsp, err := c.V1GetProjectApiKeys(ctx, ref, params, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
@@ -7783,16 +7986,16 @@ func (c *ClientWithResponses) V1GetProjectApiKeysWithResponse(ctx context.Contex
 }
 
 // CreateApiKeyWithBodyWithResponse request with arbitrary body returning *CreateApiKeyResponse
-func (c *ClientWithResponses) CreateApiKeyWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) {
-	rsp, err := c.CreateApiKeyWithBody(ctx, ref, contentType, body, reqEditors...)
+func (c *ClientWithResponses) CreateApiKeyWithBodyWithResponse(ctx context.Context, ref string, params *CreateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) {
+	rsp, err := c.CreateApiKeyWithBody(ctx, ref, params, contentType, body, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
 	return ParseCreateApiKeyResponse(rsp)
 }
 
-func (c *ClientWithResponses) CreateApiKeyWithResponse(ctx context.Context, ref string, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) {
-	rsp, err := c.CreateApiKey(ctx, ref, body, reqEditors...)
+func (c *ClientWithResponses) CreateApiKeyWithResponse(ctx context.Context, ref string, params *CreateApiKeyParams, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) {
+	rsp, err := c.CreateApiKey(ctx, ref, params, body, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
@@ -7800,25 +8003,34 @@ func (c *ClientWithResponses) CreateApiKeyWithResponse(ctx context.Context, ref
 }
 
 // DeleteApiKeyWithResponse request returning *DeleteApiKeyResponse
-func (c *ClientWithResponses) DeleteApiKeyWithResponse(ctx context.Context, ref string, id string, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error) {
-	rsp, err := c.DeleteApiKey(ctx, ref, id, reqEditors...)
+func (c *ClientWithResponses) DeleteApiKeyWithResponse(ctx context.Context, ref string, id string, params *DeleteApiKeyParams, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error) {
+	rsp, err := c.DeleteApiKey(ctx, ref, id, params, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
 	return ParseDeleteApiKeyResponse(rsp)
 }
 
+// GetApiKeyWithResponse request returning *GetApiKeyResponse
+func (c *ClientWithResponses) GetApiKeyWithResponse(ctx context.Context, ref string, id string, params *GetApiKeyParams, reqEditors ...RequestEditorFn) (*GetApiKeyResponse, error) {
+	rsp, err := c.GetApiKey(ctx, ref, id, params, reqEditors...)
+	if err != nil {
+		return nil, err
+	}
+	return ParseGetApiKeyResponse(rsp)
+}
+
 // UpdateApiKeyWithBodyWithResponse request with arbitrary body returning *UpdateApiKeyResponse
-func (c *ClientWithResponses) UpdateApiKeyWithBodyWithResponse(ctx context.Context, ref string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) {
-	rsp, err := c.UpdateApiKeyWithBody(ctx, ref, id, contentType, body, reqEditors...)
+func (c *ClientWithResponses) UpdateApiKeyWithBodyWithResponse(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) {
+	rsp, err := c.UpdateApiKeyWithBody(ctx, ref, id, params, contentType, body, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
 	return ParseUpdateApiKeyResponse(rsp)
 }
 
-func (c *ClientWithResponses) UpdateApiKeyWithResponse(ctx context.Context, ref string, id string, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) {
-	rsp, err := c.UpdateApiKey(ctx, ref, id, body, reqEditors...)
+func (c *ClientWithResponses) UpdateApiKeyWithResponse(ctx context.Context, ref string, id string, params *UpdateApiKeyParams, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) {
+	rsp, err := c.UpdateApiKey(ctx, ref, id, params, body, reqEditors...)
 	if err != nil {
 		return nil, err
 	}
@@ -8875,7 +9087,7 @@ func ParseV1ListAllProjectsResponse(rsp *http.Response) (*V1ListAllProjectsRespo
 
 	switch {
 	case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
-		var dest []V1ProjectResponse
+		var dest []V1ProjectWithDatabaseResponse
 		if err := json.Unmarshal(bodyBytes, &dest); err != nil {
 			return nil, err
 		}
@@ -8953,7 +9165,7 @@ func ParseV1GetProjectResponse(rsp *http.Response) (*V1GetProjectResponse, error
 
 	switch {
 	case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
-		var dest V1ProjectResponse
+		var dest V1ProjectWithDatabaseResponse
 		if err := json.Unmarshal(bodyBytes, &dest); err != nil {
 			return nil, err
 		}
@@ -9042,6 +9254,32 @@ func ParseDeleteApiKeyResponse(rsp *http.Response) (*DeleteApiKeyResponse, error
 	return response, nil
 }
 
+// ParseGetApiKeyResponse parses an HTTP response from a GetApiKeyWithResponse call
+func ParseGetApiKeyResponse(rsp *http.Response) (*GetApiKeyResponse, error) {
+	bodyBytes, err := io.ReadAll(rsp.Body)
+	defer func() { _ = rsp.Body.Close() }()
+	if err != nil {
+		return nil, err
+	}
+
+	response := &GetApiKeyResponse{
+		Body:         bodyBytes,
+		HTTPResponse: rsp,
+	}
+
+	switch {
+	case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
+		var dest ApiKeyResponse
+		if err := json.Unmarshal(bodyBytes, &dest); err != nil {
+			return nil, err
+		}
+		response.JSON200 = &dest
+
+	}
+
+	return response, nil
+}
+
 // ParseUpdateApiKeyResponse parses an HTTP response from a UpdateApiKeyWithResponse call
 func ParseUpdateApiKeyResponse(rsp *http.Response) (*UpdateApiKeyResponse, error) {
 	bodyBytes, err := io.ReadAll(rsp.Body)
diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go
index 9334b80b..4cfa1556 100644
--- a/pkg/api/types.gen.go
+++ b/pkg/api/types.gen.go
@@ -111,16 +111,16 @@ const (
 
 // Defines values for DesiredInstanceSize.
 const (
-	Large     DesiredInstanceSize = "large"
-	Medium    DesiredInstanceSize = "medium"
-	Micro     DesiredInstanceSize = "micro"
-	N12xlarge DesiredInstanceSize = "12xlarge"
-	N16xlarge DesiredInstanceSize = "16xlarge"
-	N2xlarge  DesiredInstanceSize = "2xlarge"
-	N4xlarge  DesiredInstanceSize = "4xlarge"
-	N8xlarge  DesiredInstanceSize = "8xlarge"
-	Small     DesiredInstanceSize = "small"
-	Xlarge    DesiredInstanceSize = "xlarge"
+	DesiredInstanceSizeLarge     DesiredInstanceSize = "large"
+	DesiredInstanceSizeMedium    DesiredInstanceSize = "medium"
+	DesiredInstanceSizeMicro     DesiredInstanceSize = "micro"
+	DesiredInstanceSizeN12xlarge DesiredInstanceSize = "12xlarge"
+	DesiredInstanceSizeN16xlarge DesiredInstanceSize = "16xlarge"
+	DesiredInstanceSizeN2xlarge  DesiredInstanceSize = "2xlarge"
+	DesiredInstanceSizeN4xlarge  DesiredInstanceSize = "4xlarge"
+	DesiredInstanceSizeN8xlarge  DesiredInstanceSize = "8xlarge"
+	DesiredInstanceSizeSmall     DesiredInstanceSize = "small"
+	DesiredInstanceSizeXlarge    DesiredInstanceSize = "xlarge"
 )
 
 // Defines values for FunctionResponseStatus.
@@ -169,16 +169,16 @@ const (
 
 // Defines values for PostgresEngine.
 const (
-	N15 PostgresEngine = "15"
+	PostgresEngineN15 PostgresEngine = "15"
 )
 
 // Defines values for ReleaseChannel.
 const (
-	Alpha     ReleaseChannel = "alpha"
-	Beta      ReleaseChannel = "beta"
-	Ga        ReleaseChannel = "ga"
-	Internal  ReleaseChannel = "internal"
-	Withdrawn ReleaseChannel = "withdrawn"
+	ReleaseChannelAlpha     ReleaseChannel = "alpha"
+	ReleaseChannelBeta      ReleaseChannel = "beta"
+	ReleaseChannelGa        ReleaseChannel = "ga"
+	ReleaseChannelInternal  ReleaseChannel = "internal"
+	ReleaseChannelWithdrawn ReleaseChannel = "withdrawn"
 )
 
 // Defines values for SetUpReadReplicaBodyReadReplicaRegion.
@@ -297,32 +297,60 @@ const (
 	V1BackupStatusREMOVED   V1BackupStatus = "REMOVED"
 )
 
-// Defines values for V1CreateProjectBodyPlan.
+// Defines values for V1CreateProjectBodyDtoDesiredInstanceSize.
 const (
-	V1CreateProjectBodyPlanFree V1CreateProjectBodyPlan = "free"
-	V1CreateProjectBodyPlanPro  V1CreateProjectBodyPlan = "pro"
+	V1CreateProjectBodyDtoDesiredInstanceSizeLarge     V1CreateProjectBodyDtoDesiredInstanceSize = "large"
+	V1CreateProjectBodyDtoDesiredInstanceSizeMedium    V1CreateProjectBodyDtoDesiredInstanceSize = "medium"
+	V1CreateProjectBodyDtoDesiredInstanceSizeMicro     V1CreateProjectBodyDtoDesiredInstanceSize = "micro"
+	V1CreateProjectBodyDtoDesiredInstanceSizeN12xlarge V1CreateProjectBodyDtoDesiredInstanceSize = "12xlarge"
+	V1CreateProjectBodyDtoDesiredInstanceSizeN16xlarge V1CreateProjectBodyDtoDesiredInstanceSize = "16xlarge"
+	V1CreateProjectBodyDtoDesiredInstanceSizeN2xlarge  V1CreateProjectBodyDtoDesiredInstanceSize = "2xlarge"
+	V1CreateProjectBodyDtoDesiredInstanceSizeN4xlarge  V1CreateProjectBodyDtoDesiredInstanceSize = "4xlarge"
+	V1CreateProjectBodyDtoDesiredInstanceSizeN8xlarge  V1CreateProjectBodyDtoDesiredInstanceSize = "8xlarge"
+	V1CreateProjectBodyDtoDesiredInstanceSizeSmall     V1CreateProjectBodyDtoDesiredInstanceSize = "small"
+	V1CreateProjectBodyDtoDesiredInstanceSizeXlarge    V1CreateProjectBodyDtoDesiredInstanceSize = "xlarge"
 )
 
-// Defines values for V1CreateProjectBodyRegion.
+// Defines values for V1CreateProjectBodyDtoPlan.
 const (
-	V1CreateProjectBodyRegionApEast1      V1CreateProjectBodyRegion = "ap-east-1"
-	V1CreateProjectBodyRegionApNortheast1 V1CreateProjectBodyRegion = "ap-northeast-1"
-	V1CreateProjectBodyRegionApNortheast2 V1CreateProjectBodyRegion = "ap-northeast-2"
-	V1CreateProjectBodyRegionApSouth1     V1CreateProjectBodyRegion = "ap-south-1"
-	V1CreateProjectBodyRegionApSoutheast1 V1CreateProjectBodyRegion = "ap-southeast-1"
-	V1CreateProjectBodyRegionApSoutheast2 V1CreateProjectBodyRegion = "ap-southeast-2"
-	V1CreateProjectBodyRegionCaCentral1   V1CreateProjectBodyRegion = "ca-central-1"
-	V1CreateProjectBodyRegionEuCentral1   V1CreateProjectBodyRegion = "eu-central-1"
-	V1CreateProjectBodyRegionEuCentral2   V1CreateProjectBodyRegion = "eu-central-2"
-	V1CreateProjectBodyRegionEuNorth1     V1CreateProjectBodyRegion = "eu-north-1"
-	V1CreateProjectBodyRegionEuWest1      V1CreateProjectBodyRegion = "eu-west-1"
-	V1CreateProjectBodyRegionEuWest2      V1CreateProjectBodyRegion = "eu-west-2"
-	V1CreateProjectBodyRegionEuWest3      V1CreateProjectBodyRegion = "eu-west-3"
-	V1CreateProjectBodyRegionSaEast1      V1CreateProjectBodyRegion = "sa-east-1"
-	V1CreateProjectBodyRegionUsEast1      V1CreateProjectBodyRegion = "us-east-1"
-	V1CreateProjectBodyRegionUsEast2      V1CreateProjectBodyRegion = "us-east-2"
-	V1CreateProjectBodyRegionUsWest1      V1CreateProjectBodyRegion = "us-west-1"
-	V1CreateProjectBodyRegionUsWest2      V1CreateProjectBodyRegion = "us-west-2"
+	V1CreateProjectBodyDtoPlanFree V1CreateProjectBodyDtoPlan = "free"
+	V1CreateProjectBodyDtoPlanPro  V1CreateProjectBodyDtoPlan = "pro"
+)
+
+// Defines values for V1CreateProjectBodyDtoPostgresEngine.
+const (
+	V1CreateProjectBodyDtoPostgresEngineN15 V1CreateProjectBodyDtoPostgresEngine = "15"
+)
+
+// Defines values for V1CreateProjectBodyDtoRegion.
+const (
+	V1CreateProjectBodyDtoRegionApEast1      V1CreateProjectBodyDtoRegion = "ap-east-1"
+	V1CreateProjectBodyDtoRegionApNortheast1 V1CreateProjectBodyDtoRegion = "ap-northeast-1"
+	V1CreateProjectBodyDtoRegionApNortheast2 V1CreateProjectBodyDtoRegion = "ap-northeast-2"
+	V1CreateProjectBodyDtoRegionApSouth1     V1CreateProjectBodyDtoRegion = "ap-south-1"
+	V1CreateProjectBodyDtoRegionApSoutheast1 V1CreateProjectBodyDtoRegion = "ap-southeast-1"
+	V1CreateProjectBodyDtoRegionApSoutheast2 V1CreateProjectBodyDtoRegion = "ap-southeast-2"
+	V1CreateProjectBodyDtoRegionCaCentral1   V1CreateProjectBodyDtoRegion = "ca-central-1"
+	V1CreateProjectBodyDtoRegionEuCentral1   V1CreateProjectBodyDtoRegion = "eu-central-1"
+	V1CreateProjectBodyDtoRegionEuCentral2   V1CreateProjectBodyDtoRegion = "eu-central-2"
+	V1CreateProjectBodyDtoRegionEuNorth1     V1CreateProjectBodyDtoRegion = "eu-north-1"
+	V1CreateProjectBodyDtoRegionEuWest1      V1CreateProjectBodyDtoRegion = "eu-west-1"
+	V1CreateProjectBodyDtoRegionEuWest2      V1CreateProjectBodyDtoRegion = "eu-west-2"
+	V1CreateProjectBodyDtoRegionEuWest3      V1CreateProjectBodyDtoRegion = "eu-west-3"
+	V1CreateProjectBodyDtoRegionSaEast1      V1CreateProjectBodyDtoRegion = "sa-east-1"
+	V1CreateProjectBodyDtoRegionUsEast1      V1CreateProjectBodyDtoRegion = "us-east-1"
+	V1CreateProjectBodyDtoRegionUsEast2      V1CreateProjectBodyDtoRegion = "us-east-2"
+	V1CreateProjectBodyDtoRegionUsWest1      V1CreateProjectBodyDtoRegion = "us-west-1"
+	V1CreateProjectBodyDtoRegionUsWest2      V1CreateProjectBodyDtoRegion = "us-west-2"
+)
+
+// Defines values for V1CreateProjectBodyDtoReleaseChannel.
+const (
+	V1CreateProjectBodyDtoReleaseChannelAlpha     V1CreateProjectBodyDtoReleaseChannel = "alpha"
+	V1CreateProjectBodyDtoReleaseChannelBeta      V1CreateProjectBodyDtoReleaseChannel = "beta"
+	V1CreateProjectBodyDtoReleaseChannelGa        V1CreateProjectBodyDtoReleaseChannel = "ga"
+	V1CreateProjectBodyDtoReleaseChannelInternal  V1CreateProjectBodyDtoReleaseChannel = "internal"
+	V1CreateProjectBodyDtoReleaseChannelWithdrawn V1CreateProjectBodyDtoReleaseChannel = "withdrawn"
 )
 
 // Defines values for V1OrganizationSlugResponseOptInTags.
@@ -356,6 +384,25 @@ const (
 	V1ProjectResponseStatusUPGRADING       V1ProjectResponseStatus = "UPGRADING"
 )
 
+// Defines values for V1ProjectWithDatabaseResponseStatus.
+const (
+	V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY   V1ProjectWithDatabaseResponseStatus = "ACTIVE_HEALTHY"
+	V1ProjectWithDatabaseResponseStatusACTIVEUNHEALTHY V1ProjectWithDatabaseResponseStatus = "ACTIVE_UNHEALTHY"
+	V1ProjectWithDatabaseResponseStatusCOMINGUP        V1ProjectWithDatabaseResponseStatus = "COMING_UP"
+	V1ProjectWithDatabaseResponseStatusGOINGDOWN       V1ProjectWithDatabaseResponseStatus = "GOING_DOWN"
+	V1ProjectWithDatabaseResponseStatusINACTIVE        V1ProjectWithDatabaseResponseStatus = "INACTIVE"
+	V1ProjectWithDatabaseResponseStatusINITFAILED      V1ProjectWithDatabaseResponseStatus = "INIT_FAILED"
+	V1ProjectWithDatabaseResponseStatusPAUSEFAILED     V1ProjectWithDatabaseResponseStatus = "PAUSE_FAILED"
+	V1ProjectWithDatabaseResponseStatusPAUSING         V1ProjectWithDatabaseResponseStatus = "PAUSING"
+	V1ProjectWithDatabaseResponseStatusREMOVED         V1ProjectWithDatabaseResponseStatus = "REMOVED"
+	V1ProjectWithDatabaseResponseStatusRESIZING        V1ProjectWithDatabaseResponseStatus = "RESIZING"
+	V1ProjectWithDatabaseResponseStatusRESTARTING      V1ProjectWithDatabaseResponseStatus = "RESTARTING"
+	V1ProjectWithDatabaseResponseStatusRESTOREFAILED   V1ProjectWithDatabaseResponseStatus = "RESTORE_FAILED"
+	V1ProjectWithDatabaseResponseStatusRESTORING       V1ProjectWithDatabaseResponseStatus = "RESTORING"
+	V1ProjectWithDatabaseResponseStatusUNKNOWN         V1ProjectWithDatabaseResponseStatus = "UNKNOWN"
+	V1ProjectWithDatabaseResponseStatusUPGRADING       V1ProjectWithDatabaseResponseStatus = "UPGRADING"
+)
+
 // Defines values for V1ServiceHealthResponseName.
 const (
 	V1ServiceHealthResponseNameAuth     V1ServiceHealthResponseName = "auth"
@@ -368,9 +415,9 @@ const (
 
 // Defines values for V1ServiceHealthResponseStatus.
 const (
-	V1ServiceHealthResponseStatusACTIVEHEALTHY V1ServiceHealthResponseStatus = "ACTIVE_HEALTHY"
-	V1ServiceHealthResponseStatusCOMINGUP      V1ServiceHealthResponseStatus = "COMING_UP"
-	V1ServiceHealthResponseStatusUNHEALTHY     V1ServiceHealthResponseStatus = "UNHEALTHY"
+	ACTIVEHEALTHY V1ServiceHealthResponseStatus = "ACTIVE_HEALTHY"
+	COMINGUP      V1ServiceHealthResponseStatus = "COMING_UP"
+	UNHEALTHY     V1ServiceHealthResponseStatus = "UNHEALTHY"
 )
 
 // Defines values for VanitySubdomainConfigResponseStatus.
@@ -725,8 +772,8 @@ type CreateBranchBody struct {
 	ReleaseChannel *ReleaseChannel `json:"release_channel,omitempty"`
 }
 
-// CreateOrganizationBodyV1 defines model for CreateOrganizationBodyV1.
-type CreateOrganizationBodyV1 struct {
+// CreateOrganizationV1Dto defines model for CreateOrganizationV1Dto.
+type CreateOrganizationV1Dto struct {
 	Name string `json:"name"`
 }
 
@@ -824,17 +871,18 @@ type Domain struct {
 
 // FunctionResponse defines model for FunctionResponse.
 type FunctionResponse struct {
-	CreatedAt      int64                  `json:"created_at"`
-	EntrypointPath *string                `json:"entrypoint_path,omitempty"`
-	Id             string                 `json:"id"`
-	ImportMap      *bool                  `json:"import_map,omitempty"`
-	ImportMapPath  *string                `json:"import_map_path,omitempty"`
-	Name           string                 `json:"name"`
-	Slug           string                 `json:"slug"`
-	Status         FunctionResponseStatus `json:"status"`
-	UpdatedAt      int64                  `json:"updated_at"`
-	VerifyJwt      *bool                  `json:"verify_jwt,omitempty"`
-	Version        int                    `json:"version"`
+	ComputeMultiplier *float32               `json:"compute_multiplier,omitempty"`
+	CreatedAt         int64                  `json:"created_at"`
+	EntrypointPath    *string                `json:"entrypoint_path,omitempty"`
+	Id                string                 `json:"id"`
+	ImportMap         *bool                  `json:"import_map,omitempty"`
+	ImportMapPath     *string                `json:"import_map_path,omitempty"`
+	Name              string                 `json:"name"`
+	Slug              string                 `json:"slug"`
+	Status            FunctionResponseStatus `json:"status"`
+	UpdatedAt         int64                  `json:"updated_at"`
+	VerifyJwt         *bool                  `json:"verify_jwt,omitempty"`
+	Version           int                    `json:"version"`
 }
 
 // FunctionResponseStatus defines model for FunctionResponse.Status.
@@ -842,17 +890,18 @@ type FunctionResponseStatus string
 
 // FunctionSlugResponse defines model for FunctionSlugResponse.
 type FunctionSlugResponse struct {
-	CreatedAt      int64                      `json:"created_at"`
-	EntrypointPath *string                    `json:"entrypoint_path,omitempty"`
-	Id             string                     `json:"id"`
-	ImportMap      *bool                      `json:"import_map,omitempty"`
-	ImportMapPath  *string                    `json:"import_map_path,omitempty"`
-	Name           string                     `json:"name"`
-	Slug           string                     `json:"slug"`
-	Status         FunctionSlugResponseStatus `json:"status"`
-	UpdatedAt      int64                      `json:"updated_at"`
-	VerifyJwt      *bool                      `json:"verify_jwt,omitempty"`
-	Version        int                        `json:"version"`
+	ComputeMultiplier *float32                   `json:"compute_multiplier,omitempty"`
+	CreatedAt         int64                      `json:"created_at"`
+	EntrypointPath    *string                    `json:"entrypoint_path,omitempty"`
+	Id                string                     `json:"id"`
+	ImportMap         *bool                      `json:"import_map,omitempty"`
+	ImportMapPath     *string                    `json:"import_map_path,omitempty"`
+	Name              string                     `json:"name"`
+	Slug              string                     `json:"slug"`
+	Status            FunctionSlugResponseStatus `json:"status"`
+	UpdatedAt         int64                      `json:"updated_at"`
+	VerifyJwt         *bool                      `json:"verify_jwt,omitempty"`
+	Version           int                        `json:"version"`
 }
 
 // FunctionSlugResponseStatus defines model for FunctionSlugResponse.Status.
@@ -1539,17 +1588,18 @@ type V1BackupsResponse struct {
 
 // V1CreateFunctionBody defines model for V1CreateFunctionBody.
 type V1CreateFunctionBody struct {
-	Body      string `json:"body"`
-	Name      string `json:"name"`
-	Slug      string `json:"slug"`
-	VerifyJwt *bool  `json:"verify_jwt,omitempty"`
+	Body              string   `json:"body"`
+	ComputeMultiplier *float32 `json:"compute_multiplier,omitempty"`
+	Name              string   `json:"name"`
+	Slug              string   `json:"slug"`
+	VerifyJwt         *bool    `json:"verify_jwt,omitempty"`
 }
 
-// V1CreateProjectBody defines model for V1CreateProjectBody.
-type V1CreateProjectBody struct {
+// V1CreateProjectBodyDto defines model for V1CreateProjectBodyDto.
+type V1CreateProjectBodyDto struct {
 	// DbPass Database password
-	DbPass              string               `json:"db_pass"`
-	DesiredInstanceSize *DesiredInstanceSize `json:"desired_instance_size,omitempty"`
+	DbPass              string                                     `json:"db_pass"`
+	DesiredInstanceSize *V1CreateProjectBodyDtoDesiredInstanceSize `json:"desired_instance_size,omitempty"`
 
 	// KpsEnabled This field is deprecated and is ignored in this request
 	// Deprecated:
@@ -1563,24 +1613,35 @@ type V1CreateProjectBody struct {
 
 	// Plan Subscription Plan is now set on organization level and is ignored in this request
 	// Deprecated:
-	Plan *V1CreateProjectBodyPlan `json:"plan,omitempty"`
+	Plan *V1CreateProjectBodyDtoPlan `json:"plan,omitempty"`
 
 	// PostgresEngine Postgres engine version. If not provided, the latest version will be used.
-	PostgresEngine *PostgresEngine `json:"postgres_engine,omitempty"`
+	PostgresEngine *V1CreateProjectBodyDtoPostgresEngine `json:"postgres_engine,omitempty"`
 
 	// Region Region you want your server to reside in
-	Region         V1CreateProjectBodyRegion `json:"region"`
-	ReleaseChannel *ReleaseChannel           `json:"release_channel,omitempty"`
+	Region V1CreateProjectBodyDtoRegion `json:"region"`
+
+	// ReleaseChannel Release channel. If not provided, GA will be used.
+	ReleaseChannel *V1CreateProjectBodyDtoReleaseChannel `json:"release_channel,omitempty"`
 
 	// TemplateUrl Template URL used to create the project from the CLI.
 	TemplateUrl *string `json:"template_url,omitempty"`
 }
 
-// V1CreateProjectBodyPlan Subscription Plan is now set on organization level and is ignored in this request
-type V1CreateProjectBodyPlan string
+// V1CreateProjectBodyDtoDesiredInstanceSize defines model for V1CreateProjectBodyDto.DesiredInstanceSize.
+type V1CreateProjectBodyDtoDesiredInstanceSize string
+
+// V1CreateProjectBodyDtoPlan Subscription Plan is now set on organization level and is ignored in this request
+type V1CreateProjectBodyDtoPlan string
+
+// V1CreateProjectBodyDtoPostgresEngine Postgres engine version. If not provided, the latest version will be used.
+type V1CreateProjectBodyDtoPostgresEngine string
 
-// V1CreateProjectBodyRegion Region you want your server to reside in
-type V1CreateProjectBodyRegion string
+// V1CreateProjectBodyDtoRegion Region you want your server to reside in
+type V1CreateProjectBodyDtoRegion string
+
+// V1CreateProjectBodyDtoReleaseChannel Release channel. If not provided, GA will be used.
+type V1CreateProjectBodyDtoReleaseChannel string
 
 // V1DatabaseResponse defines model for V1DatabaseResponse.
 type V1DatabaseResponse struct {
@@ -1656,8 +1717,7 @@ type V1ProjectRefResponse struct {
 // V1ProjectResponse defines model for V1ProjectResponse.
 type V1ProjectResponse struct {
 	// CreatedAt Creation timestamp
-	CreatedAt string              `json:"created_at"`
-	Database  *V1DatabaseResponse `json:"database,omitempty"`
+	CreatedAt string `json:"created_at"`
 
 	// Id Id of your project
 	Id string `json:"id"`
@@ -1676,6 +1736,29 @@ type V1ProjectResponse struct {
 // V1ProjectResponseStatus defines model for V1ProjectResponse.Status.
 type V1ProjectResponseStatus string
 
+// V1ProjectWithDatabaseResponse defines model for V1ProjectWithDatabaseResponse.
+type V1ProjectWithDatabaseResponse struct {
+	// CreatedAt Creation timestamp
+	CreatedAt string             `json:"created_at"`
+	Database  V1DatabaseResponse `json:"database"`
+
+	// Id Id of your project
+	Id string `json:"id"`
+
+	// Name Name of your project
+	Name string `json:"name"`
+
+	// OrganizationId Slug of your organization
+	OrganizationId string `json:"organization_id"`
+
+	// Region Region of your project
+	Region string                              `json:"region"`
+	Status V1ProjectWithDatabaseResponseStatus `json:"status"`
+}
+
+// V1ProjectWithDatabaseResponseStatus defines model for V1ProjectWithDatabaseResponse.Status.
+type V1ProjectWithDatabaseResponseStatus string
+
 // V1RestorePitrBody defines model for V1RestorePitrBody.
 type V1RestorePitrBody struct {
 	RecoveryTimeTargetUnix int64 `json:"recovery_time_target_unix"`
@@ -1718,9 +1801,10 @@ type V1StorageBucketResponse struct {
 
 // V1UpdateFunctionBody defines model for V1UpdateFunctionBody.
 type V1UpdateFunctionBody struct {
-	Body      *string `json:"body,omitempty"`
-	Name      *string `json:"name,omitempty"`
-	VerifyJwt *bool   `json:"verify_jwt,omitempty"`
+	Body              *string  `json:"body,omitempty"`
+	ComputeMultiplier *float32 `json:"compute_multiplier,omitempty"`
+	Name              *string  `json:"name,omitempty"`
+	VerifyJwt         *bool    `json:"verify_jwt,omitempty"`
 }
 
 // ValidationError defines model for ValidationError.
@@ -1766,24 +1850,51 @@ type V1AuthorizeUserParamsResponseType string
 // V1AuthorizeUserParamsCodeChallengeMethod defines parameters for V1AuthorizeUser.
 type V1AuthorizeUserParamsCodeChallengeMethod string
 
+// V1GetProjectApiKeysParams defines parameters for V1GetProjectApiKeys.
+type V1GetProjectApiKeysParams struct {
+	Reveal bool `form:"reveal" json:"reveal"`
+}
+
+// CreateApiKeyParams defines parameters for CreateApiKey.
+type CreateApiKeyParams struct {
+	Reveal bool `form:"reveal" json:"reveal"`
+}
+
+// DeleteApiKeyParams defines parameters for DeleteApiKey.
+type DeleteApiKeyParams struct {
+	Reveal bool `form:"reveal" json:"reveal"`
+}
+
+// GetApiKeyParams defines parameters for GetApiKey.
+type GetApiKeyParams struct {
+	Reveal bool `form:"reveal" json:"reveal"`
+}
+
+// UpdateApiKeyParams defines parameters for UpdateApiKey.
+type UpdateApiKeyParams struct {
+	Reveal bool `form:"reveal" json:"reveal"`
+}
+
 // V1CreateAFunctionParams defines parameters for V1CreateAFunction.
 type V1CreateAFunctionParams struct {
-	Slug           *string `form:"slug,omitempty" json:"slug,omitempty"`
-	Name           *string `form:"name,omitempty" json:"name,omitempty"`
-	VerifyJwt      *bool   `form:"verify_jwt,omitempty" json:"verify_jwt,omitempty"`
-	ImportMap      *bool   `form:"import_map,omitempty" json:"import_map,omitempty"`
-	EntrypointPath *string `form:"entrypoint_path,omitempty" json:"entrypoint_path,omitempty"`
-	ImportMapPath  *string `form:"import_map_path,omitempty" json:"import_map_path,omitempty"`
+	Slug              *string  `form:"slug,omitempty" json:"slug,omitempty"`
+	Name              *string  `form:"name,omitempty" json:"name,omitempty"`
+	VerifyJwt         *bool    `form:"verify_jwt,omitempty" json:"verify_jwt,omitempty"`
+	ImportMap         *bool    `form:"import_map,omitempty" json:"import_map,omitempty"`
+	EntrypointPath    *string  `form:"entrypoint_path,omitempty" json:"entrypoint_path,omitempty"`
+	ImportMapPath     *string  `form:"import_map_path,omitempty" json:"import_map_path,omitempty"`
+	ComputeMultiplier *float32 `form:"compute_multiplier,omitempty" json:"compute_multiplier,omitempty"`
 }
 
 // V1UpdateAFunctionParams defines parameters for V1UpdateAFunction.
 type V1UpdateAFunctionParams struct {
-	Slug           *string `form:"slug,omitempty" json:"slug,omitempty"`
-	Name           *string `form:"name,omitempty" json:"name,omitempty"`
-	VerifyJwt      *bool   `form:"verify_jwt,omitempty" json:"verify_jwt,omitempty"`
-	ImportMap      *bool   `form:"import_map,omitempty" json:"import_map,omitempty"`
-	EntrypointPath *string `form:"entrypoint_path,omitempty" json:"entrypoint_path,omitempty"`
-	ImportMapPath  *string `form:"import_map_path,omitempty" json:"import_map_path,omitempty"`
+	Slug              *string  `form:"slug,omitempty" json:"slug,omitempty"`
+	Name              *string  `form:"name,omitempty" json:"name,omitempty"`
+	VerifyJwt         *bool    `form:"verify_jwt,omitempty" json:"verify_jwt,omitempty"`
+	ImportMap         *bool    `form:"import_map,omitempty" json:"import_map,omitempty"`
+	EntrypointPath    *string  `form:"entrypoint_path,omitempty" json:"entrypoint_path,omitempty"`
+	ImportMapPath     *string  `form:"import_map_path,omitempty" json:"import_map_path,omitempty"`
+	ComputeMultiplier *float32 `form:"compute_multiplier,omitempty" json:"compute_multiplier,omitempty"`
 }
 
 // V1GetServicesHealthParams defines parameters for V1GetServicesHealth.
@@ -1823,10 +1934,10 @@ type V1UpdateABranchConfigJSONRequestBody = UpdateBranchBody
 type V1ExchangeOauthTokenFormdataRequestBody = OAuthTokenBody
 
 // V1CreateAnOrganizationJSONRequestBody defines body for V1CreateAnOrganization for application/json ContentType.
-type V1CreateAnOrganizationJSONRequestBody = CreateOrganizationBodyV1
+type V1CreateAnOrganizationJSONRequestBody = CreateOrganizationV1Dto
 
 // V1CreateAProjectJSONRequestBody defines body for V1CreateAProject for application/json ContentType.
-type V1CreateAProjectJSONRequestBody = V1CreateProjectBody
+type V1CreateAProjectJSONRequestBody = V1CreateProjectBodyDto
 
 // CreateApiKeyJSONRequestBody defines body for CreateApiKey for application/json ContentType.
 type CreateApiKeyJSONRequestBody = CreateApiKeyBody
diff --git a/pkg/config/api.go b/pkg/config/api.go
index 405bcb7b..ec7c4f86 100644
--- a/pkg/config/api.go
+++ b/pkg/config/api.go
@@ -55,7 +55,7 @@ func (a *api) ToUpdatePostgrestConfigBody() v1API.UpdatePostgrestConfigBody {
 	return body
 }
 
-func (a *api) fromRemoteApiConfig(remoteConfig v1API.PostgrestConfigWithJWTSecretResponse) {
+func (a *api) FromRemoteApiConfig(remoteConfig v1API.PostgrestConfigWithJWTSecretResponse) {
 	if a.Enabled = len(remoteConfig.DbSchema) > 0; !a.Enabled {
 		return
 	}
@@ -84,7 +84,7 @@ func (a *api) DiffWithRemote(remoteConfig v1API.PostgrestConfigWithJWTSecretResp
 	if err != nil {
 		return nil, err
 	}
-	copy.fromRemoteApiConfig(remoteConfig)
+	copy.FromRemoteApiConfig(remoteConfig)
 	remoteCompare, err := ToTomlBytes(copy)
 	if err != nil {
 		return nil, err
diff --git a/pkg/config/auth.go b/pkg/config/auth.go
index a2ea016f..10611c23 100644
--- a/pkg/config/auth.go
+++ b/pkg/config/auth.go
@@ -10,19 +10,54 @@ import (
 	"github.com/supabase/cli/pkg/diff"
 )
 
+type PasswordRequirements string
+
+const (
+	NoRequirements                 PasswordRequirements = ""
+	LettersDigits                  PasswordRequirements = "letters_digits"
+	LowerUpperLettersDigits        PasswordRequirements = "lower_upper_letters_digits"
+	LowerUpperLettersDigitsSymbols PasswordRequirements = "lower_upper_letters_digits_symbols"
+)
+
+func (r PasswordRequirements) ToChar() v1API.UpdateAuthConfigBodyPasswordRequiredCharacters {
+	switch r {
+	case LettersDigits:
+		return v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+	case LowerUpperLettersDigits:
+		return v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567891
+	case LowerUpperLettersDigitsSymbols:
+		return v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567892
+	}
+	return v1API.Empty
+}
+
+func NewPasswordRequirement(c v1API.UpdateAuthConfigBodyPasswordRequiredCharacters) PasswordRequirements {
+	switch c {
+	case v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:
+		return LettersDigits
+	case v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567891:
+		return LowerUpperLettersDigits
+	case v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567892:
+		return LowerUpperLettersDigitsSymbols
+	}
+	return NoRequirements
+}
+
 type (
 	auth struct {
 		Enabled bool   `toml:"enabled"`
 		Image   string `toml:"-"`
 
-		SiteUrl                    string   `toml:"site_url"`
-		AdditionalRedirectUrls     []string `toml:"additional_redirect_urls"`
-		JwtExpiry                  uint     `toml:"jwt_expiry"`
-		EnableRefreshTokenRotation bool     `toml:"enable_refresh_token_rotation"`
-		RefreshTokenReuseInterval  uint     `toml:"refresh_token_reuse_interval"`
-		EnableManualLinking        bool     `toml:"enable_manual_linking"`
-		EnableSignup               bool     `toml:"enable_signup"`
-		EnableAnonymousSignIns     bool     `toml:"enable_anonymous_sign_ins"`
+		SiteUrl                    string               `toml:"site_url"`
+		AdditionalRedirectUrls     []string             `toml:"additional_redirect_urls"`
+		JwtExpiry                  uint                 `toml:"jwt_expiry"`
+		EnableRefreshTokenRotation bool                 `toml:"enable_refresh_token_rotation"`
+		RefreshTokenReuseInterval  uint                 `toml:"refresh_token_reuse_interval"`
+		EnableManualLinking        bool                 `toml:"enable_manual_linking"`
+		EnableSignup               bool                 `toml:"enable_signup"`
+		EnableAnonymousSignIns     bool                 `toml:"enable_anonymous_sign_ins"`
+		MinimumPasswordLength      uint                 `toml:"minimum_password_length"`
+		PasswordRequirements       PasswordRequirements `toml:"password_requirements"`
 
 		Hook     hook     `toml:"hook"`
 		MFA      mfa      `toml:"mfa"`
@@ -192,6 +227,8 @@ func (a *auth) ToUpdateAuthConfigBody() v1API.UpdateAuthConfigBody {
 		SecurityManualLinkingEnabled:      &a.EnableManualLinking,
 		DisableSignup:                     cast.Ptr(!a.EnableSignup),
 		ExternalAnonymousUsersEnabled:     &a.EnableAnonymousSignIns,
+		PasswordMinLength:                 cast.UintToIntPtr(&a.MinimumPasswordLength),
+		PasswordRequiredCharacters:        cast.Ptr(a.PasswordRequirements.ToChar()),
 	}
 	a.Hook.toAuthConfigBody(&body)
 	a.MFA.toAuthConfigBody(&body)
@@ -202,7 +239,7 @@ func (a *auth) ToUpdateAuthConfigBody() v1API.UpdateAuthConfigBody {
 	return body
 }
 
-func (a *auth) fromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) {
+func (a *auth) FromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) {
 	a.SiteUrl = cast.Val(remoteConfig.SiteUrl, "")
 	a.AdditionalRedirectUrls = strToArr(cast.Val(remoteConfig.UriAllowList, ""))
 	a.JwtExpiry = cast.IntToUint(cast.Val(remoteConfig.JwtExp, 0))
@@ -211,6 +248,9 @@ func (a *auth) fromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) {
 	a.EnableManualLinking = cast.Val(remoteConfig.SecurityManualLinkingEnabled, false)
 	a.EnableSignup = !cast.Val(remoteConfig.DisableSignup, false)
 	a.EnableAnonymousSignIns = cast.Val(remoteConfig.ExternalAnonymousUsersEnabled, false)
+	a.MinimumPasswordLength = cast.IntToUint(cast.Val(remoteConfig.PasswordMinLength, 0))
+	prc := cast.Val(remoteConfig.PasswordRequiredCharacters, "")
+	a.PasswordRequirements = NewPasswordRequirement(v1API.UpdateAuthConfigBodyPasswordRequiredCharacters(prc))
 	a.Hook.fromAuthConfig(remoteConfig)
 	a.MFA.fromAuthConfig(remoteConfig)
 	a.Sessions.fromAuthConfig(remoteConfig)
@@ -222,53 +262,76 @@ func (a *auth) fromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) {
 func (h hook) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
 	if body.HookCustomAccessTokenEnabled = &h.CustomAccessToken.Enabled; *body.HookCustomAccessTokenEnabled {
 		body.HookCustomAccessTokenUri = &h.CustomAccessToken.URI
-		body.HookCustomAccessTokenSecrets = &h.CustomAccessToken.Secrets
+		if len(h.CustomAccessToken.Secrets) > 0 {
+			body.HookCustomAccessTokenSecrets = &h.CustomAccessToken.Secrets
+		}
 	}
 	if body.HookSendEmailEnabled = &h.SendEmail.Enabled; *body.HookSendEmailEnabled {
 		body.HookSendEmailUri = &h.SendEmail.URI
-		body.HookSendEmailSecrets = &h.SendEmail.Secrets
+		if len(h.SendEmail.Secrets) > 0 {
+			body.HookSendEmailSecrets = &h.SendEmail.Secrets
+		}
 	}
 	if body.HookSendSmsEnabled = &h.SendSMS.Enabled; *body.HookSendSmsEnabled {
 		body.HookSendSmsUri = &h.SendSMS.URI
-		body.HookSendSmsSecrets = &h.SendSMS.Secrets
+		if len(h.SendSMS.Secrets) > 0 {
+			body.HookSendSmsSecrets = &h.SendSMS.Secrets
+		}
 	}
 	// Enterprise and team only features
 	if body.HookMfaVerificationAttemptEnabled = &h.MFAVerificationAttempt.Enabled; *body.HookMfaVerificationAttemptEnabled {
 		body.HookMfaVerificationAttemptUri = &h.MFAVerificationAttempt.URI
-		body.HookMfaVerificationAttemptSecrets = &h.MFAVerificationAttempt.Secrets
+		if len(h.MFAVerificationAttempt.Secrets) > 0 {
+			body.HookMfaVerificationAttemptSecrets = &h.MFAVerificationAttempt.Secrets
+		}
 	}
 	if body.HookPasswordVerificationAttemptEnabled = &h.PasswordVerificationAttempt.Enabled; *body.HookPasswordVerificationAttemptEnabled {
 		body.HookPasswordVerificationAttemptUri = &h.PasswordVerificationAttempt.URI
-		body.HookPasswordVerificationAttemptSecrets = &h.PasswordVerificationAttempt.Secrets
+		if len(h.PasswordVerificationAttempt.Secrets) > 0 {
+			body.HookPasswordVerificationAttemptSecrets = &h.PasswordVerificationAttempt.Secrets
+		}
 	}
 }
-
 func (h *hook) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
 	// Ignore disabled hooks because their envs are not loaded
 	if h.CustomAccessToken.Enabled {
 		h.CustomAccessToken.URI = cast.Val(remoteConfig.HookCustomAccessTokenUri, "")
-		h.CustomAccessToken.Secrets = hashPrefix + cast.Val(remoteConfig.HookCustomAccessTokenSecrets, "")
+		if remoteConfig.HookCustomAccessTokenSecrets != nil {
+			h.CustomAccessToken.Secrets = hashPrefix + cast.Val(remoteConfig.HookCustomAccessTokenSecrets, "")
+		}
 	}
 	h.CustomAccessToken.Enabled = cast.Val(remoteConfig.HookCustomAccessTokenEnabled, false)
+
 	if h.SendEmail.Enabled {
 		h.SendEmail.URI = cast.Val(remoteConfig.HookSendEmailUri, "")
-		h.SendEmail.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendEmailSecrets, "")
+		if remoteConfig.HookSendEmailSecrets != nil {
+			h.SendEmail.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendEmailSecrets, "")
+		}
 	}
 	h.SendEmail.Enabled = cast.Val(remoteConfig.HookSendEmailEnabled, false)
+
 	if h.SendSMS.Enabled {
 		h.SendSMS.URI = cast.Val(remoteConfig.HookSendSmsUri, "")
-		h.SendSMS.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendSmsSecrets, "")
+		if remoteConfig.HookSendSmsSecrets != nil {
+			h.SendSMS.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendSmsSecrets, "")
+		}
 	}
 	h.SendSMS.Enabled = cast.Val(remoteConfig.HookSendSmsEnabled, false)
+
 	// Enterprise and team only features
 	if h.MFAVerificationAttempt.Enabled {
 		h.MFAVerificationAttempt.URI = cast.Val(remoteConfig.HookMfaVerificationAttemptUri, "")
-		h.MFAVerificationAttempt.Secrets = hashPrefix + cast.Val(remoteConfig.HookMfaVerificationAttemptSecrets, "")
+		if remoteConfig.HookMfaVerificationAttemptSecrets != nil {
+			h.MFAVerificationAttempt.Secrets = hashPrefix + cast.Val(remoteConfig.HookMfaVerificationAttemptSecrets, "")
+		}
 	}
 	h.MFAVerificationAttempt.Enabled = cast.Val(remoteConfig.HookMfaVerificationAttemptEnabled, false)
+
 	if h.PasswordVerificationAttempt.Enabled {
 		h.PasswordVerificationAttempt.URI = cast.Val(remoteConfig.HookPasswordVerificationAttemptUri, "")
-		h.PasswordVerificationAttempt.Secrets = hashPrefix + cast.Val(remoteConfig.HookPasswordVerificationAttemptSecrets, "")
+		if remoteConfig.HookPasswordVerificationAttemptSecrets != nil {
+			h.PasswordVerificationAttempt.Secrets = hashPrefix + cast.Val(remoteConfig.HookPasswordVerificationAttemptSecrets, "")
+		}
 	}
 	h.PasswordVerificationAttempt.Enabled = cast.Val(remoteConfig.HookPasswordVerificationAttemptEnabled, false)
 }
@@ -775,13 +838,13 @@ func (e external) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
 
 func (a *auth) DiffWithRemote(projectRef string, remoteConfig v1API.AuthConfigResponse) ([]byte, error) {
 	copy := a.Clone()
-	copy.hashSecrets(projectRef)
+	copy.HashSecrets(projectRef)
 	// Convert the config values into easily comparable remoteConfig values
 	currentValue, err := ToTomlBytes(copy)
 	if err != nil {
 		return nil, err
 	}
-	copy.fromRemoteAuthConfig(remoteConfig)
+	copy.FromRemoteAuthConfig(remoteConfig)
 	remoteCompare, err := ToTomlBytes(copy)
 	if err != nil {
 		return nil, err
@@ -791,7 +854,7 @@ func (a *auth) DiffWithRemote(projectRef string, remoteConfig v1API.AuthConfigRe
 
 const hashPrefix = "hash:"
 
-func (a *auth) hashSecrets(key string) {
+func (a *auth) HashSecrets(key string) {
 	hash := func(v string) string {
 		return hashPrefix + sha256Hmac(key, v)
 	}
@@ -811,19 +874,19 @@ func (a *auth) hashSecrets(key string) {
 	case a.Sms.Vonage.Enabled:
 		a.Sms.Vonage.ApiSecret = hash(a.Sms.Vonage.ApiSecret)
 	}
-	if a.Hook.MFAVerificationAttempt.Enabled {
+	if a.Hook.MFAVerificationAttempt.Enabled && len(a.Hook.MFAVerificationAttempt.Secrets) > 0 {
 		a.Hook.MFAVerificationAttempt.Secrets = hash(a.Hook.MFAVerificationAttempt.Secrets)
 	}
-	if a.Hook.PasswordVerificationAttempt.Enabled {
+	if a.Hook.PasswordVerificationAttempt.Enabled && len(a.Hook.PasswordVerificationAttempt.Secrets) > 0 {
 		a.Hook.PasswordVerificationAttempt.Secrets = hash(a.Hook.PasswordVerificationAttempt.Secrets)
 	}
-	if a.Hook.CustomAccessToken.Enabled {
+	if a.Hook.CustomAccessToken.Enabled && len(a.Hook.CustomAccessToken.Secrets) > 0 {
 		a.Hook.CustomAccessToken.Secrets = hash(a.Hook.CustomAccessToken.Secrets)
 	}
-	if a.Hook.SendSMS.Enabled {
+	if a.Hook.SendSMS.Enabled && len(a.Hook.SendSMS.Secrets) > 0 {
 		a.Hook.SendSMS.Secrets = hash(a.Hook.SendSMS.Secrets)
 	}
-	if a.Hook.SendEmail.Enabled {
+	if a.Hook.SendEmail.Enabled && len(a.Hook.SendEmail.Secrets) > 0 {
 		a.Hook.SendEmail.Secrets = hash(a.Hook.SendEmail.Secrets)
 	}
 	for name, provider := range a.External {
diff --git a/pkg/config/config.go b/pkg/config/config.go
index b1e7ed57..f5a56dfc 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -159,11 +159,13 @@ type (
 	}
 
 	inbucket struct {
-		Enabled  bool   `toml:"enabled"`
-		Image    string `toml:"-"`
-		Port     uint16 `toml:"port"`
-		SmtpPort uint16 `toml:"smtp_port"`
-		Pop3Port uint16 `toml:"pop3_port"`
+		Enabled    bool   `toml:"enabled"`
+		Image      string `toml:"-"`
+		Port       uint16 `toml:"port"`
+		SmtpPort   uint16 `toml:"smtp_port"`
+		Pop3Port   uint16 `toml:"pop3_port"`
+		AdminEmail string `toml:"admin_email"`
+		SenderName string `toml:"sender_name"`
 	}
 
 	edgeRuntime struct {
@@ -301,6 +303,9 @@ func NewConfig(editors ...ConfigEditor) config {
 					"reauthentication": {},
 				},
 			},
+			Sms: sms{
+				TestOTP: map[string]string{},
+			},
 			External: map[string]provider{
 				"apple":         {},
 				"azure":         {},
@@ -327,7 +332,9 @@ func NewConfig(editors ...ConfigEditor) config {
 			JwtSecret: defaultJwtSecret,
 		},
 		Inbucket: inbucket{
-			Image: inbucketImage,
+			Image:      inbucketImage,
+			AdminEmail: "admin@email.com",
+			SenderName: "Admin",
 		},
 		Studio: studio{
 			Image:       studioImage,
@@ -666,6 +673,10 @@ func (c *baseConfig) Validate(fsys fs.FS) error {
 				return errors.Errorf("Invalid config for auth.additional_redirect_urls[%d]: %v", i, err)
 			}
 		}
+		allowed := []PasswordRequirements{NoRequirements, LettersDigits, LowerUpperLettersDigits, LowerUpperLettersDigitsSymbols}
+		if !sliceContains(allowed, c.Auth.PasswordRequirements) {
+			return errors.Errorf("Invalid config for auth.password_requirements. Must be one of: %v", allowed)
+		}
 		if err := c.Auth.Hook.validate(); err != nil {
 			return err
 		}
@@ -982,14 +993,25 @@ func (h *hookConfig) validate(hookType string) (err error) {
 		return nil
 	}
 	if h.URI == "" {
-		return errors.Errorf("missing required field in config: auth.hook.%s.uri", hookType)
-	} else if parsed, err := url.Parse(h.URI); err != nil {
+		return errors.Errorf("Missing required field in config: auth.hook.%s.uri", hookType)
+	}
+	parsed, err := url.Parse(h.URI)
+	if err != nil {
 		return errors.Errorf("failed to parse template url: %w", err)
-	} else if !(parsed.Scheme == "http" || parsed.Scheme == "https" || parsed.Scheme == "pg-functions") {
-		return errors.Errorf("Invalid HTTP hook config: auth.hook.%v should be a Postgres function URI, or a HTTP or HTTPS URL", hookType)
 	}
-	if h.Secrets, err = maybeLoadEnv(h.Secrets); err != nil {
-		return errors.Errorf("missing required field in config: auth.hook.%s.secrets", hookType)
+	switch strings.ToLower(parsed.Scheme) {
+	case "http", "https":
+		if len(h.Secrets) == 0 {
+			return errors.Errorf("Missing required field in config: auth.hook.%s.secrets", hookType)
+		} else if h.Secrets, err = maybeLoadEnv(h.Secrets); err != nil {
+			return err
+		}
+	case "pg-functions":
+		if len(h.Secrets) > 0 {
+			return errors.Errorf("Invalid hook config: auth.hook.%s.secrets is unsupported for pg-functions URI", hookType)
+		}
+	default:
+		return errors.Errorf("Invalid hook config: auth.hook.%v should be a HTTP, HTTPS, or pg-functions URI", hookType)
 	}
 	return nil
 }
@@ -1059,19 +1081,16 @@ func (c *tpaCognito) issuerURL() string {
 	return fmt.Sprintf("https://cognito-idp.%s.amazonaws.com/%s", c.UserPoolRegion, c.UserPoolID)
 }
 
-func (c *tpaCognito) validate() error {
+func (c *tpaCognito) validate() (err error) {
 	if c.UserPoolID == "" {
 		return errors.New("Invalid config: auth.third_party.cognito is enabled but without a user_pool_id.")
-	}
-	var err error
-	if c.UserPoolID, err = maybeLoadEnv(c.UserPoolID); err != nil {
+	} else if c.UserPoolID, err = maybeLoadEnv(c.UserPoolID); err != nil {
 		return err
 	}
 
 	if c.UserPoolRegion == "" {
 		return errors.New("Invalid config: auth.third_party.cognito is enabled but without a user_pool_region.")
-	}
-	if c.UserPoolRegion, err = maybeLoadEnv(c.UserPoolRegion); err != nil {
+	} else if c.UserPoolRegion, err = maybeLoadEnv(c.UserPoolRegion); err != nil {
 		return err
 	}
 
diff --git a/pkg/config/constants.go b/pkg/config/constants.go
index 670450d5..da0a9bf4 100644
--- a/pkg/config/constants.go
+++ b/pkg/config/constants.go
@@ -12,11 +12,11 @@ const (
 	pgmetaImage      = "supabase/postgres-meta:v0.84.2"
 	studioImage      = "supabase/studio:20241106-f29003e"
 	imageProxyImage  = "darthsim/imgproxy:v3.8.0"
-	edgeRuntimeImage = "supabase/edge-runtime:v1.62.2"
+	edgeRuntimeImage = "supabase/edge-runtime:v1.65.3"
 	vectorImage      = "timberio/vector:0.28.1-alpine"
 	supavisorImage   = "supabase/supavisor:1.1.56"
 	gotrueImage      = "supabase/gotrue:v2.164.0"
-	realtimeImage    = "supabase/realtime:v2.30.34"
+	realtimeImage    = "supabase/realtime:v2.33.58"
 	storageImage     = "supabase/storage-api:v1.11.13"
 	logflareImage    = "supabase/logflare:1.4.0"
 	// Append to JobImages when adding new dependencies below
diff --git a/pkg/config/db.go b/pkg/config/db.go
index 4e22dd53..2a1d31ca 100644
--- a/pkg/config/db.go
+++ b/pkg/config/db.go
@@ -112,7 +112,7 @@ func (a *settings) ToUpdatePostgresConfigBody() v1API.UpdatePostgresConfigBody {
 	return body
 }
 
-func (a *settings) fromRemoteConfig(remoteConfig v1API.PostgresConfigResponse) {
+func (a *settings) FromRemotePostgresConfig(remoteConfig v1API.PostgresConfigResponse) {
 	a.EffectiveCacheSize = remoteConfig.EffectiveCacheSize
 	a.LogicalDecodingWorkMem = remoteConfig.LogicalDecodingWorkMem
 	a.MaintenanceWorkMem = remoteConfig.MaintenanceWorkMem
@@ -155,7 +155,7 @@ func (a *settings) DiffWithRemote(remoteConfig v1API.PostgresConfigResponse) ([]
 	if err != nil {
 		return nil, err
 	}
-	copy.fromRemoteConfig(remoteConfig)
+	copy.FromRemotePostgresConfig(remoteConfig)
 	remoteCompare, err := ToTomlBytes(copy)
 	if err != nil {
 		return nil, err
diff --git a/pkg/config/storage.go b/pkg/config/storage.go
index 3398dee4..b11b28a1 100644
--- a/pkg/config/storage.go
+++ b/pkg/config/storage.go
@@ -44,7 +44,7 @@ func (s *storage) ToUpdateStorageConfigBody() v1API.UpdateStorageConfigBody {
 	return body
 }
 
-func (s *storage) fromRemoteStorageConfig(remoteConfig v1API.StorageConfigResponse) {
+func (s *storage) FromRemoteStorageConfig(remoteConfig v1API.StorageConfigResponse) {
 	s.FileSizeLimit = sizeInBytes(remoteConfig.FileSizeLimit)
 	s.ImageTransformation.Enabled = remoteConfig.Features.ImageTransformation.Enabled
 }
@@ -56,7 +56,7 @@ func (s *storage) DiffWithRemote(remoteConfig v1API.StorageConfigResponse) ([]by
 	if err != nil {
 		return nil, err
 	}
-	copy.fromRemoteStorageConfig(remoteConfig)
+	copy.FromRemoteStorageConfig(remoteConfig)
 	remoteCompare, err := ToTomlBytes(copy)
 	if err != nil {
 		return nil, err
diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml
index 43854f7d..12decc3f 100644
--- a/pkg/config/templates/config.toml
+++ b/pkg/config/templates/config.toml
@@ -1,3 +1,5 @@
+# For detailed configuration reference documentation, visit:
+# https://supabase.com/docs/guides/local-development/cli/config
 # A string used to distinguish different Supabase projects on the same host. Defaults to the
 # working directory name when running `supabase init`.
 project_id = "{{ .ProjectId }}"
@@ -72,6 +74,8 @@ port = 54324
 # Uncomment to expose additional ports for testing user applications that send emails.
 # smtp_port = 54325
 # pop3_port = 54326
+# admin_email = "admin@email.com"
+# sender_name = "Admin"
 
 [storage]
 enabled = true
@@ -108,6 +112,11 @@ enable_signup = true
 enable_anonymous_sign_ins = false
 # Allow/disallow testing manual linking of accounts
 enable_manual_linking = false
+# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more.
+minimum_password_length = 6
+# Passwords that do not meet the following requirements will be rejected as weak. Supported values
+# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols`
+password_requirements = ""
 
 [auth.email]
 # Allow/disallow new user signups via email to your project.
@@ -146,7 +155,7 @@ enable_signup = false
 # If enabled, users need to confirm their phone number before signing in.
 enable_confirmations = false
 # Template for sending OTP to users
-template = "Your code is {{ `{{ .Code }}` }} ."
+template = "Your code is {{ `{{ .Code }}` }}"
 # Controls the minimum amount of time that must pass before sending another sms otp.
 max_frequency = "5s"
 
@@ -234,8 +243,18 @@ enabled = true
 # Configure one of the supported request policies: `oneshot`, `per_worker`.
 # Use `oneshot` for hot reload, or `per_worker` for load testing.
 policy = "oneshot"
+# Port to attach the Chrome inspector for debugging edge functions.
 inspector_port = 8083
 
+# Use these configurations to customize your Edge Function.
+# [functions.MY_FUNCTION_NAME]
+# enabled = true
+# verify_jwt = true
+# import_map = "./functions/MY_FUNCTION_NAME/deno.json"
+# Uncomment to specify a custom file path to the entrypoint.
+# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx
+# entrypoint = "./functions/MY_FUNCTION_NAME/index.ts"
+
 [analytics]
 enabled = true
 port = 54327
diff --git a/pkg/config/utils.go b/pkg/config/utils.go
index 2dd9c1aa..9a46d94a 100644
--- a/pkg/config/utils.go
+++ b/pkg/config/utils.go
@@ -103,9 +103,6 @@ func mapToEnv(input map[string]string) string {
 
 func envToMap(input string) map[string]string {
 	env := strToArr(input)
-	if len(env) == 0 {
-		return nil
-	}
 	result := make(map[string]string, len(env))
 	for _, kv := range env {
 		if parts := strings.Split(kv, "="); len(parts) > 1 {


Test patch:
diff --git a/internal/db/branch/switch_/switch__test.go b/internal/db/branch/switch_/switch__test.go
index 42960662..7c70959c 100644
--- a/internal/db/branch/switch_/switch__test.go
+++ b/internal/db/branch/switch_/switch__test.go
@@ -2,7 +2,6 @@ package switch_
 
 import (
 	"context"
-	"fmt"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -14,6 +13,7 @@ import (
 	"github.com/spf13/afero"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"github.com/supabase/cli/internal/db/reset"
 	"github.com/supabase/cli/internal/testing/apitest"
 	"github.com/supabase/cli/internal/utils"
 	"github.com/supabase/cli/pkg/pgtest"
@@ -42,10 +42,14 @@ func TestSwitchCommand(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
 			Reply("ALTER DATABASE").
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			Reply("DO").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query(reset.TERMINATE_BACKENDS).
+			Reply("SELECT 1").
+			Query(reset.COUNT_REPLICATION_SLOTS).
+			Reply("SELECT 1", []interface{}{0}).
 			Query("ALTER DATABASE postgres RENAME TO main;").
 			Reply("ALTER DATABASE").
 			Query("ALTER DATABASE " + branch + " RENAME TO postgres;").
@@ -218,8 +222,10 @@ func TestSwitchDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
-			ReplyError(pgerrcode.InvalidParameterValue, `cannot disallow connections for current database`)
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			ReplyError(pgerrcode.InvalidParameterValue, `cannot disallow connections for current database`).
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
+			Query(reset.TERMINATE_BACKENDS)
 		// Run test
 		err := switchDatabase(context.Background(), "main", "target", conn.Intercept)
 		// Check error
@@ -234,10 +240,14 @@ func TestSwitchDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
 			Reply("ALTER DATABASE").
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			Reply("DO").
+			Query(reset.TERMINATE_BACKENDS).
+			Reply("SELECT 1").
+			Query(reset.COUNT_REPLICATION_SLOTS).
+			Reply("SELECT 1", []interface{}{0}).
 			Query("ALTER DATABASE postgres RENAME TO main;").
 			ReplyError(pgerrcode.DuplicateDatabase, `database "main" already exists`)
 		// Setup mock docker
@@ -260,10 +270,14 @@ func TestSwitchDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
 			Reply("ALTER DATABASE").
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			Reply("DO").
+			Query(reset.TERMINATE_BACKENDS).
+			Reply("SELECT 1").
+			Query(reset.COUNT_REPLICATION_SLOTS).
+			Reply("SELECT 1", []interface{}{0}).
 			Query("ALTER DATABASE postgres RENAME TO main;").
 			Reply("ALTER DATABASE").
 			Query("ALTER DATABASE target RENAME TO postgres;").
diff --git a/internal/db/reset/reset_test.go b/internal/db/reset/reset_test.go
index c65aa0ef..4e3558be 100644
--- a/internal/db/reset/reset_test.go
+++ b/internal/db/reset/reset_test.go
@@ -3,7 +3,6 @@ package reset
 import (
 	"context"
 	"errors"
-	"fmt"
 	"io"
 	"net/http"
 	"path/filepath"
@@ -202,10 +201,14 @@ func TestRecreateDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
 			Reply("ALTER DATABASE").
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			Reply("DO").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query(TERMINATE_BACKENDS).
+			Reply("SELECT 1").
+			Query(COUNT_REPLICATION_SLOTS).
+			Reply("SELECT 1", []interface{}{0}).
 			Query("DROP DATABASE IF EXISTS postgres WITH (FORCE)").
 			Reply("DROP DATABASE").
 			Query("CREATE DATABASE postgres WITH OWNER postgres").
@@ -228,14 +231,17 @@ func TestRecreateDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
-			ReplyError(pgerrcode.InvalidCatalogName, `database "postgres" does not exist`).
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			ReplyError(pgerrcode.UndefinedTable, `relation "pg_stat_activity" does not exist`)
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
+			ReplyError(pgerrcode.InvalidCatalogName, `database "_supabase" does not exist`).
+			Query(TERMINATE_BACKENDS).
+			Query(COUNT_REPLICATION_SLOTS).
+			ReplyError(pgerrcode.UndefinedTable, `relation "pg_replication_slots" does not exist`)
 		// Run test
 		err := recreateDatabase(context.Background(), conn.Intercept)
 		// Check error
-		assert.ErrorContains(t, err, `ERROR: relation "pg_stat_activity" does not exist (SQLSTATE 42P01)`)
+		assert.ErrorContains(t, err, `ERROR: relation "pg_replication_slots" does not exist (SQLSTATE 42P01)`)
 	})
 
 	t.Run("throws error on failure to disconnect", func(t *testing.T) {
@@ -243,8 +249,10 @@ func TestRecreateDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
-			ReplyError(pgerrcode.InvalidParameterValue, `cannot disallow connections for current database`)
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			ReplyError(pgerrcode.InvalidParameterValue, `cannot disallow connections for current database`).
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
+			Query(TERMINATE_BACKENDS)
 		// Run test
 		err := recreateDatabase(context.Background(), conn.Intercept)
 		// Check error
@@ -256,10 +264,14 @@ func TestRecreateDatabase(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false;").
+		conn.Query("ALTER DATABASE postgres ALLOW_CONNECTIONS false").
+			Reply("ALTER DATABASE").
+			Query("ALTER DATABASE _supabase ALLOW_CONNECTIONS false").
 			Reply("ALTER DATABASE").
-			Query(fmt.Sprintf(utils.TerminateDbSqlFmt, "postgres")).
-			Reply("DO").
+			Query(TERMINATE_BACKENDS).
+			Reply("SELECT 1").
+			Query(COUNT_REPLICATION_SLOTS).
+			Reply("SELECT 1", []interface{}{0}).
 			Query("DROP DATABASE IF EXISTS postgres WITH (FORCE)").
 			ReplyError(pgerrcode.ObjectInUse, `database "postgres" is used by an active logical replication slot`).
 			Query("CREATE DATABASE postgres WITH OWNER postgres").
diff --git a/internal/link/link_test.go b/internal/link/link_test.go
index c8a867f6..18c090ad 100644
--- a/internal/link/link_test.go
+++ b/internal/link/link_test.go
@@ -51,19 +51,38 @@ func TestLinkCommand(t *testing.T) {
 		// Flush pending mocks after test execution
 		defer gock.OffAll()
 		// Mock project status
+		postgres := api.V1DatabaseResponse{
+			Host:    utils.GetSupabaseDbHost(project),
+			Version: "15.1.0.117",
+		}
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project).
 			Reply(200).
-			JSON(api.V1ProjectResponse{Status: api.V1ProjectResponseStatusACTIVEHEALTHY})
+			JSON(api.V1ProjectWithDatabaseResponse{
+				Status:   api.V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY,
+				Database: postgres,
+			})
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/api-keys").
 			Reply(200).
 			JSON([]api.ApiKeyResponse{{Name: "anon", ApiKey: "anon-key"}})
 		// Link configs
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/database/postgres").
+			Reply(200).
+			JSON(api.PostgresConfigResponse{})
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/postgrest").
 			Reply(200).
 			JSON(api.V1PostgrestConfigResponse{})
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/auth").
+			Reply(200).
+			JSON(api.AuthConfigResponse{})
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/storage").
+			Reply(200).
+			JSON(api.StorageConfigResponse{})
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/config/database/pooler").
 			Reply(200).
@@ -83,23 +102,6 @@ func TestLinkCommand(t *testing.T) {
 			Get("/storage/v1/version").
 			Reply(200).
 			BodyString("0.40.4")
-		postgres := api.V1DatabaseResponse{
-			Host:    utils.GetSupabaseDbHost(project),
-			Version: "15.1.0.117",
-		}
-		gock.New(utils.DefaultApiHost).
-			Get("/v1/projects").
-			Reply(200).
-			JSON([]api.V1ProjectResponse{
-				{
-					Id:             project,
-					Database:       &postgres,
-					OrganizationId: "combined-fuchsia-lion",
-					Name:           "Test Project",
-					Region:         "us-west-1",
-					CreatedAt:      "2022-04-25T02:14:55.906498Z",
-				},
-			})
 		// Run test
 		err := Run(context.Background(), project, fsys, conn.Intercept)
 		// Check error
@@ -130,15 +132,27 @@ func TestLinkCommand(t *testing.T) {
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project).
 			Reply(200).
-			JSON(api.V1ProjectResponse{Status: api.V1ProjectResponseStatusACTIVEHEALTHY})
+			JSON(api.V1ProjectWithDatabaseResponse{
+				Status:   api.V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY,
+				Database: api.V1DatabaseResponse{},
+			})
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/api-keys").
 			Reply(200).
 			JSON([]api.ApiKeyResponse{{Name: "anon", ApiKey: "anon-key"}})
 		// Link configs
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/database/postgres").
+			ReplyError(errors.New("network error"))
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/postgrest").
 			ReplyError(errors.New("network error"))
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/auth").
+			ReplyError(errors.New("network error"))
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/storage").
+			ReplyError(errors.New("network error"))
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/config/database/pooler").
 			ReplyError(errors.New("network error"))
@@ -152,9 +166,6 @@ func TestLinkCommand(t *testing.T) {
 		gock.New("https://" + utils.GetSupabaseHost(project)).
 			Get("/storage/v1/version").
 			ReplyError(errors.New("network error"))
-		gock.New(utils.DefaultApiHost).
-			Get("/v1/projects").
-			ReplyError(errors.New("network error"))
 		// Run test
 		err := Run(context.Background(), project, fsys, func(cc *pgx.ConnConfig) {
 			cc.LookupFunc = func(ctx context.Context, host string) (addrs []string, err error) {
@@ -175,15 +186,27 @@ func TestLinkCommand(t *testing.T) {
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project).
 			Reply(200).
-			JSON(api.V1ProjectResponse{Status: api.V1ProjectResponseStatusACTIVEHEALTHY})
+			JSON(api.V1ProjectWithDatabaseResponse{
+				Status:   api.V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY,
+				Database: api.V1DatabaseResponse{},
+			})
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/api-keys").
 			Reply(200).
 			JSON([]api.ApiKeyResponse{{Name: "anon", ApiKey: "anon-key"}})
 		// Link configs
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/database/postgres").
+			ReplyError(errors.New("network error"))
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/postgrest").
 			ReplyError(errors.New("network error"))
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/auth").
+			ReplyError(errors.New("network error"))
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project + "/config/storage").
+			ReplyError(errors.New("network error"))
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project + "/config/database/pooler").
 			ReplyError(errors.New("network error"))
@@ -215,7 +238,32 @@ func TestLinkCommand(t *testing.T) {
 func TestStatusCheck(t *testing.T) {
 	project := "test-project"
 
+	t.Run("updates postgres version when healthy", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		// Flush pending mocks after test execution
+		defer gock.OffAll()
+		// Mock project status
+		gock.New(utils.DefaultApiHost).
+			Get("/v1/projects/" + project).
+			Reply(http.StatusOK).
+			JSON(api.V1ProjectWithDatabaseResponse{
+				Status:   api.V1ProjectWithDatabaseResponseStatusACTIVEHEALTHY,
+				Database: api.V1DatabaseResponse{Version: "15.6.1.139"},
+			})
+		// Run test
+		err := checkRemoteProjectStatus(context.Background(), project, fsys)
+		// Check error
+		assert.NoError(t, err)
+		version, err := afero.ReadFile(fsys, utils.PostgresVersionPath)
+		assert.NoError(t, err)
+		assert.Equal(t, "15.6.1.139", string(version))
+		assert.Empty(t, apitest.ListUnmatchedRequests())
+	})
+
 	t.Run("ignores project not found", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
 		// Flush pending mocks after test execution
 		defer gock.OffAll()
 		// Mock project status
@@ -223,24 +271,32 @@ func TestStatusCheck(t *testing.T) {
 			Get("/v1/projects/" + project).
 			Reply(http.StatusNotFound)
 		// Run test
-		err := checkRemoteProjectStatus(context.Background(), project)
+		err := checkRemoteProjectStatus(context.Background(), project, fsys)
 		// Check error
 		assert.NoError(t, err)
+		exists, err := afero.Exists(fsys, utils.PostgresVersionPath)
+		assert.NoError(t, err)
+		assert.False(t, exists)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 
 	t.Run("throws error on project inactive", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
 		// Flush pending mocks after test execution
 		defer gock.OffAll()
 		// Mock project status
 		gock.New(utils.DefaultApiHost).
 			Get("/v1/projects/" + project).
 			Reply(http.StatusOK).
-			JSON(api.V1ProjectResponse{Status: api.V1ProjectResponseStatusINACTIVE})
+			JSON(api.V1ProjectWithDatabaseResponse{Status: api.V1ProjectWithDatabaseResponseStatusINACTIVE})
 		// Run test
-		err := checkRemoteProjectStatus(context.Background(), project)
+		err := checkRemoteProjectStatus(context.Background(), project, fsys)
 		// Check error
 		assert.ErrorIs(t, err, errProjectPaused)
+		exists, err := afero.Exists(fsys, utils.PostgresVersionPath)
+		assert.NoError(t, err)
+		assert.False(t, exists)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 }
@@ -309,7 +365,7 @@ func TestLinkPostgrest(t *testing.T) {
 		// Run test
 		err := linkPostgrest(context.Background(), project)
 		// Validate api
-		assert.ErrorIs(t, err, tenant.ErrAuthToken)
+		assert.ErrorContains(t, err, `unexpected API config status 500: {"message":"unavailable"}`)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 }
diff --git a/internal/projects/create/create_test.go b/internal/projects/create/create_test.go
index c67c7a35..879421d7 100644
--- a/internal/projects/create/create_test.go
+++ b/internal/projects/create/create_test.go
@@ -14,11 +14,11 @@ import (
 )
 
 func TestProjectCreateCommand(t *testing.T) {
-	var params = api.V1CreateProjectBody{
+	var params = api.V1CreateProjectBodyDto{
 		Name:           "Test Project",
 		OrganizationId: "combined-fuchsia-lion",
 		DbPass:         "redacted",
-		Region:         api.V1CreateProjectBodyRegionUsWest1,
+		Region:         api.V1CreateProjectBodyDtoRegionUsWest1,
 	}
 
 	t.Run("creates a new project", func(t *testing.T) {
diff --git a/pkg/config/auth_test.go b/pkg/config/auth_test.go
index e8d373b9..057c5ccd 100644
--- a/pkg/config/auth_test.go
+++ b/pkg/config/auth_test.go
@@ -18,6 +18,9 @@ func newWithDefaults() auth {
 		Email: email{
 			EnableConfirmations: true,
 		},
+		Sms: sms{
+			TestOTP: map[string]string{},
+		},
 	}
 }
 
@@ -31,33 +34,134 @@ func assertSnapshotEqual(t *testing.T, actual []byte) {
 	assert.Equal(t, string(expected), string(actual))
 }
 
+func TestAuthDiff(t *testing.T) {
+	t.Run("local and remote enabled", func(t *testing.T) {
+		c := newWithDefaults()
+		c.SiteUrl = "http://127.0.0.1:3000"
+		c.AdditionalRedirectUrls = []string{"https://127.0.0.1:3000"}
+		c.JwtExpiry = 3600
+		c.EnableRefreshTokenRotation = true
+		c.RefreshTokenReuseInterval = 10
+		c.EnableManualLinking = true
+		c.EnableSignup = true
+		c.EnableAnonymousSignIns = true
+		c.MinimumPasswordLength = 6
+		c.PasswordRequirements = LettersDigits
+		// Run test
+		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
+			SiteUrl:                           cast.Ptr("http://127.0.0.1:3000"),
+			UriAllowList:                      cast.Ptr("https://127.0.0.1:3000"),
+			JwtExp:                            cast.Ptr(3600),
+			RefreshTokenRotationEnabled:       cast.Ptr(true),
+			SecurityRefreshTokenReuseInterval: cast.Ptr(10),
+			SecurityManualLinkingEnabled:      cast.Ptr(true),
+			DisableSignup:                     cast.Ptr(false),
+			ExternalAnonymousUsersEnabled:     cast.Ptr(true),
+			PasswordMinLength:                 cast.Ptr(6),
+			PasswordRequiredCharacters:        cast.Ptr(string(v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)),
+		})
+		// Check error
+		assert.NoError(t, err)
+		assert.Empty(t, string(diff))
+	})
+
+	t.Run("local enabled and disabled", func(t *testing.T) {
+		c := newWithDefaults()
+		c.SiteUrl = "http://127.0.0.1:3000"
+		c.AdditionalRedirectUrls = []string{"https://127.0.0.1:3000"}
+		c.JwtExpiry = 3600
+		c.EnableRefreshTokenRotation = false
+		c.RefreshTokenReuseInterval = 10
+		c.EnableManualLinking = false
+		c.EnableSignup = false
+		c.EnableAnonymousSignIns = false
+		c.MinimumPasswordLength = 6
+		c.PasswordRequirements = LowerUpperLettersDigitsSymbols
+		// Run test
+		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
+			SiteUrl:                           cast.Ptr(""),
+			UriAllowList:                      cast.Ptr("https://127.0.0.1:3000,https://ref.supabase.co"),
+			JwtExp:                            cast.Ptr(0),
+			RefreshTokenRotationEnabled:       cast.Ptr(true),
+			SecurityRefreshTokenReuseInterval: cast.Ptr(0),
+			SecurityManualLinkingEnabled:      cast.Ptr(true),
+			DisableSignup:                     cast.Ptr(false),
+			ExternalAnonymousUsersEnabled:     cast.Ptr(true),
+			PasswordMinLength:                 cast.Ptr(8),
+			PasswordRequiredCharacters:        cast.Ptr(string(v1API.AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)),
+		})
+		// Check error
+		assert.NoError(t, err)
+		assertSnapshotEqual(t, diff)
+	})
+
+	t.Run("local and remote disabled", func(t *testing.T) {
+		c := newWithDefaults()
+		c.EnableSignup = false
+		// Run test
+		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
+			SiteUrl:                           cast.Ptr(""),
+			UriAllowList:                      cast.Ptr(""),
+			JwtExp:                            cast.Ptr(0),
+			RefreshTokenRotationEnabled:       cast.Ptr(false),
+			SecurityRefreshTokenReuseInterval: cast.Ptr(0),
+			SecurityManualLinkingEnabled:      cast.Ptr(false),
+			DisableSignup:                     cast.Ptr(true),
+			ExternalAnonymousUsersEnabled:     cast.Ptr(false),
+			PasswordMinLength:                 cast.Ptr(0),
+			PasswordRequiredCharacters:        cast.Ptr(""),
+		})
+		// Check error
+		assert.NoError(t, err)
+		assert.Empty(t, string(diff))
+	})
+}
+
 func TestHookDiff(t *testing.T) {
 	t.Run("local and remote enabled", func(t *testing.T) {
 		c := newWithDefaults()
 		c.Hook = hook{
-			CustomAccessToken:           hookConfig{Enabled: true},
-			SendSMS:                     hookConfig{Enabled: true},
-			SendEmail:                   hookConfig{Enabled: true},
-			MFAVerificationAttempt:      hookConfig{Enabled: true},
-			PasswordVerificationAttempt: hookConfig{Enabled: true},
+			CustomAccessToken: hookConfig{
+				Enabled: true,
+				URI:     "http://example.com",
+				Secrets: "test-secret",
+			},
+			SendSMS: hookConfig{
+				Enabled: true,
+				URI:     "http://example.com",
+				Secrets: "test-secret",
+			},
+			SendEmail: hookConfig{
+				Enabled: true,
+				URI:     "https://example.com",
+				Secrets: "test-secret",
+			},
+			MFAVerificationAttempt: hookConfig{
+				Enabled: true,
+				URI:     "https://example.com",
+				Secrets: "test-secret",
+			},
+			PasswordVerificationAttempt: hookConfig{
+				Enabled: true,
+				URI:     "pg-functions://verifyPassword",
+			},
 		}
 		// Run test
 		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
 			HookCustomAccessTokenEnabled:           cast.Ptr(true),
-			HookCustomAccessTokenUri:               cast.Ptr(""),
-			HookCustomAccessTokenSecrets:           cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookCustomAccessTokenUri:               cast.Ptr("http://example.com"),
+			HookCustomAccessTokenSecrets:           cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
 			HookSendEmailEnabled:                   cast.Ptr(true),
-			HookSendEmailUri:                       cast.Ptr(""),
-			HookSendEmailSecrets:                   cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookSendEmailUri:                       cast.Ptr("https://example.com"),
+			HookSendEmailSecrets:                   cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
 			HookSendSmsEnabled:                     cast.Ptr(true),
-			HookSendSmsUri:                         cast.Ptr(""),
-			HookSendSmsSecrets:                     cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookSendSmsUri:                         cast.Ptr("http://example.com"),
+			HookSendSmsSecrets:                     cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
 			HookMfaVerificationAttemptEnabled:      cast.Ptr(true),
-			HookMfaVerificationAttemptUri:          cast.Ptr(""),
-			HookMfaVerificationAttemptSecrets:      cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookMfaVerificationAttemptUri:          cast.Ptr("https://example.com"),
+			HookMfaVerificationAttemptSecrets:      cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
 			HookPasswordVerificationAttemptEnabled: cast.Ptr(true),
-			HookPasswordVerificationAttemptUri:     cast.Ptr(""),
-			HookPasswordVerificationAttemptSecrets: cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookPasswordVerificationAttemptUri:     cast.Ptr("pg-functions://verifyPassword"),
 		})
 		// Check error
 		assert.NoError(t, err)
@@ -67,17 +171,41 @@ func TestHookDiff(t *testing.T) {
 	t.Run("local enabled and disabled", func(t *testing.T) {
 		c := newWithDefaults()
 		c.Hook = hook{
-			CustomAccessToken:      hookConfig{Enabled: true},
-			MFAVerificationAttempt: hookConfig{Enabled: false},
+			CustomAccessToken: hookConfig{
+				Enabled: true,
+				URI:     "http://example.com",
+				Secrets: "test-secret",
+			},
+			SendSMS: hookConfig{
+				Enabled: false,
+				URI:     "https://example.com",
+				Secrets: "test-secret",
+			},
+			SendEmail: hookConfig{
+				Enabled: true,
+				URI:     "pg-functions://sendEmail",
+			},
+			MFAVerificationAttempt: hookConfig{
+				Enabled: false,
+				URI:     "pg-functions://verifyMFA",
+			},
+			PasswordVerificationAttempt: hookConfig{Enabled: false},
 		}
 		// Run test
 		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
-			HookCustomAccessTokenEnabled:      cast.Ptr(false),
-			HookCustomAccessTokenUri:          cast.Ptr(""),
-			HookCustomAccessTokenSecrets:      cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
-			HookMfaVerificationAttemptEnabled: cast.Ptr(true),
-			HookMfaVerificationAttemptUri:     cast.Ptr(""),
-			HookMfaVerificationAttemptSecrets: cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookCustomAccessTokenEnabled:           cast.Ptr(false),
+			HookCustomAccessTokenUri:               cast.Ptr(""),
+			HookCustomAccessTokenSecrets:           cast.Ptr("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+			HookSendEmailEnabled:                   cast.Ptr(false),
+			HookSendEmailUri:                       cast.Ptr(""),
+			HookSendSmsEnabled:                     cast.Ptr(true),
+			HookSendSmsUri:                         cast.Ptr("http://example.com"),
+			HookSendSmsSecrets:                     cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
+			HookMfaVerificationAttemptEnabled:      cast.Ptr(true),
+			HookMfaVerificationAttemptUri:          cast.Ptr("pg-functions://verifyMFA"),
+			HookPasswordVerificationAttemptEnabled: cast.Ptr(true),
+			HookPasswordVerificationAttemptUri:     cast.Ptr("https://example.com"),
+			HookPasswordVerificationAttemptSecrets: cast.Ptr("ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"),
 		})
 		// Check error
 		assert.NoError(t, err)
@@ -563,9 +691,7 @@ func TestSmsDiff(t *testing.T) {
 		// This is not a valid config because platform requires a SMS provider.
 		// For consistency, we handle this in config.Load and emit a warning.
 		c := newWithDefaults()
-		c.Sms = sms{
-			EnableSignup: true,
-		}
+		c.Sms.EnableSignup = true
 		// Run test
 		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
 			ExternalPhoneEnabled: cast.Ptr(false),
@@ -578,11 +704,7 @@ func TestSmsDiff(t *testing.T) {
 
 	t.Run("enable provider without sign up", func(t *testing.T) {
 		c := newWithDefaults()
-		c.Sms = sms{
-			Messagebird: messagebirdConfig{
-				Enabled: true,
-			},
-		}
+		c.Sms.Messagebird.Enabled = true
 		// Run test
 		diff, err := c.DiffWithRemote("", v1API.AuthConfigResponse{
 			ExternalPhoneEnabled:    cast.Ptr(false),
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 8f1169d5..4aa7ce24 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -205,55 +205,74 @@ func TestSigningJWT(t *testing.T) {
 
 func TestValidateHookURI(t *testing.T) {
 	tests := []struct {
-		name      string
-		uri       string
-		hookName  string
-		shouldErr bool
-		errorMsg  string
+		hookConfig
+		name     string
+		errorMsg string
 	}{
 		{
-			name:      "valid http URL",
-			uri:       "http://example.com",
-			hookName:  "testHook",
-			shouldErr: false,
+			name: "valid http URL",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "http://example.com",
+				Secrets: "test-secret",
+			},
 		},
 		{
-			name:      "valid https URL",
-			uri:       "https://example.com",
-			hookName:  "testHook",
-			shouldErr: false,
+			name: "valid https URL",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "https://example.com",
+				Secrets: "test-secret",
+			},
+		},
+		{
+			name: "valid pg-functions URI",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "pg-functions://functionName",
+			},
+		},
+		{
+			name: "invalid URI with unsupported scheme",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "ftp://example.com",
+				Secrets: "test-secret",
+			},
+			errorMsg: "Invalid hook config: auth.hook.invalid URI with unsupported scheme should be a HTTP, HTTPS, or pg-functions URI",
 		},
 		{
-			name:      "valid pg-functions URI",
-			uri:       "pg-functions://functionName",
-			hookName:  "pgHook",
-			shouldErr: false,
+			name: "invalid URI with parsing error",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "http://a b.com",
+				Secrets: "test-secret",
+			},
+			errorMsg: "failed to parse template url: parse \"http://a b.com\": invalid character \" \" in host name",
 		},
 		{
-			name:      "invalid URI with unsupported scheme",
-			uri:       "ftp://example.com",
-			hookName:  "malformedHook",
-			shouldErr: true,
-			errorMsg:  "Invalid HTTP hook config: auth.hook.malformedHook should be a Postgres function URI, or a HTTP or HTTPS URL",
+			name: "valid http URL with missing secrets",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "http://example.com",
+			},
+			errorMsg: "Missing required field in config: auth.hook.valid http URL with missing secrets.secrets",
 		},
 		{
-			name:      "invalid URI with parsing error",
-			uri:       "http://a b.com",
-			hookName:  "errorHook",
-			shouldErr: true,
-			errorMsg:  "failed to parse template url: parse \"http://a b.com\": invalid character \" \" in host name",
+			name: "valid pg-functions URI with unsupported secrets",
+			hookConfig: hookConfig{
+				Enabled: true,
+				URI:     "pg-functions://functionName",
+				Secrets: "test-secret",
+			},
+			errorMsg: "Invalid hook config: auth.hook.valid pg-functions URI with unsupported secrets.secrets is unsupported for pg-functions URI",
 		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			h := hookConfig{
-				Enabled: true,
-				URI:     tt.uri,
-				Secrets: "test-secret",
-			}
-			err := h.validate(tt.hookName)
-			if tt.shouldErr {
+			err := tt.hookConfig.validate(tt.name)
+			if len(tt.errorMsg) > 0 {
 				assert.Error(t, err, "Expected an error for %v", tt.name)
 				assert.EqualError(t, err, tt.errorMsg, "Expected error message does not match for %v", tt.name)
 			} else {
diff --git a/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff
new file mode 100644
index 00000000..3db4d546
--- /dev/null
+++ b/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff
@@ -0,0 +1,28 @@
+diff remote[auth] local[auth]
+--- remote[auth]
++++ local[auth]
+@@ -1,14 +1,14 @@
+ enabled = false
+-site_url = ""
+-additional_redirect_urls = ["https://127.0.0.1:3000", "https://ref.supabase.co"]
+-jwt_expiry = 0
+-enable_refresh_token_rotation = true
+-refresh_token_reuse_interval = 0
+-enable_manual_linking = true
+-enable_signup = true
+-enable_anonymous_sign_ins = true
+-minimum_password_length = 8
+-password_requirements = "letters_digits"
++site_url = "http://127.0.0.1:3000"
++additional_redirect_urls = ["https://127.0.0.1:3000"]
++jwt_expiry = 3600
++enable_refresh_token_rotation = false
++refresh_token_reuse_interval = 10
++enable_manual_linking = false
++enable_signup = false
++enable_anonymous_sign_ins = false
++minimum_password_length = 6
++password_requirements = "lower_upper_letters_digits_symbols"
+ 
+ [hook]
+ [hook.mfa_verification_attempt]
diff --git a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff
index d6c7f6dc..3123336f 100644
--- a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff
+++ b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -49,13 +49,13 @@
+@@ -51,13 +51,13 @@
  inactivity_timeout = "0s"
  
  [email]
@@ -22,7 +22,7 @@ diff remote[auth] local[auth]
  [email.template]
  [email.template.confirmation]
  content_path = ""
-@@ -69,13 +69,6 @@
+@@ -71,13 +71,6 @@
  content_path = ""
  [email.template.recovery]
  content_path = ""
diff --git a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff
index 9bcf8ccb..24386ae9 100644
--- a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff
+++ b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -49,28 +49,43 @@
+@@ -51,28 +51,43 @@
  inactivity_timeout = "0s"
  
  [email]
diff --git a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff
index fcfb3d1d..234e422f 100644
--- a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff
+++ b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -88,7 +88,7 @@
+@@ -91,7 +91,7 @@
  
  [external]
  [external.apple]
@@ -10,7 +10,7 @@ diff remote[auth] local[auth]
  client_id = "test-client-1,test-client-2"
  secret = "hash:ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"
  url = ""
-@@ -144,7 +144,7 @@
+@@ -147,7 +147,7 @@
  redirect_uri = ""
  skip_nonce_check = false
  [external.google]
diff --git a/pkg/config/testdata/TestHookDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestHookDiff/local_enabled_and_disabled.diff
index b45808d4..e3afeb49 100644
--- a/pkg/config/testdata/TestHookDiff/local_enabled_and_disabled.diff
+++ b/pkg/config/testdata/TestHookDiff/local_enabled_and_disabled.diff
@@ -1,21 +1,36 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -9,7 +9,7 @@
+@@ -11,24 +11,24 @@
  
  [hook]
  [hook.mfa_verification_attempt]
 -enabled = true
 +enabled = false
- uri = ""
+ uri = "pg-functions://verifyMFA"
  secrets = ""
  [hook.password_verification_attempt]
-@@ -17,7 +17,7 @@
+-enabled = true
++enabled = false
  uri = ""
  secrets = ""
  [hook.custom_access_token]
 -enabled = false
+-uri = ""
+-secrets = "hash:b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"
 +enabled = true
- uri = ""
- secrets = "hash:b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"
++uri = "http://example.com"
++secrets = "hash:ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"
  [hook.send_sms]
+-enabled = true
++enabled = false
+ uri = "https://example.com"
+ secrets = "test-secret"
+ [hook.send_email]
+-enabled = false
+-uri = ""
++enabled = true
++uri = "pg-functions://sendEmail"
+ secrets = ""
+ 
+ [mfa]
diff --git a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff
index f7935bfa..866ce8fa 100644
--- a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff
+++ b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -30,16 +30,16 @@
+@@ -32,16 +32,16 @@
  secrets = ""
  
  [mfa]
diff --git a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff
index 2e44496f..637a0206 100644
--- a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff
+++ b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -58,7 +58,7 @@
+@@ -60,7 +60,7 @@
  otp_expiry = 0
  
  [sms]
diff --git a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff
index a173a8ad..4348c80b 100644
--- a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff
+++ b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -58,12 +58,12 @@
+@@ -60,12 +60,12 @@
  otp_expiry = 0
  
  [sms]
@@ -19,11 +19,10 @@ diff remote[auth] local[auth]
  account_sid = ""
  message_service_sid = ""
  auth_token = ""
-@@ -85,9 +85,6 @@
- from = ""
+@@ -88,8 +88,6 @@
  api_key = ""
  api_secret = ""
--[sms.test_otp]
+ [sms.test_otp]
 -123 = "456"
 -456 = "123"
  
diff --git a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff
index f9ee1d7f..e29c287e 100644
--- a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff
+++ b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff
@@ -1,7 +1,7 @@
 diff remote[auth] local[auth]
 --- remote[auth]
 +++ local[auth]
-@@ -58,12 +58,12 @@
+@@ -60,12 +60,12 @@
  otp_expiry = 0
  
  [sms]
@@ -19,7 +19,7 @@ diff remote[auth] local[auth]
  account_sid = ""
  message_service_sid = ""
  auth_token = ""
-@@ -73,9 +73,9 @@
+@@ -75,9 +75,9 @@
  message_service_sid = ""
  auth_token = ""
  [sms.messagebird]
@@ -32,11 +32,10 @@ diff remote[auth] local[auth]
  [sms.textlocal]
  enabled = false
  sender = ""
-@@ -85,6 +85,8 @@
- from = ""
+@@ -88,6 +88,7 @@
  api_key = ""
  api_secret = ""
-+[sms.test_otp]
+ [sms.test_otp]
 +123 = "456"
  
  [third_party]
diff --git a/pkg/config/testdata/config.toml b/pkg/config/testdata/config.toml
index 9aba86c3..ce845743 100644
--- a/pkg/config/testdata/config.toml
+++ b/pkg/config/testdata/config.toml
@@ -106,6 +106,11 @@ refresh_token_reuse_interval = 10
 enable_signup = true
 # Allow/disallow testing manual linking of accounts
 enable_manual_linking = true
+# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more.
+minimum_password_length = 6
+# Passwords that do not meet the following requirements will be rejected as weak. Supported values
+# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols`
+password_requirements = ""
 
 [auth.email]
 # Allow/disallow new user signups via email to your project.
@@ -142,7 +147,7 @@ enable_signup = true
 # If enabled, users need to confirm their phone number before signing in.
 enable_confirmations = false
 # Template for sending OTP to users
-template = "Your code is {{ `{{ .Code }}` }} ."
+template = "Your code is {{ `{{ .Code }}` }}"
 # Controls the minimum amount of time that must pass before sending another sms otp.
 max_frequency = "5s"
 
diff --git a/pkg/config/updater_test.go b/pkg/config/updater_test.go
index 3e549e05..471e8496 100644
--- a/pkg/config/updater_test.go
+++ b/pkg/config/updater_test.go
@@ -193,6 +193,7 @@ func TestUpdateAuthConfig(t *testing.T) {
 			Enabled:      true,
 			EnableSignup: true,
 			Email:        email{EnableConfirmations: true},
+			Sms:          sms{TestOTP: map[string]string{}},
 		})
 		// Check result
 		assert.NoError(t, err)