diff --git a/app.go b/app.go
index c251c22cc826e5b5a01080cf9741e1af304710eb..2f2e8b76055aa48c8dedceccab3b1f27a846deba 100644
--- a/app.go
+++ b/app.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"time"
 
+	"github.com/gofiber/contrib/hcaptcha"
 	"github.com/gofiber/fiber/v3"
 	"github.com/gofiber/fiber/v3/middleware/cors"
 	"github.com/gofiber/fiber/v3/middleware/limiter"
@@ -33,11 +34,31 @@ func serve(sig chan os.Signal, db *leveldb.DB) error {
 		},
 	}))
 
+	var captcha fiber.Handler
+	hCaptchaEnable := conf[hCaptchaSiteKey] != "unset" && conf[hCaptchaSecretKey] != "unset"
+
+	if hCaptchaEnable {
+		// create hCaptcha middleware if enabled
+		captcha = hcaptcha.New(hcaptcha.Config{
+			SecretKey: conf[hCaptchaSecretKey],
+		})
+
+		log.Printf("hCaptcha enabled with site key %q", conf[hCaptchaSiteKey])
+	} else {
+		// empty middleware if disabled
+		captcha = func(c fiber.Ctx) error {
+			return c.Next()
+		}
+
+		log.Printf("hCaptcha disabled because one or both of %q and %q are unset",
+			confEnv[hCaptchaSiteKey][0], confEnv[hCaptchaSecretKey][0])
+	}
+
 	// /register
-	routeRegister(app, db)
+	routeRegister(app, db, captcha)
 
 	// /hcaptcha-site-key
-	routeHCaptchaSiteKey(app)
+	routeHCaptchaSiteKey(app, !hCaptchaEnable, conf[hCaptchaSiteKey])
 
 	// graceful shutdown
 	go func() {
diff --git a/captcha.go b/captcha.go
index edb3cd2ab66efce6e6b260742705ccd4cbf0f833..73bc8c6fef9b4f9d2b301da96d8f70fb8a06f8f0 100644
--- a/captcha.go
+++ b/captcha.go
@@ -1,34 +1,24 @@
 package main
 
 import (
-	"log"
-
 	"github.com/gofiber/fiber/v3"
 )
 
 // Route to expose hCaptcha site key
-func routeHCaptchaSiteKey(app *fiber.App) {
-	app.Get("/hcaptcha-site-key", func(c fiber.Ctx) error {
-		if conf[hCaptchaSiteKey] == "unset" {
-			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
-				"message": "hCaptcha site key not configured",
+func routeHCaptchaSiteKey(app *fiber.App, stub bool, siteKey string) {
+	if stub {
+		app.Get("/captcha", func(c fiber.Ctx) error {
+			return c.JSON(fiber.Map{
+				"success": false,
+				"message": "hCaptcha is not enabled on this instance",
+			})
+		})
+	} else {
+		app.Get("/captcha", func(c fiber.Ctx) error {
+			return c.JSON(fiber.Map{
+				"success":           true,
+				"hcaptcha_site_key": siteKey,
 			})
-		}
-		return c.JSON(fiber.Map{
-			"hcaptcha_site_key": conf[hCaptchaSiteKey],
 		})
-	})
-}
-
-// Middleware to conditionally apply hCaptcha
-func conditionalCaptcha(captcha fiber.Handler) fiber.Handler {
-	return func(c fiber.Ctx) error {
-		if conf[hCaptchaSecret] == "unset" {
-			if verbose {
-				log.Printf("Captcha bypassed for %q", c.IP())
-			}
-			return c.Next()
-		}
-		return captcha(c)
 	}
 }
diff --git a/conf.go b/conf.go
index 5a9ed93c521b4bc1591751b0dee095ee8116d88e..a95b71fafe42fc5bae60d13befa533a67b89674b 100644
--- a/conf.go
+++ b/conf.go
@@ -10,18 +10,18 @@ const (
 	listenAddr
 	allowedURL
 	hCaptchaSiteKey
-	hCaptchaSecret
+	hCaptchaSecretKey
 	verboseLogging
 )
 
 // env variable, default pairing
 var confEnv = [...][2]string{
-	dbPath:          {"DB", "db"},
-	listenAddr:      {"LISTEN_ADDR", "127.0.0.1:3000"},
-	allowedURL:      {"ALLOWED_URL", "https://hizla.io"},
-	hCaptchaSiteKey: {"HCAPTCHA_SITE_KEY", "unset"},
-	hCaptchaSecret:  {"HCAPTCHA_SECRET", "unset"},
-	verboseLogging:  {"VERBOSE", "1"},
+	dbPath:            {"DB", "db"},
+	listenAddr:        {"LISTEN_ADDR", "127.0.0.1:3000"},
+	allowedURL:        {"ALLOWED_URL", "https://hizla.io"},
+	hCaptchaSiteKey:   {"HCAPTCHA_SITE_KEY", "unset"},
+	hCaptchaSecretKey: {"HCAPTCHA_SECRET_KEY", "unset"},
+	verboseLogging:    {"VERBOSE", "1"},
 }
 
 // resolved config values
diff --git a/register.go b/register.go
index 109b9ecddd861258d7e6275a9f38f2d5c849f0fb..02b4f60031e328308469e0fa080950fd8192bb3f 100644
--- a/register.go
+++ b/register.go
@@ -4,7 +4,6 @@ import (
 	"log"
 	"regexp"
 
-	"github.com/gofiber/contrib/hcaptcha"
 	"github.com/gofiber/fiber/v3"
 	"github.com/syndtr/goleveldb/leveldb"
 )
@@ -16,13 +15,8 @@ type registration struct {
 }
 
 // Waitlist registration route
-func routeRegister(app *fiber.App, db *leveldb.DB) {
-
-	captcha := hcaptcha.New(hcaptcha.Config{
-		SecretKey: conf[hCaptchaSecret],
-	})
-
-	app.Post("/register", conditionalCaptcha(captcha), func(c fiber.Ctx) error {
+func routeRegister(app *fiber.App, db *leveldb.DB, captcha fiber.Handler) {
+	app.Post("/register", func(c fiber.Ctx) error {
 		req := new(registration)
 
 		// Parse and validate the request
@@ -72,5 +66,5 @@ func routeRegister(app *fiber.App, db *leveldb.DB) {
 		return c.JSON(fiber.Map{
 			"message": "Email registered successfully",
 		})
-	})
+	}, captcha)
 }