diff --git a/site/package.json b/site/package.json
index 6a8e6ae153658..383d3e0f6457d 100644
--- a/site/package.json
+++ b/site/package.json
@@ -95,6 +95,7 @@
     "ts-prune": "0.10.3",
     "tzdata": "1.0.30",
     "ua-parser-js": "1.0.33",
+    "unique-names-generator": "4.7.1",
     "uuid": "9.0.0",
     "vite": "4.4.2",
     "xstate": "4.38.1",
diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx
index 6aa5fe32b83e8..b34ff6fd97939 100644
--- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx
+++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx
@@ -12,6 +12,7 @@ import {
   MockTemplateVersionParameter2,
   MockTemplateVersionParameter3,
   MockTemplateVersionGitAuth,
+  MockOrganization,
 } from "testHelpers/entities"
 import {
   renderWithAuth,
@@ -217,4 +218,29 @@ describe("CreateWorkspacePage", () => {
 
     await screen.findByText("You must authenticate to create a workspace!")
   })
+
+  it("auto create a workspace if uses mode=auto", async () => {
+    const param = "first_parameter"
+    const paramValue = "It works!"
+    const createWorkspaceSpy = jest.spyOn(API, "createWorkspace")
+
+    renderWithAuth(<CreateWorkspacePage />, {
+      route:
+        "/templates/" +
+        MockTemplate.name +
+        `/workspace?param.${param}=${paramValue}&mode=auto`,
+      path: "/templates/:template/workspace",
+    })
+
+    await waitFor(() => {
+      expect(createWorkspaceSpy).toBeCalledWith(
+        MockOrganization.id,
+        "me",
+        expect.objectContaining({
+          template_id: MockTemplate.id,
+          rich_parameter_values: [{ name: param, value: paramValue }],
+        }),
+      )
+    })
+  })
 })
diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx
index 613655961582e..d49ea38894ed9 100644
--- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx
+++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx
@@ -1,27 +1,47 @@
 import { useMachine } from "@xstate/react"
-import { TemplateVersionParameter } from "api/typesGenerated"
+import {
+  Template,
+  TemplateVersionGitAuth,
+  TemplateVersionParameter,
+  WorkspaceBuildParameter,
+} from "api/typesGenerated"
 import { useMe } from "hooks/useMe"
 import { useOrganizationId } from "hooks/useOrganizationId"
 import { FC } from "react"
 import { Helmet } from "react-helmet-async"
 import { useNavigate, useParams, useSearchParams } from "react-router-dom"
 import { pageTitle } from "utils/page"
