diff --git a/ci/integration/envs_test.go b/ci/integration/envs_test.go
index cfa96983..634496f7 100644
--- a/ci/integration/envs_test.go
+++ b/ci/integration/envs_test.go
@@ -108,7 +108,7 @@ func TestEnvsCLI(t *testing.T) {
 		// Successfully output help.
 		c.Run(ctx, "coder envs create --help").Assert(t,
 			tcli.Success(),
-			tcli.StdoutMatches(regexp.QuoteMeta("Create a new environment under the active user.")),
+			tcli.StdoutMatches(regexp.QuoteMeta("Create a new Coder environment.")),
 			tcli.StderrEmpty(),
 		)
 
diff --git a/coder-sdk/client.go b/coder-sdk/client.go
index 12a7c476..8076c517 100644
--- a/coder-sdk/client.go
+++ b/coder-sdk/client.go
@@ -6,7 +6,7 @@ import (
 	"net/url"
 )
 
-// Me is the route param to access resources of the authenticated user.
+// Me is the user ID of the authenticated user.
 const Me = "me"
 
 // Client wraps the Coder HTTP API.
diff --git a/coder-sdk/error.go b/coder-sdk/error.go
index e5d16eb2..bdbef50f 100644
--- a/coder-sdk/error.go
+++ b/coder-sdk/error.go
@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"net/http"
-	"net/http/httputil"
 
 	"golang.org/x/xerrors"
 )
@@ -34,16 +33,11 @@ type HTTPError struct {
 }
 
 func (e *HTTPError) Error() string {
-	dump, err := httputil.DumpResponse(e.Response, false)
-	if err != nil {
-		return fmt.Sprintf("dump response: %+v", err)
-	}
-
 	var msg APIError
 	// Try to decode the payload as an error, if it fails or if there is no error message,
 	// return the response URL with the dump.
 	if err := json.NewDecoder(e.Response.Body).Decode(&msg); err != nil || msg.Err.Msg == "" {
-		return fmt.Sprintf("%s\n%s", e.Response.Request.URL, dump)
+		return fmt.Sprintf("%s: %d %s", e.Request.URL, e.StatusCode, e.Status)
 	}
 
 	// If the payload was a in the expected error format with a message, include it.
@@ -51,5 +45,5 @@ func (e *HTTPError) Error() string {
 }
 
 func bodyError(resp *http.Response) error {
-	return &HTTPError{resp}
+	return &HTTPError{Response: resp}
 }
diff --git a/docs/coder_envs.md b/docs/coder_envs.md
index c89a5060..90d14880 100644
--- a/docs/coder_envs.md
+++ b/docs/coder_envs.md
@@ -22,6 +22,8 @@ Perform operations on the Coder environments owned by the active user.
 ### SEE ALSO
 
 * [coder](coder.md)	 - coder provides a CLI for working with an existing Coder Enterprise installation
+* [coder envs create](coder_envs_create.md)	 - create a new environment.
+* [coder envs edit](coder_envs_edit.md)	 - edit an existing environment and initiate a rebuild.
 * [coder envs ls](coder_envs_ls.md)	 - list all environments owned by the active user
 * [coder envs rebuild](coder_envs_rebuild.md)	 - rebuild a Coder environment
 * [coder envs rm](coder_envs_rm.md)	 - remove Coder environments by name
diff --git a/docs/coder_envs_create.md b/docs/coder_envs_create.md
new file mode 100644
index 00000000..67c2cb8c
--- /dev/null
+++ b/docs/coder_envs_create.md
@@ -0,0 +1,45 @@
+## coder envs create
+
+create a new environment.
+
+### Synopsis
+
+Create a new Coder environment.
+
+```
+coder envs create [environment_name] [flags]
+```
+
+### Examples
+
+```
+# create a new environment using default resource amounts
+coder envs create my-new-env --image ubuntu
+coder envs create my-new-powerful-env --cpu 12 --disk 100 --memory 16 --image ubuntu
+```
+
+### Options
+
+```
+  -c, --cpu float32      number of cpu cores the environment should be provisioned with.
+  -d, --disk int         GB of disk storage an environment should be provisioned with.
+      --follow           follow buildlog after initiating rebuild
+  -g, --gpus int         number GPUs an environment should be provisioned with.
+  -h, --help             help for create
+  -i, --image string     name of the image to base the environment off of.
+  -m, --memory float32   GB of RAM an environment should be provisioned with.
+  -o, --org string       ID of the organization the environment should be created under.
+  -t, --tag string       tag of the image the environment will be based off of. (default "latest")
+```
+
+### Options inherited from parent commands
+
+```
+      --user string   Specify the user whose resources to target (default "me")
+  -v, --verbose       show verbose output
+```
+
+### SEE ALSO
+
+* [coder envs](coder_envs.md)	 - Interact with Coder environments
+
diff --git a/docs/coder_envs_edit.md b/docs/coder_envs_edit.md
new file mode 100644
index 00000000..72416b2c
--- /dev/null
+++ b/docs/coder_envs_edit.md
@@ -0,0 +1,45 @@
+## coder envs edit
+
+edit an existing environment and initiate a rebuild.
+
+### Synopsis
+
+Edit an existing environment and initate a rebuild.
+
+```
+coder envs edit [flags]
+```
+
+### Examples
+
+```
+coder envs edit back-end-env --cpu 4
+
+coder envs edit back-end-env --disk 20
+```
+
+### Options
+
+```
+  -c, --cpu float32      The number of cpu cores the environment should be provisioned with.
+  -d, --disk int         The amount of disk storage an environment should be provisioned with.
+      --follow           follow buildlog after initiating rebuild
+  -g, --gpu int          The amount of disk storage to provision the environment with.
+  -h, --help             help for edit
+  -i, --image string     name of the image you want the environment to be based off of.
+  -m, --memory float32   The amount of RAM an environment should be provisioned with.
+  -o, --org string       name of the organization the environment should be created under.
+  -t, --tag string       image tag of the image you want to base the environment off of. (default "latest")
+```
+
+### Options inherited from parent commands
+
+```
+      --user string   Specify the user whose resources to target (default "me")
+  -v, --verbose       show verbose output
+```
+
+### SEE ALSO
+
+* [coder envs](coder_envs.md)	 - Interact with Coder environments
+
diff --git a/internal/cmd/ceapi.go b/internal/cmd/ceapi.go
index 1e7e2480..8d155de1 100644
--- a/internal/cmd/ceapi.go
+++ b/internal/cmd/ceapi.go
@@ -84,13 +84,12 @@ func findEnv(ctx context.Context, client *coder.Client, envName, userEmail strin
 }
 
 type findImgConf struct {
-	client  *coder.Client
 	email   string
 	imgName string
 	orgName string
 }
 
-func findImg(ctx context.Context, conf findImgConf) (*coder.Image, error) {
+func findImg(ctx context.Context, client *coder.Client, conf findImgConf) (*coder.Image, error) {
 	switch {
 	case conf.email == "":
 		return nil, xerrors.New("user email unset")
@@ -98,13 +97,10 @@ func findImg(ctx context.Context, conf findImgConf) (*coder.Image, error) {
 		return nil, xerrors.New("image name unset")
 	}
 
-	imgs, err := getImgs(ctx,
-		getImgsConf{
-			client:  conf.client,
-			email:   conf.email,
-			orgName: conf.orgName,
-		},
-	)
+	imgs, err := getImgs(ctx, client, getImgsConf{
+		email:   conf.email,
+		orgName: conf.orgName,
+	})
 	if err != nil {
 		return nil, err
 	}
@@ -129,30 +125,29 @@ func findImg(ctx context.Context, conf findImgConf) (*coder.Image, error) {
 		return nil, xerrors.New("image not found - did you forget to import this image?")
 	}
 
-	lines := []string{clog.Tipf("Did you mean?")}
+	lines := []string{clog.Hintf("Did you mean?")}
 
 	for _, img := range possibleMatches {
-		lines = append(lines, img.Repository)
+		lines = append(lines, fmt.Sprintf("  %s", img.Repository))
 	}
 	return nil, clog.Fatal(
-		fmt.Sprintf("Found %d possible matches for %q.", len(possibleMatches), conf.imgName),
+		fmt.Sprintf("image %s not found", conf.imgName),
 		lines...,
 	)
 }
 
 type getImgsConf struct {
-	client  *coder.Client
 	email   string
 	orgName string
 }
 
-func getImgs(ctx context.Context, conf getImgsConf) ([]coder.Image, error) {
-	u, err := conf.client.UserByEmail(ctx, conf.email)
+func getImgs(ctx context.Context, client *coder.Client, conf getImgsConf) ([]coder.Image, error) {
+	u, err := client.UserByEmail(ctx, conf.email)
 	if err != nil {
 		return nil, err
 	}
 
-	orgs, err := conf.client.Organizations(ctx)
+	orgs, err := client.Organizations(ctx)
 	if err != nil {
 		return nil, err
 	}
@@ -160,7 +155,7 @@ func getImgs(ctx context.Context, conf getImgsConf) ([]coder.Image, error) {
 	orgs = lookupUserOrgs(u, orgs)
 
 	for _, org := range orgs {
-		imgs, err := conf.client.OrganizationImages(ctx, org.ID)
+		imgs, err := client.OrganizationImages(ctx, org.ID)
 		if err != nil {
 			return nil, err
 		}
diff --git a/internal/cmd/envs.go b/internal/cmd/envs.go
index 4dff187b..a35fa6ed 100644
--- a/internal/cmd/envs.go
+++ b/internal/cmd/envs.go
@@ -141,6 +141,10 @@ coder envs --user charlie@coder.com ls -o json \
 func createEnvCmd(user *string) *cobra.Command {
 	var (
 		org    string
+		cpu    float32
+		memory float32
+		disk   int
+		gpus   int
 		img    string
 		tag    string
 		follow bool
@@ -150,14 +154,10 @@ func createEnvCmd(user *string) *cobra.Command {
 		Use:   "create [environment_name]",
 		Short: "create a new environment.",
 		Args:  cobra.ExactArgs(1),
-		// Don't unhide this command until we can pass image names instead of image id's.
-		Hidden: true,
-		Long:   "Create a new environment under the active user.",
+		Long:  "Create a new Coder environment.",
 		Example: `# create a new environment using default resource amounts
-coder envs create --image 5f443b16-30652892427b955601330fa5 my-env-name
-
-# create a new environment using custom resource amounts
-coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955601330fa5 my-env-name`,
+coder envs create my-new-env --image ubuntu
+coder envs create my-new-powerful-env --cpu 12 --disk 100 --memory 16 --image ubuntu`,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			ctx := cmd.Context()
 			if img == "" {
@@ -178,14 +178,11 @@ coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955
 				return xerrors.New("org is required for multi-org members")
 			}
 
-			importedImg, err := findImg(ctx,
-				findImgConf{
-					client:  client,
-					email:   *user,
-					imgName: img,
-					orgName: org,
-				},
-			)
+			importedImg, err := findImg(ctx, client, findImgConf{
+				email:   *user,
+				imgName: img,
+				orgName: org,
+			})
 			if err != nil {
 				return err
 			}
@@ -195,13 +192,11 @@ coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955
 				Name:     args[0],
 				ImageID:  importedImg.ID,
 				ImageTag: tag,
+				CPUCores: cpu,
+				MemoryGB: memory,
+				DiskGB:   disk,
+				GPUs:     gpus,
 			}
-			// We're explicitly ignoring errors for these because all we
-			// need to now is if the numeric type is 0 or not.
-			createReq.CPUCores, _ = cmd.Flags().GetFloat32("cpu")
-			createReq.MemoryGB, _ = cmd.Flags().GetFloat32("memory")
-			createReq.DiskGB, _ = cmd.Flags().GetInt("disk")
-			createReq.GPUs, _ = cmd.Flags().GetInt("gpus")
 
 			// if any of these defaulted to their zero value we provision
 			// the create request with the imported image defaults instead.
@@ -230,17 +225,17 @@ coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955
 
 			clog.LogSuccess("creating environment...",
 				clog.BlankLine,
-				clog.Tipf(`run "coder envs watch-build %q" to trail the build logs`, env.Name),
+				clog.Tipf(`run "coder envs watch-build %s" to trail the build logs`, env.Name),
 			)
 			return nil
 		},
 	}
 	cmd.Flags().StringVarP(&org, "org", "o", "", "ID of the organization the environment should be created under.")
 	cmd.Flags().StringVarP(&tag, "tag", "t", defaultImgTag, "tag of the image the environment will be based off of.")
-	cmd.Flags().Float32P("cpu", "c", 0, "number of cpu cores the environment should be provisioned with.")
-	cmd.Flags().Float32P("memory", "m", 0, "GB of RAM an environment should be provisioned with.")
-	cmd.Flags().IntP("disk", "d", 0, "GB of disk storage an environment should be provisioned with.")
-	cmd.Flags().IntP("gpus", "g", 0, "number GPUs an environment should be provisioned with.")
+	cmd.Flags().Float32VarP(&cpu, "cpu", "c", 0, "number of cpu cores the environment should be provisioned with.")
+	cmd.Flags().Float32VarP(&memory, "memory", "m", 0, "GB of RAM an environment should be provisioned with.")
+	cmd.Flags().IntVarP(&disk, "disk", "d", 0, "GB of disk storage an environment should be provisioned with.")
+	cmd.Flags().IntVarP(&gpus, "gpus", "g", 0, "number GPUs an environment should be provisioned with.")
 	cmd.Flags().StringVarP(&img, "image", "i", "", "name of the image to base the environment off of.")
 	cmd.Flags().BoolVar(&follow, "follow", false, "follow buildlog after initiating rebuild")
 	_ = cmd.MarkFlagRequired("image")
@@ -249,22 +244,21 @@ coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955
 
 func editEnvCmd(user *string) *cobra.Command {
 	var (
-		org      string
-		img      string
-		tag      string
-		cpuCores float32
-		memGB    float32
-		diskGB   int
-		gpus     int
-		follow   bool
+		org    string
+		img    string
+		tag    string
+		cpu    float32
+		memory float32
+		disk   int
+		gpus   int
+		follow bool
 	)
 
 	cmd := &cobra.Command{
-		Use:    "edit",
-		Short:  "edit an existing environment owned by the active user.",
-		Args:   cobra.ExactArgs(1),
-		Hidden: true,
-		Long:   "Edit an existing environment owned by the active user.",
+		Use:   "edit",
+		Short: "edit an existing environment and initiate a rebuild.",
+		Args:  cobra.ExactArgs(1),
+		Long:  "Edit an existing environment and initate a rebuild.",
 		Example: `coder envs edit back-end-env --cpu 4
 
 coder envs edit back-end-env --disk 20`,
@@ -292,25 +286,17 @@ coder envs edit back-end-env --disk 20`,
 				return xerrors.New("org is required for multi-org members")
 			}
 
-			cpuCores, _ = cmd.Flags().GetFloat32("cpu")
-			memGB, _ = cmd.Flags().GetFloat32("memory")
-			diskGB, _ = cmd.Flags().GetInt("disk")
-			gpus, _ = cmd.Flags().GetInt("gpus")
-
-			req, err := buildUpdateReq(ctx,
-				updateConf{
-					cpu:         cpuCores,
-					memGB:       memGB,
-					diskGB:      diskGB,
-					gpus:        gpus,
-					client:      client,
-					environment: env,
-					user:        user,
-					image:       img,
-					imageTag:    tag,
-					orgName:     org,
-				},
-			)
+			req, err := buildUpdateReq(ctx, client, updateConf{
+				cpu:         cpu,
+				memGB:       memory,
+				diskGB:      disk,
+				gpus:        gpus,
+				environment: env,
+				user:        user,
+				image:       img,
+				imageTag:    tag,
+				orgName:     org,
+			})
 			if err != nil {
 				return err
 			}
@@ -329,7 +315,7 @@ coder envs edit back-end-env --disk 20`,
 
 			clog.LogSuccess("applied changes to the environment, rebuilding...",
 				clog.BlankLine,
-				clog.Tipf(`run "coder envs watch-build %q" to trail the build logs`, envName),
+				clog.Tipf(`run "coder envs watch-build %s" to trail the build logs`, envName),
 			)
 			return nil
 		},
@@ -337,10 +323,10 @@ coder envs edit back-end-env --disk 20`,
 	cmd.Flags().StringVarP(&org, "org", "o", "", "name of the organization the environment should be created under.")
 	cmd.Flags().StringVarP(&img, "image", "i", "", "name of the image you want the environment to be based off of.")
 	cmd.Flags().StringVarP(&tag, "tag", "t", "latest", "image tag of the image you want to base the environment off of.")
-	cmd.Flags().Float32P("cpu", "c", cpuCores, "The number of cpu cores the environment should be provisioned with.")
-	cmd.Flags().Float32P("memory", "m", memGB, "The amount of RAM an environment should be provisioned with.")
-	cmd.Flags().IntP("disk", "d", diskGB, "The amount of disk storage an environment should be provisioned with.")
-	cmd.Flags().IntP("gpu", "g", gpus, "The amount of disk storage to provision the environment with.")
+	cmd.Flags().Float32VarP(&cpu, "cpu", "c", 0, "The number of cpu cores the environment should be provisioned with.")
+	cmd.Flags().Float32VarP(&memory, "memory", "m", 0, "The amount of RAM an environment should be provisioned with.")
+	cmd.Flags().IntVarP(&disk, "disk", "d", 0, "The amount of disk storage an environment should be provisioned with.")
+	cmd.Flags().IntVarP(&gpus, "gpu", "g", 0, "The amount of disk storage to provision the environment with.")
 	cmd.Flags().BoolVar(&follow, "follow", false, "follow buildlog after initiating rebuild")
 	return cmd
 }
@@ -364,7 +350,7 @@ func rmEnvsCmd(user *string) *cobra.Command {
 				}
 				if _, err := confirm.Run(); err != nil {
 					return clog.Fatal(
-						"failed to confirm prompt", clog.BlankLine,
+						"failed to confirm deletion", clog.BlankLine,
 						clog.Tipf(`use "--force" to rebuild without a confirmation prompt`),
 					)
 				}
@@ -400,7 +386,6 @@ type updateConf struct {
 	memGB       float32
 	diskGB      int
 	gpus        int
-	client      *coder.Client
 	environment *coder.Environment
 	user        *string
 	image       string
@@ -408,7 +393,7 @@ type updateConf struct {
 	orgName     string
 }
 
-func buildUpdateReq(ctx context.Context, conf updateConf) (*coder.UpdateEnvironmentReq, error) {
+func buildUpdateReq(ctx context.Context, client *coder.Client, conf updateConf) (*coder.UpdateEnvironmentReq, error) {
 	var (
 		updateReq       coder.UpdateEnvironmentReq
 		defaultCPUCores float32
@@ -418,14 +403,11 @@ func buildUpdateReq(ctx context.Context, conf updateConf) (*coder.UpdateEnvironm
 
 	// If this is not empty it means the user is requesting to change the environment image.
 	if conf.image != "" {
-		importedImg, err := findImg(ctx,
-			findImgConf{
-				client:  conf.client,
-				email:   *conf.user,
-				imgName: conf.image,
-				orgName: conf.orgName,
-			},
-		)
+		importedImg, err := findImg(ctx, client, findImgConf{
+			email:   *conf.user,
+			imgName: conf.image,
+			orgName: conf.orgName,
+		})
 		if err != nil {
 			return nil, err
 		}