-import { createWorkspaceMachine } from "xServices/createWorkspace/createWorkspaceXService"
 import {
-  CreateWorkspaceErrors,
-  CreateWorkspacePageView,
-} from "./CreateWorkspacePageView"
+  CreateWSPermissions,
+  CreateWorkspaceMode,
+  createWorkspaceMachine,
+} from "xServices/createWorkspace/createWorkspaceXService"
+import { CreateWorkspacePageView } from "./CreateWorkspacePageView"
+import { Loader } from "components/Loader/Loader"
+import { ErrorAlert } from "components/Alert/ErrorAlert"
+import {
+  uniqueNamesGenerator,
+  animals,
+  colors,
+  NumberDictionary,
+} from "unique-names-generator"
 
 const CreateWorkspacePage: FC = () => {
   const organizationId = useOrganizationId()
   const { template: templateName } = useParams() as { template: string }
-  const navigate = useNavigate()
   const me = useMe()
+  const navigate = useNavigate()
+  const [searchParams] = useSearchParams()
+  const defaultBuildParameters = getDefaultBuildParameters(searchParams)
+  const mode = (searchParams.get("mode") ?? "form") as CreateWorkspaceMode
   const [createWorkspaceState, send] = useMachine(createWorkspaceMachine, {
     context: {
       organizationId,
       templateName,
-      owner: me,
+      mode,
+      defaultBuildParameters,
+      defaultName:
+        mode === "auto" ? generateUniqueName() : searchParams.get("name") ?? "",
     },
     actions: {
       onCreateWorkspace: (_, event) => {
@@ -29,83 +49,65 @@ const CreateWorkspacePage: FC = () => {
       },
     },
   })
-  const {
-    templates,
-    templateParameters,
-    templateGitAuth,
-    selectedTemplate,
-    getTemplateGitAuthError,
-    getTemplatesError,
-    createWorkspaceError,
-    permissions,
-    owner,
-  } = createWorkspaceState.context
-  const [searchParams] = useSearchParams()
-  const defaultParameterValues = getDefaultParameterValues(searchParams)
-  const name = getName(searchParams)
+  const { template, error, parameters, permissions, gitAuth, defaultName } =
+    createWorkspaceState.context
+  const title = createWorkspaceState.matches("autoCreating")
+    ? "Creating workspace..."
+    : "Create Workspace"
 
   return (
     <>
       <Helmet>
-        <title>{pageTitle("Create Workspace")}</title>
+        <title>{pageTitle(title)}</title>
       </Helmet>
-      <CreateWorkspacePageView
-        name={name}
-        defaultParameterValues={defaultParameterValues}
-        loadingTemplates={createWorkspaceState.matches("gettingTemplates")}
-        creatingWorkspace={createWorkspaceState.matches("creatingWorkspace")}
-        hasTemplateErrors={createWorkspaceState.matches("error")}
-        templateName={templateName}
-        templates={templates}
-        selectedTemplate={selectedTemplate}
-        templateParameters={orderedTemplateParameters(templateParameters)}
-        templateGitAuth={templateGitAuth}
-        createWorkspaceErrors={{
-          [CreateWorkspaceErrors.GET_TEMPLATES_ERROR]: getTemplatesError,
-          [CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR]: createWorkspaceError,
-          [CreateWorkspaceErrors.GET_TEMPLATE_GITAUTH_ERROR]:
-            getTemplateGitAuthError,
-        }}
-        canCreateForUser={permissions?.createWorkspaceForUser}
-        owner={owner}
-        setOwner={(user) => {
-          send({
-            type: "SELECT_OWNER",
-            owner: user,
-          })
-        }}
-        onCancel={() => {
-          // Go back
-          navigate(-1)
-        }}
-        onSubmit={(request) => {
-          send({
-            type: "CREATE_WORKSPACE",
-            request,
-            owner,
-          })
-        }}
-      />
+      {Boolean(
+        createWorkspaceState.matches("loadingFormData") ||
+          createWorkspaceState.matches("autoCreating"),
+      ) && <Loader />}
+      {createWorkspaceState.matches("loadError") && (
+        <ErrorAlert error={error} />
+      )}
+      {createWorkspaceState.matches("idle") && (
+        <CreateWorkspacePageView
+          defaultName={defaultName}
+          defaultOwner={me}
+          defaultBuildParameters={defaultBuildParameters}
+          error={error}
+          template={template as Template}
+          gitAuth={gitAuth as TemplateVersionGitAuth[]}
+          permissions={permissions as CreateWSPermissions}
+          parameters={parameters as TemplateVersionParameter[]}
+          creatingWorkspace={createWorkspaceState.matches("creatingWorkspace")}
+          onCancel={() => {
+            navigate(-1)
+          }}
+          onSubmit={(request, owner) => {
+            send({
+              type: "CREATE_WORKSPACE",
+              request,
+              owner,
+            })
+          }}
+        />
+      )}
     </>
   )
 }
 
-const getName = (urlSearchParams: URLSearchParams): string => {
-  return urlSearchParams.get("name") ?? ""
-}
+export default CreateWorkspacePage
 
-const getDefaultParameterValues = (
+const getDefaultBuildParameters = (
   urlSearchParams: URLSearchParams,
-): Record<string, string> => {
-  const paramValues: Record<string, string> = {}
+): WorkspaceBuildParameter[] => {
+  const buildValues: WorkspaceBuildParameter[] = []
   Array.from(urlSearchParams.keys())
     .filter((key) => key.startsWith("param."))
     .forEach((key) => {
-      const paramName = key.replace("param.", "")
-      const paramValue = urlSearchParams.get(key)
-      paramValues[paramName] = paramValue ?? ""
+      const name = key.replace("param.", "")
+      const value = urlSearchParams.get(key) ?? ""
+      buildValues.push({ name, value })
     })
-  return paramValues
+  return buildValues
 }
 
 export const orderedTemplateParameters = (
@@ -122,4 +124,12 @@ export const orderedTemplateParameters = (
   return [...immutables, ...mutables]
 }
 
-export default CreateWorkspacePage
+const generateUniqueName = () => {
+  const numberDictionary = NumberDictionary.generate({ min: 0, max: 99 })
+  return uniqueNamesGenerator({
+    dictionaries: [colors, animals, numberDictionary],
+    separator: "-",
+    length: 3,
+    style: "lowerCase",
+  })
+}
diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
index 94ac17a40d9c7..51cfc8c69b66f 100644
--- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
+++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
@@ -1,64 +1,38 @@
-import { ComponentMeta, Story } from "@storybook/react"
+import { Meta, StoryObj } from "@storybook/react"
 import {
   mockApiError,
   MockTemplate,
   MockTemplateVersionParameter1,
   MockTemplateVersionParameter2,
   MockTemplateVersionParameter3,
+  MockUser,
 } from "../../testHelpers/entities"
-import {
-  CreateWorkspaceErrors,
-  CreateWorkspacePageView,
-  CreateWorkspacePageViewProps,
-} from "./CreateWorkspacePageView"
+import { CreateWorkspacePageView } from "./CreateWorkspacePageView"
 
-export default {
-  title: "pages/CreateWorkspacePageView",
+const meta: Meta<typeof CreateWorkspacePageView> = {
+  title: "components/Alert",
   component: CreateWorkspacePageView,
-} as ComponentMeta<typeof CreateWorkspacePageView>
-
-const Template: Story<CreateWorkspacePageViewProps> = (args) => (
-  <CreateWorkspacePageView {...args} />
-)
-
-export const NoParameters = Template.bind({})
-NoParameters.args = {
-  templates: [MockTemplate],
-  selectedTemplate: MockTemplate,
-  createWorkspaceErrors: {},
-}
-
-export const Parameters = Template.bind({})
-Parameters.args = {
-  templates: [MockTemplate],
-  selectedTemplate: MockTemplate,
-  createWorkspaceErrors: {},
+  args: {
+    defaultName: "",
+    defaultOwner: MockUser,
+    defaultBuildParameters: [],
+    template: MockTemplate,
+    parameters: [],
+    gitAuth: [],
+    permissions: {
+      createWorkspaceForUser: true,
+    },
+  },
 }
 
-export const RedisplayParameters = Template.bind({})
-RedisplayParameters.args = {
-  templates: [MockTemplate],
-  selectedTemplate: MockTemplate,
-  createWorkspaceErrors: {},
-}
+export default meta
+type Story = StoryObj<typeof CreateWorkspacePageView>
 
-export const GetTemplatesError = Template.bind({})
-GetTemplatesError.args = {
-  ...Parameters.args,
-  createWorkspaceErrors: {
-    [CreateWorkspaceErrors.GET_TEMPLATES_ERROR]: mockApiError({
-      message: "Failed to fetch templates.",
-      detail: "You do not have permission to access this resource.",
-    }),
-  },
-  hasTemplateErrors: true,
-}
+export const NoParameters: Story = {}
 
-export const CreateWorkspaceError = Template.bind({})
-CreateWorkspaceError.args = {
-  ...Parameters.args,
-  createWorkspaceErrors: {
-    [CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR]: mockApiError({
+export const CreateWorkspaceError: Story = {
+  args: {
+    error: mockApiError({
       message:
         'Workspace "test" already exists in the "docker-amd64" template.',
       validations: [
@@ -69,72 +43,64 @@ CreateWorkspaceError.args = {
       ],
     }),
   },
-  initialTouched: {
-    name: true,
-  },
 }
 
-export const RichParameters = Template.bind({})
-RichParameters.args = {
-  templates: [MockTemplate],
-  selectedTemplate: MockTemplate,
-  templateParameters: [
-    MockTemplateVersionParameter1,
-    MockTemplateVersionParameter2,
-    MockTemplateVersionParameter3,
-    {
-      name: "Region",
-      required: false,
-      description: "",
-      description_plaintext: "",
-      type: "string",
-      mutable: false,
-      default_value: "",
-      icon: "/emojis/1f30e.png",
-      options: [
-        {
-          name: "Pittsburgh",
-          description: "",
-          value: "us-pittsburgh",
-          icon: "/emojis/1f1fa-1f1f8.png",
-        },
-        {
-          name: "Helsinki",
-          description: "",
-          value: "eu-helsinki",
-          icon: "/emojis/1f1eb-1f1ee.png",
-        },
-        {
-          name: "Sydney",
-          description: "",
-          value: "ap-sydney",
-          icon: "/emojis/1f1e6-1f1fa.png",
-        },
-      ],
-      ephemeral: false,
-    },
-  ],
-  createWorkspaceErrors: {},
+export const Parameters: Story = {
+  args: {
+    parameters: [
+      MockTemplateVersionParameter1,
+      MockTemplateVersionParameter2,
+      MockTemplateVersionParameter3,
+      {
+        name: "Region",
+        required: false,
+        description: "",
+        description_plaintext: "",
+        type: "string",
+        mutable: false,
+        default_value: "",
+        icon: "/emojis/1f30e.png",
+        options: [
+          {
+            name: "Pittsburgh",
+            description: "",
+            value: "us-pittsburgh",
+            icon: "/emojis/1f1fa-1f1f8.png",
+          },
+          {
+            name: "Helsinki",
+            description: "",
+            value: "eu-helsinki",
+            icon: "/emojis/1f1eb-1f1ee.png",
+          },
+          {
+            name: "Sydney",
+            description: "",
+            value: "ap-sydney",
+            icon: "/emojis/1f1e6-1f1fa.png",
+          },
+        ],
+        ephemeral: false,
+      },
+    ],
+  },
 }
 
-export const GitAuth = Template.bind({})
-GitAuth.args = {
-  templates: [MockTemplate],
-  selectedTemplate: MockTemplate,
-  createWorkspaceErrors: {},
-  templateParameters: [],
-  templateGitAuth: [
-    {
-      id: "github",
-      type: "github",
-      authenticated: false,
-      authenticate_url: "",
-    },
-    {
-      id: "gitlab",
-      type: "gitlab",
-      authenticated: true,
-      authenticate_url: "",
-    },
-  ],
+export const GitAuth: Story = {
+  args: {
+    gitAuth: [
+      {
+        id: "github",
+        type: "github",
+        authenticated: false,
+        authenticate_url: "",
+      },
+      {
+        id: "gitlab",
+        type: "gitlab",
+        authenticated: true,
+        authenticate_url: "",
+      },
+    ],
+  },
 }
diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
index eee8f4875990d..ecc16b9b5ce97 100644
--- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
+++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
@@ -1,16 +1,13 @@
 import TextField from "@mui/material/TextField"
 import * as TypesGen from "api/typesGenerated"
-import { Stack } from "components/Stack/Stack"
 import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete"
-import { FormikContextType, FormikTouched, useFormik } from "formik"
+import { FormikContextType, useFormik } from "formik"
 import { FC, useEffect, useState } from "react"
 import { useTranslation } from "react-i18next"
 import { getFormHelpers, nameValidator, onChangeTrimmed } from "utils/formUtils"
 import * as Yup from "yup"
 import { FullPageHorizontalForm } from "components/FullPageForm/FullPageHorizontalForm"
 import { SelectedTemplate } from "./SelectedTemplate"
-import { Loader } from "components/Loader/Loader"
-import { GitAuth } from "components/GitAuth/GitAuth"
 import {
   FormFields,
   FormSection,
@@ -27,171 +24,92 @@ import {
   ImmutableTemplateParametersSection,
   MutableTemplateParametersSection,
 } from "components/TemplateParameters/TemplateParameters"
+import { CreateWSPermissions } from "xServices/createWorkspace/createWorkspaceXService"
+import { GitAuth } from "components/GitAuth/GitAuth"
 import { ErrorAlert } from "components/Alert/ErrorAlert"
-import { paramUsedToCreateWorkspace } from "utils/workspace"
-
-export enum CreateWorkspaceErrors {
-  GET_TEMPLATES_ERROR = "getTemplatesError",
-  GET_TEMPLATE_GITAUTH_ERROR = "getTemplateGitAuthError",
-  CREATE_WORKSPACE_ERROR = "createWorkspaceError",
-}
 
 export interface CreateWorkspacePageViewProps {
-  name: string
-  loadingTemplates: boolean
+  error: unknown
+  defaultName: string
+  defaultOwner: TypesGen.User
+  template: TypesGen.Template
+  gitAuth: TypesGen.TemplateVersionGitAuth[]
+  parameters: TypesGen.TemplateVersionParameter[]
+  defaultBuildParameters: TypesGen.WorkspaceBuildParameter[]
+  permissions: CreateWSPermissions
   creatingWorkspace: boolean
-  hasTemplateErrors: boolean
-  templateName: string
-  templates?: TypesGen.Template[]
-  selectedTemplate?: TypesGen.Template
-  templateParameters?: TypesGen.TemplateVersionParameter[]
-  templateGitAuth?: TypesGen.TemplateVersionGitAuth[]
-  createWorkspaceErrors: Partial<Record<CreateWorkspaceErrors, Error | unknown>>
-  canCreateForUser?: boolean
-  owner: TypesGen.User | null
-  setOwner: (arg0: TypesGen.User | null) => void
   onCancel: () => void
-  onSubmit: (req: TypesGen.CreateWorkspaceRequest) => void
-  // initialTouched is only used for testing the error state of the form.
-  initialTouched?: FormikTouched<TypesGen.CreateWorkspaceRequest>
-  defaultParameterValues?: Record<string, string>
+  onSubmit: (req: TypesGen.CreateWorkspaceRequest, owner: TypesGen.User) => void
 }
 
-export const CreateWorkspacePageView: FC<
-  React.PropsWithChildren<CreateWorkspacePageViewProps>
-> = (props) => {
-  const templateParameters = props.templateParameters?.filter(
-    paramUsedToCreateWorkspace,
-  )
+export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
+  error,
+  defaultName,
+  defaultOwner,
+  template,
+  gitAuth,
+  parameters,
+  defaultBuildParameters,
+  permissions,
+  creatingWorkspace,
+  onSubmit,
+  onCancel,
+}) => {
   const initialRichParameterValues = selectInitialRichParametersValues(
-    templateParameters,
-    props.defaultParameterValues,
+    parameters,
+    defaultBuildParameters,
   )
-  const [gitAuthErrors, setGitAuthErrors] = useState<Record<string, string>>({})
-  useEffect(() => {
-    // templateGitAuth is refreshed automatically using a BroadcastChannel
-    // which may change the `authenticated` property.
-    //
-    // If the provider becomes authenticated, we want the error message
-    // to disappear.
-    setGitAuthErrors({})
-  }, [props.templateGitAuth])
-  const workspaceErrors =
-    props.createWorkspaceErrors[CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR]
-  // Scroll to top of page if errors are present
-  useEffect(() => {
-    if (props.hasTemplateErrors || Boolean(workspaceErrors)) {
-      window.scrollTo(0, 0)
-    }
-  }, [props.hasTemplateErrors, workspaceErrors])
   const { t } = useTranslation("createWorkspacePage")
   const styles = useStyles()
+  const [owner, setOwner] = useState(defaultOwner)
+  const { verifyGitAuth, gitAuthErrors } = useGitAuthVerification(gitAuth)
   const form: FormikContextType<TypesGen.CreateWorkspaceRequest> =
     useFormik<TypesGen.CreateWorkspaceRequest>({
       initialValues: {
-        name: props.name,
-        template_id: props.selectedTemplate ? props.selectedTemplate.id : "",
+        name: defaultName,
+        template_id: template.id,
         rich_parameter_values: initialRichParameterValues,
       },
       validationSchema: Yup.object({
         name: nameValidator(t("nameLabel", { ns: "createWorkspacePage" })),
         rich_parameter_values: useValidationSchemaForRichParameters(
           "createWorkspacePage",
-          templateParameters,
+          parameters,
         ),
       }),
       enableReinitialize: true,
-      initialTouched: props.initialTouched,
       onSubmit: (request) => {
-        for (let i = 0; i < (props.templateGitAuth?.length || 0); i++) {
-          const auth = props.templateGitAuth?.[i]
-          if (!auth) {
-            continue
-          }
-          if (!auth.authenticated) {
-            setGitAuthErrors({
-              [auth.id]: "You must authenticate to create a workspace!",
-            })
-            form.setSubmitting(false)
-            return
-          }
+        if (!verifyGitAuth()) {
+          form.setSubmitting(false)
+          return
         }
-        props.onSubmit({
-          ...request,
-        })
-        form.setSubmitting(false)
+
+        onSubmit(request, owner)
       },
     })
 
-  const isLoading = props.loadingTemplates
+  useEffect(() => {
+    if (error) {
+      window.scrollTo(0, 0)
+    }
+  }, [error])
 
   const getFieldHelpers = getFormHelpers<TypesGen.CreateWorkspaceRequest>(
     form,
-    props.createWorkspaceErrors[CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR],
+    error,
   )
 
-  if (isLoading) {
-    return <Loader />
-  }
-
   return (
-    <FullPageHorizontalForm title="New workspace" onCancel={props.onCancel}>
+    <FullPageHorizontalForm title="New workspace" onCancel={onCancel}>
       <HorizontalForm onSubmit={form.handleSubmit}>
-        {Boolean(props.hasTemplateErrors) && (
-          <Stack>
-            {Boolean(
-              props.createWorkspaceErrors[
-                CreateWorkspaceErrors.GET_TEMPLATES_ERROR
-              ],
-            ) && (
-              <ErrorAlert
-                error={
-                  props.createWorkspaceErrors[
-                    CreateWorkspaceErrors.GET_TEMPLATES_ERROR
-                  ]
-                }
-              />
-            )}
-            {Boolean(
-              props.createWorkspaceErrors[
-                CreateWorkspaceErrors.GET_TEMPLATE_GITAUTH_ERROR
-              ],
-            ) && (
-              <ErrorAlert
-                error={
-                  props.createWorkspaceErrors[
-                    CreateWorkspaceErrors.GET_TEMPLATE_GITAUTH_ERROR
-                  ]
-                }
-              />
-            )}
-          </Stack>
-        )}
-
-        {Boolean(
-          props.createWorkspaceErrors[
-            CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR
-          ],
-        ) && (
-          <ErrorAlert
-            error={
-              props.createWorkspaceErrors[
-                CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR
-              ]
-            }
-          />
-        )}
-
+        {Boolean(error) && <ErrorAlert error={error} />}
         {/* General info */}
         <FormSection
           title="General"
           description="The template and name of your new workspace."
         >
           <FormFields>
-            {props.selectedTemplate && (
-              <SelectedTemplate template={props.selectedTemplate} />
-            )}
-
+            <SelectedTemplate template={template} />
             <TextField
               {...getFieldHelpers("name")}
               disabled={form.isSubmitting}
@@ -203,16 +121,17 @@ export const CreateWorkspacePageView: FC<
           </FormFields>
         </FormSection>
 
-        {/* Workspace owner */}
-        {props.canCreateForUser && (
+        {permissions.createWorkspaceForUser && (
           <FormSection
             title="Workspace Owner"
             description="Only admins can create workspace for other users."
           >
             <FormFields>
               <UserAutocomplete
-                value={props.owner}
-                onChange={props.setOwner}
+                value={owner}
+                onChange={(user) => {
+                  setOwner(user ?? defaultOwner)
+                }}
                 label={t("ownerLabel").toString()}
                 size="medium"
               />
@@ -220,14 +139,13 @@ export const CreateWorkspacePageView: FC<
           </FormSection>
         )}
 
-        {/* Template git auth */}
-        {props.templateGitAuth && props.templateGitAuth.length > 0 && (
+        {gitAuth && gitAuth.length > 0 && (
           <FormSection
             title="Git Authentication"
             description="This template requires authentication to automatically perform Git operations on create."
           >
             <FormFields>
-              {props.templateGitAuth.map((auth, index) => (
+              {gitAuth.map((auth, index) => (
                 <GitAuth
                   key={index}
                   authenticateURL={auth.authenticate_url}
@@ -240,10 +158,10 @@ export const CreateWorkspacePageView: FC<
           </FormSection>
         )}
 
-        {templateParameters && (
+        {parameters && (
           <>
             <MutableTemplateParametersSection
-              templateParameters={templateParameters}
+              templateParameters={parameters}
               getInputProps={(parameter, index) => {
                 return {
                   ...getFieldHelpers(
@@ -264,7 +182,7 @@ export const CreateWorkspacePageView: FC<
               }}
             />
             <ImmutableTemplateParametersSection
-              templateParameters={templateParameters}
+              templateParameters={parameters}
               classes={{ root: styles.warningSection }}
               getInputProps={(parameter, index) => {
                 return {
@@ -289,8 +207,8 @@ export const CreateWorkspacePageView: FC<
         )}
 
         <FormFooter
-          onCancel={props.onCancel}
-          isLoading={props.creatingWorkspace}
+          onCancel={onCancel}
+          isLoading={creatingWorkspace}
           submitLabel={t("createWorkspace").toString()}
         />
       </HorizontalForm>
@@ -298,6 +216,44 @@ export const CreateWorkspacePageView: FC<
   )
 }
 
+type GitAuthErrors = Record<string, string>
+
+const useGitAuthVerification = (gitAuth: TypesGen.TemplateVersionGitAuth[]) => {
+  const [gitAuthErrors, setGitAuthErrors] = useState<GitAuthErrors>({})
+
+  useEffect(() => {
+    // templateGitAuth is refreshed automatically using a BroadcastChannel
+    // which may change the `authenticated` property.
+    //
+    // If the provider becomes authenticated, we want the error message
+    // to disappear.
+    setGitAuthErrors({})
+  }, [gitAuth])
+
+  const verifyGitAuth = () => {
+    const errors: GitAuthErrors = {}
+
+    for (let i = 0; i < gitAuth.length; i++) {
+      const auth = gitAuth.at(i)
+      if (!auth) {
+        continue
+      }
+      if (!auth.authenticated) {
+        errors[auth.id] = "You must authenticate to create a workspace!"
+      }
+    }
+
+    setGitAuthErrors(errors)
+    const isValid = Object.keys(errors).length === 0
+    return isValid
+  }
+
+  return {
+    gitAuthErrors,
+    verifyGitAuth,
+  }
+}
+
 const useStyles = makeStyles((theme) => ({
   warningText: {
     color: theme.palette.warning.light,
diff --git a/site/src/pages/GitAuthPage/GitAuthPage.tsx b/site/src/pages/GitAuthPage/GitAuthPage.tsx
index 97013b7b13fb4..efe62ad6a9f25 100644
--- a/site/src/pages/GitAuthPage/GitAuthPage.tsx
+++ b/site/src/pages/GitAuthPage/GitAuthPage.tsx
@@ -7,10 +7,10 @@ import {
 import { usePermissions } from "hooks"
 import { FC, useEffect } from "react"
 import { useParams } from "react-router-dom"
-import { REFRESH_GITAUTH_BROADCAST_CHANNEL } from "xServices/createWorkspace/createWorkspaceXService"
 import GitAuthPageView from "./GitAuthPageView"
 import { ApiErrorResponse } from "api/errors"
 import { isAxiosError } from "axios"
+import { REFRESH_GITAUTH_BROADCAST_CHANNEL } from "utils/gitAuth"
 
 const GitAuthPage: FC = () => {
   const { provider } = useParams()
@@ -58,7 +58,6 @@ const GitAuthPage: FC = () => {
     }
     // This is used to notify the parent window that the Git auth token has been refreshed.
     // It's critical in the create workspace flow!
-    // eslint-disable-next-line compat/compat -- It actually is supported... not sure why it's complaining.
     const bc = new BroadcastChannel(REFRESH_GITAUTH_BROADCAST_CHANNEL)
     // The message doesn't matter, any message refreshes the page!
     bc.postMessage("noop")
diff --git a/site/src/pages/GitAuthPage/GitAuthPageView.tsx b/site/src/pages/GitAuthPage/GitAuthPageView.tsx
index 4bf1acded55ba..ce46539ac366a 100644
--- a/site/src/pages/GitAuthPage/GitAuthPageView.tsx
+++ b/site/src/pages/GitAuthPage/GitAuthPageView.tsx
@@ -12,7 +12,7 @@ import { CopyButton } from "components/CopyButton/CopyButton"
 import { SignInLayout } from "components/SignInLayout/SignInLayout"
 import { Welcome } from "components/Welcome/Welcome"
 import { FC, useEffect } from "react"
-import { REFRESH_GITAUTH_BROADCAST_CHANNEL } from "xServices/createWorkspace/createWorkspaceXService"
+import { REFRESH_GITAUTH_BROADCAST_CHANNEL } from "utils/gitAuth"
 
 export interface GitAuthPageViewProps {
   gitAuth: GitAuth
diff --git a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.test.tsx b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.test.tsx
index 7da5ae0555940..898e89efeb24f 100644
--- a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.test.tsx
+++ b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.test.tsx
@@ -47,6 +47,6 @@ test("Users can fill the parameters and copy the open in coder url", async () =>
   const copyButton = screen.getByRole("button", { name: /copy/i })
   await userEvent.click(copyButton)
   expect(window.navigator.clipboard.writeText).toBeCalledWith(
-    `[![Open in Coder](http://localhost/open-in-coder.svg)](http://localhost/templates/test-template/workspace?param.first_parameter=firstParameterValue&param.second_parameter=123456)`,
+    `[![Open in Coder](http://localhost/open-in-coder.svg)](http://localhost/templates/test-template/workspace?mode=manual&param.first_parameter=firstParameterValue&param.second_parameter=123456)`,
   )
 })
diff --git a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.tsx b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.tsx
index 8874bc8d2bed0..32b9ffcd39afc 100644
--- a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.tsx
+++ b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.tsx
@@ -2,10 +2,13 @@ import CheckOutlined from "@mui/icons-material/CheckOutlined"
 import FileCopyOutlined from "@mui/icons-material/FileCopyOutlined"
 import Box from "@mui/material/Box"
 import Button from "@mui/material/Button"
+import FormControlLabel from "@mui/material/FormControlLabel"
+import Radio from "@mui/material/Radio"
+import RadioGroup from "@mui/material/RadioGroup"
 import { useQuery } from "@tanstack/react-query"
 import { getTemplateVersionRichParameters } from "api/api"
 import { Template, TemplateVersionParameter } from "api/typesGenerated"
-import { VerticalForm } from "components/Form/Form"
+import { FormSection, VerticalForm } from "components/Form/Form"
 import { Loader } from "components/Loader/Loader"
 import { useTemplateLayoutContext } from "components/TemplateLayout/TemplateLayout"
 import {
@@ -21,7 +24,7 @@ import {
   selectInitialRichParametersValues,
   workspaceBuildParameterValue,
 } from "utils/richParameters"
-import { paramUsedToCreateWorkspace } from "utils/workspace"
+import { paramsUsedToCreateWorkspace } from "utils/workspace"
 
 type ButtonValues = Record<string, string>
 
@@ -40,7 +43,7 @@ const TemplateEmbedPage = () => {
       <TemplateEmbedPageView
         template={template}
         templateParameters={templateParameters?.filter(
-          paramUsedToCreateWorkspace,
+          paramsUsedToCreateWorkspace,
         )}
       />
     </>
@@ -51,7 +54,9 @@ export const TemplateEmbedPageView: FC<{
   template: Template
   templateParameters?: TemplateVersionParameter[]
 }> = ({ template, templateParameters }) => {
-  const [buttonValues, setButtonValues] = useState<ButtonValues>({})
+  const [buttonValues, setButtonValues] = useState<ButtonValues>({
+    mode: "manual",
+  })
   const initialRichParametersValues = templateParameters
     ? selectInitialRichParametersValues(templateParameters)
     : undefined
@@ -92,20 +97,48 @@ export const TemplateEmbedPageView: FC<{
         <Loader />
       ) : (
         <Box display="flex" alignItems="flex-start" gap={6}>
-          {templateParameters.length > 0 && (
-            <Box flex={1} maxWidth={400}>
-              <VerticalForm>
-                <MutableTemplateParametersSection
-                  templateParameters={templateParameters}
-                  getInputProps={getInputProps}
-                />
-                <ImmutableTemplateParametersSection
-                  templateParameters={templateParameters}
-                  getInputProps={getInputProps}
-                />
-              </VerticalForm>
-            </Box>
-          )}
+          <Box flex={1} maxWidth={400}>
+            <VerticalForm>
+              <FormSection
+                title="Creation mode"
+                description="By changing the mode to automatic, when the user clicks the button, the workspace will be created automatically instead of showing a form to the user."
+              >
+                <RadioGroup
+                  defaultValue={buttonValues.mode}
+                  onChange={(_, v) => {
+                    setButtonValues((buttonValues) => ({
+                      ...buttonValues,
+                      mode: v,
+                    }))
+                  }}
+                >
+                  <FormControlLabel
+                    value="manual"
+                    control={<Radio size="small" />}
+                    label="Manual"
+                  />
+                  <FormControlLabel
+                    value="auto"
+                    control={<Radio size="small" />}
+                    label="Automatic"
+                  />
+                </RadioGroup>
+              </FormSection>
+
+              {templateParameters.length > 0 && (
+                <>
+                  <MutableTemplateParametersSection
+                    templateParameters={templateParameters}
+                    getInputProps={getInputProps}
+                  />
+                  <ImmutableTemplateParametersSection
+                    templateParameters={templateParameters}
+                    getInputProps={getInputProps}
+                  />
+                </>
+              )}
+            </VerticalForm>
+          </Box>
           <Box
             display="flex"
             height={{
diff --git a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPageView.stories.tsx b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPageView.stories.tsx
index f1330ab0b0727..39860cccb78d9 100644
--- a/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPageView.stories.tsx
+++ b/site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPageView.stories.tsx
@@ -20,7 +20,7 @@ const meta: Meta<typeof TemplateEmbedPageView> = {
 export default meta
 type Story = StoryObj<typeof TemplateEmbedPageView>
 
-export const Empty: Story = {
+export const NoParameters: Story = {
   args: {
     templateParameters: [],
   },
diff --git a/site/src/utils/gitAuth.ts b/site/src/utils/gitAuth.ts
new file mode 100644
index 0000000000000..11a15668f1bc0
--- /dev/null
+++ b/site/src/utils/gitAuth.ts
@@ -0,0 +1 @@
+export const REFRESH_GITAUTH_BROADCAST_CHANNEL = "gitauth_refresh"
diff --git a/site/src/utils/richParameters.test.ts b/site/src/utils/richParameters.test.ts
new file mode 100644
index 0000000000000..66ccb3ac6b068
--- /dev/null
+++ b/site/src/utils/richParameters.test.ts
@@ -0,0 +1,53 @@
+import { TemplateVersionParameter } from "api/typesGenerated"
+import { selectInitialRichParametersValues } from "./richParameters"
+
+test("selectInitialRichParametersValues return default value when default build parameter is not valid", () => {
+  const templateParameters: TemplateVersionParameter[] = [
+    {
+      name: "cpu",
+      display_name: "CPU",
+      description: "The number of CPU cores",
+      description_plaintext: "The number of CPU cores",
+      type: "string",
+      mutable: true,
+      default_value: "2",
+      icon: "/icon/memory.svg",
+      options: [
+        {
+          name: "2 Cores",
+          description: "",
+          value: "2",
+          icon: "",
+        },
+        {
+          name: "4 Cores",
+          description: "",
+          value: "4",
+          icon: "",
+        },
+        {
+          name: "6 Cores",
+          description: "",
+          value: "6",
+          icon: "",
+        },
+        {
+          name: "8 Cores",
+          description: "",
+          value: "8",
+          icon: "",
+        },
+      ],
+      required: false,
+      ephemeral: false,
+    },
+  ]
+
+  const cpuParameter = templateParameters[0]
+  const [cpuParameterInitialValue] = selectInitialRichParametersValues(
+    templateParameters,
+    [{ name: cpuParameter.name, value: "100" }],
+  )
+
+  expect(cpuParameterInitialValue.value).toBe(cpuParameter.default_value)
+})
diff --git a/site/src/utils/richParameters.ts b/site/src/utils/richParameters.ts
index f4c87eff48bd9..6fac6c33f25f4 100644
--- a/site/src/utils/richParameters.ts
+++ b/site/src/utils/richParameters.ts
@@ -7,7 +7,7 @@ import * as Yup from "yup"
 
 export const selectInitialRichParametersValues = (
   templateParameters?: TemplateVersionParameter[],
-  defaultValuesFromQuery?: Record<string, string>,
+  defaultBuildParameters?: WorkspaceBuildParameter[],
 ): WorkspaceBuildParameter[] => {
   const defaults: WorkspaceBuildParameter[] = []
   if (!templateParameters) {
@@ -19,9 +19,20 @@ export const selectInitialRichParametersValues = (
 
     if (parameter.options.length > 0) {
       parameterValue = parameterValue ?? parameter.options[0].value
+      const validValues = parameter.options.map((option) => option.value)
 
-      if (defaultValuesFromQuery && defaultValuesFromQuery[parameter.name]) {
-        parameterValue = defaultValuesFromQuery[parameter.name]
+      if (defaultBuildParameters) {
+        const defaultBuildParameter = defaultBuildParameters.find(
+          (p) => p.name === parameter.name,
+        )
+
+        // We don't want invalid values from default parameters to be set
+        if (
+          defaultBuildParameter &&
+          validValues.includes(defaultBuildParameter.value)
+        ) {
+          parameterValue = defaultBuildParameter?.value
+        }
       }
 
       const buildParameter: WorkspaceBuildParameter = {
@@ -36,8 +47,14 @@ export const selectInitialRichParametersValues = (
       parameterValue = parameter.default_value
     }
 
-    if (defaultValuesFromQuery && defaultValuesFromQuery[parameter.name]) {
-      parameterValue = defaultValuesFromQuery[parameter.name]
+    if (defaultBuildParameters) {
+      const buildParameter = defaultBuildParameters.find(
+        (p) => p.name === parameter.name,
+      )
+
+      if (buildParameter) {
+        parameterValue = buildParameter?.value
+      }
     }
 
     const buildParameter: WorkspaceBuildParameter = {
diff --git a/site/src/utils/workspace.tsx b/site/src/utils/workspace.tsx
index 61213bf21b81f..26b436aafe79e 100644
--- a/site/src/utils/workspace.tsx
+++ b/site/src/utils/workspace.tsx
@@ -286,6 +286,6 @@ export const hasJobError = (workspace: TypesGen.Workspace) => {
   return workspace.latest_build.job.error !== undefined
 }
 
-export const paramUsedToCreateWorkspace = (
+export const paramsUsedToCreateWorkspace = (
   param: TypesGen.TemplateVersionParameter,
 ) => !param.ephemeral
diff --git a/site/src/xServices/createWorkspace/createWorkspaceXService.ts b/site/src/xServices/createWorkspace/createWorkspaceXService.ts
index a052e92d48f72..be7b0b0779db6 100644
--- a/site/src/xServices/createWorkspace/createWorkspaceXService.ts
+++ b/site/src/xServices/createWorkspace/createWorkspaceXService.ts
@@ -1,7 +1,7 @@
 import {
   checkAuthorization,
   createWorkspace,
-  getTemplates,
+  getTemplateByName,
   getTemplateVersionGitAuth,
   getTemplateVersionRichParameters,
 } from "api/api"
@@ -12,38 +12,33 @@ import {
   TemplateVersionParameter,
   User,
   Workspace,
+  WorkspaceBuildParameter,
 } from "api/typesGenerated"
 import { assign, createMachine } from "xstate"
+import { paramsUsedToCreateWorkspace } from "utils/workspace"
+import { REFRESH_GITAUTH_BROADCAST_CHANNEL } from "utils/gitAuth"
 
-export const REFRESH_GITAUTH_BROADCAST_CHANNEL = "gitauth_refresh"
+export type CreateWorkspaceMode = "form" | "auto"
 
 type CreateWorkspaceContext = {
   organizationId: string
-  owner: User | null
   templateName: string
-  templates?: Template[]
-  selectedTemplate?: Template
-  templateParameters?: TemplateVersionParameter[]
-  templateGitAuth?: TemplateVersionGitAuth[]
-  createWorkspaceRequest?: CreateWorkspaceRequest
-  createdWorkspace?: Workspace
-  createWorkspaceError?: Error | unknown
-  getTemplatesError?: Error | unknown
-  getTemplateParametersError?: Error | unknown
-  getTemplateGitAuthError?: Error | unknown
+  mode: CreateWorkspaceMode
+  defaultName: string
+  error?: Error | unknown
+  // Form
+  template?: Template
+  parameters?: TemplateVersionParameter[]
   permissions?: Record<string, boolean>
-  checkPermissionsError?: Error | unknown
+  gitAuth?: TemplateVersionGitAuth[]
+  // Used on auto-create
+  defaultBuildParameters?: WorkspaceBuildParameter[]
 }
 
 type CreateWorkspaceEvent = {
   type: "CREATE_WORKSPACE"
   request: CreateWorkspaceRequest
-  owner: User | null
-}
-
-type SelectOwnerEvent = {
-  type: "SELECT_OWNER"
-  owner: User | null
+  owner: User
 }
 
 type RefreshGitAuthEvent = {
@@ -59,117 +54,79 @@ export const createWorkspaceMachine =
       tsTypes: {} as import("./createWorkspaceXService.typegen").Typegen0,
       schema: {
         context: {} as CreateWorkspaceContext,
-        events: {} as
-          | CreateWorkspaceEvent
-          | SelectOwnerEvent
-          | RefreshGitAuthEvent,
+        events: {} as CreateWorkspaceEvent | RefreshGitAuthEvent,
         services: {} as {
-          getTemplates: {
-            data: Template[]
-          }
-          getTemplateGitAuth: {
-            data: TemplateVersionGitAuth[]
-          }
-          getTemplateParameters: {
-            data: TemplateVersionParameter[]
+          loadFormData: {
+            data: {
+              template: Template
+              permissions: CreateWSPermissions
+              parameters: TemplateVersionParameter[]
+              gitAuth: TemplateVersionGitAuth[]
+            }
           }
           createWorkspace: {
             data: Workspace
           }
+          autoCreateWorkspace: {
+            data: Workspace
+          }
         },
       },
-      initial: "gettingTemplates",
+      initial: "checkingMode",
       states: {
-        gettingTemplates: {
-          entry: "clearGetTemplatesError",
-          invoke: {
-            src: "getTemplates",
-            onDone: [
-              {
-                actions: ["assignTemplates"],
-                cond: "areTemplatesEmpty",
-              },
-              {
-                actions: ["assignTemplates", "assignSelectedTemplate"],
-                target: "gettingTemplateParameters",
-              },
-            ],
-            onError: {
-              actions: ["assignGetTemplatesError"],
-              target: "error",
-            },
-          },
-        },
-        gettingTemplateParameters: {
-          entry: "clearGetTemplateParametersError",
-          invoke: {
-            src: "getTemplateParameters",
-            onDone: {
-              actions: ["assignTemplateParameters"],
-              target: "checkingPermissions",
-            },
-            onError: {
-              actions: ["assignGetTemplateParametersError"],
-              target: "error",
+        checkingMode: {
+          always: [
+            {
+              target: "autoCreating",
+              cond: ({ mode }) => mode === "auto",
             },
-          },
+            { target: "loadingFormData" },
+          ],
         },
-        checkingPermissions: {
-          entry: "clearCheckPermissionsError",
+        autoCreating: {
           invoke: {
-            src: "checkPermissions",
-            id: "checkPermissions",
+            src: "autoCreateWorkspace",
             onDone: {
-              actions: "assignPermissions",
-              target: "gettingTemplateGitAuth",
+              actions: ["onCreateWorkspace"],
             },
             onError: {
-              actions: ["assignCheckPermissionsError"],
+              actions: ["assignError"],
+              target: "loadingFormData",
             },
           },
         },
-        gettingTemplateGitAuth: {
-          entry: "clearTemplateGitAuthError",
+        loadingFormData: {
           invoke: {
-            src: "getTemplateGitAuth",
+            src: "loadFormData",
             onDone: {
-              actions: ["assignTemplateGitAuth"],
-              target: "fillingParams",
+              target: "idle",
+              actions: ["assignFormData"],
             },
             onError: {
-              actions: ["assignTemplateGitAuthError"],
-              target: "error",
+              target: "loadError",
+              actions: ["assignError"],
             },
           },
         },
-        fillingParams: {
-          invoke: {
-            id: "listenForRefreshGitAuth",
-            src: () => (callback) => {
-              // eslint-disable-next-line compat/compat -- It actually is supported... not sure why eslint is complaining.
-              const bc = new BroadcastChannel(REFRESH_GITAUTH_BROADCAST_CHANNEL)
-              bc.addEventListener("message", () => {
-                callback("REFRESH_GITAUTH")
-              })
-              return () => bc.close()
+        idle: {
+          invoke: [
+            {
+              src: () => (callback) => {
+                const channel = watchGitAuthRefresh(() => {
+                  callback("REFRESH_GITAUTH")
+                })
+                return () => channel.close()
+              },
             },
-          },
+          ],
           on: {
             CREATE_WORKSPACE: {
-              actions: ["assignCreateWorkspaceRequest", "assignOwner"],
               target: "creatingWorkspace",
             },
-            SELECT_OWNER: {
-              actions: ["assignOwner"],
-              target: ["fillingParams"],
-            },
-            REFRESH_GITAUTH: {
-              target: "gettingTemplateGitAuth",
-            },
           },
         },
         creatingWorkspace: {
-          entry: "clearCreateWorkspaceError",
+          entry: "clearError",
           invoke: {
             src: "createWorkspace",
             onDone: {
@@ -177,137 +134,100 @@ export const createWorkspaceMachine =
               target: "created",
             },
             onError: {
-              actions: ["assignCreateWorkspaceError"],
-              target: "fillingParams",
+              actions: ["assignError"],
+              target: "idle",
             },
           },
         },
         created: {
           type: "final",
         },
-        error: {},
+        loadError: {
+          type: "final",
+        },
       },
     },
     {
       services: {
-        getTemplates: (context) => getTemplates(context.organizationId),
-        getTemplateGitAuth: (context) => {
-          const { selectedTemplate } = context
-
-          if (!selectedTemplate) {
-            throw new Error("No selected template")
-          }
-
-          return getTemplateVersionGitAuth(selectedTemplate.active_version_id)
-        },
-        getTemplateParameters: (context) => {
-          const { selectedTemplate } = context
-
-          if (!selectedTemplate) {
-            throw new Error("No selected template")
-          }
-
-          return getTemplateVersionRichParameters(
-            selectedTemplate.active_version_id,
-          )
+        createWorkspace: ({ organizationId }, { request, owner }) => {
+          return createWorkspace(organizationId, owner.id, request)
         },
-        checkPermissions: async (context) => {
-          if (!context.organizationId) {
-            throw new Error("No organization ID")
-          }
-
-          // HACK: below, we pass in * for the owner_id, which is a hacky way of checking if the
-          // current user can create a workspace on behalf of anyone within the org (only org owners should be able to do this).
-          // This pattern should not be replicated outside of this narrow use case.
-          const permissionsToCheck = {
-            createWorkspaceForUser: {
-              object: {
-                resource_type: "workspace",
-                organization_id: `${context.organizationId}`,
-                owner_id: "*",
-              },
-              action: "create",
-            },
-          } as const
-
-          return checkAuthorization({
-            checks: permissionsToCheck,
+        autoCreateWorkspace: async ({
+          templateName,
+          organizationId,
+          defaultBuildParameters,
+          defaultName,
+        }) => {
+          const template = await getTemplateByName(organizationId, templateName)
+          return createWorkspace(organizationId, "me", {
+            template_id: template.id,
+            name: defaultName,
+            rich_parameter_values: defaultBuildParameters,
           })
         },
-        createWorkspace: (context) => {
-          const { createWorkspaceRequest, organizationId, owner } = context
+        loadFormData: async ({ templateName, organizationId }) => {
+          const [template, permissions] = await Promise.all([
+            getTemplateByName(organizationId, templateName),
+            checkCreateWSPermissions(organizationId),
+          ])
+          const [parameters, gitAuth] = await Promise.all([
+            getTemplateVersionRichParameters(template.active_version_id).then(
+              (p) => p.filter(paramsUsedToCreateWorkspace),
+            ),
+            getTemplateVersionGitAuth(template.active_version_id),
+          ])
 
-          if (!createWorkspaceRequest) {
-            throw new Error("No create workspace request")
+          return {
+            template,
+            permissions,
+            parameters,
+            gitAuth,
           }
-
-          return createWorkspace(
-            organizationId,
-            owner?.id ?? "me",
-            createWorkspaceRequest,
-          )
         },
       },
-      guards: {
-        areTemplatesEmpty: (_, event) => event.data.length === 0,
-      },
       actions: {
-        assignTemplates: assign({
-          templates: (_, event) => event.data,
-        }),
-        assignSelectedTemplate: assign({
-          selectedTemplate: (ctx, event) => {
-            const templates = event.data.filter(
-              (template) => template.name === ctx.templateName,
-            )
-            return templates.length > 0 ? templates[0] : undefined
-          },
-        }),
-        assignTemplateParameters: assign({
-          templateParameters: (_, event) => event.data,
-        }),
-        assignPermissions: assign({
-          permissions: (_, event) => event.data as Record<string, boolean>,
-        }),
-        assignCheckPermissionsError: assign({
-          checkPermissionsError: (_, event) => event.data,
-        }),
-        clearCheckPermissionsError: assign({
-          checkPermissionsError: (_) => undefined,
-        }),
-        assignCreateWorkspaceRequest: assign({
-          createWorkspaceRequest: (_, event) => event.request,
-        }),
-        assignOwner: assign({
-          owner: (_, event) => event.owner,
-        }),
-        assignCreateWorkspaceError: assign({
-          createWorkspaceError: (_, event) => event.data,
-        }),
-        clearCreateWorkspaceError: assign({
-          createWorkspaceError: (_) => undefined,
-        }),
-        assignGetTemplatesError: assign({
-          getTemplatesError: (_, event) => event.data,
-        }),
-        clearGetTemplatesError: assign({
-          getTemplatesError: (_) => undefined,
-        }),
-        assignGetTemplateParametersError: assign({
-          getTemplateParametersError: (_, event) => event.data,
-        }),
-        clearGetTemplateParametersError: assign({
-          getTemplateParametersError: (_) => undefined,
-        }),
-        clearTemplateGitAuthError: assign({
-          getTemplateGitAuthError: (_) => undefined,
+        assignFormData: assign((ctx, event) => {
+          return {
+            ...ctx,
+            ...event.data,
+          }
         }),
-        assignTemplateGitAuthError: assign({
-          getTemplateGitAuthError: (_, event) => event.data,
+        assignError: assign({
+          error: (_, event) => event.data,
         }),
-        assignTemplateGitAuth: assign({
-          templateGitAuth: (_, event) => event.data,
+        clearError: assign({
+          error: (_) => undefined,
         }),
       },
     },
   )
+
+const checkCreateWSPermissions = async (organizationId: string) => {
+  // HACK: below, we pass in * for the owner_id, which is a hacky way of checking if the
+  // current user can create a workspace on behalf of anyone within the org (only org owners should be able to do this).
+  // This pattern should not be replicated outside of this narrow use case.
+  const permissionsToCheck = {
+    createWorkspaceForUser: {
+      object: {
+        resource_type: "workspace",
+        organization_id: organizationId,
+        owner_id: "*",
+      },
+      action: "create",
+    },
+  } as const
+
+  return checkAuthorization({
+    checks: permissionsToCheck,
+  }) as Promise<Record<keyof typeof permissionsToCheck, boolean>>
+}
+
+export const watchGitAuthRefresh = (callback: () => void) => {
+  const bc = new BroadcastChannel(REFRESH_GITAUTH_BROADCAST_CHANNEL)
+  bc.addEventListener("message", callback)
+  return bc
+}
+
+export type CreateWSPermissions = Awaited<
+  ReturnType<typeof checkCreateWSPermissions>
+>
diff --git a/site/yarn.lock b/site/yarn.lock
index bbbe6d3984c13..125af4fabac20 100644
--- a/site/yarn.lock
+++ b/site/yarn.lock
@@ -11497,6 +11497,11 @@ unified@^10.0.0:
     trough "^2.0.0"
     vfile "^5.0.0"
 
+unique-names-generator@4.7.1:
+  version "4.7.1"
+  resolved "https://registry.yarnpkg.com/unique-names-generator/-/unique-names-generator-4.7.1.tgz#966407b12ba97f618928f77322cfac8c80df5597"
+  integrity sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==
+
 unique-string@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"