Block disposable email signups in Go (Gin)
Add a small package-level function and call it in your signup handler. Works the same way in Echo, Chi, Fiber, or net/http — only the framework wiring changes.
The code
// internal/cde/cde.go
package cde
import (
"context"
"encoding/json"
"net/http"
"net/url"
"os"
"time"
)
var client = &http.Client{Timeout: 3 * time.Second}
func IsDisposable(ctx context.Context, email string) bool {
u := "https://api.checkdisposable.email/v1/check?email=" + url.QueryEscape(email)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return false
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("CDE_KEY"))
res, err := client.Do(req)
if err != nil || res.StatusCode != 200 {
return false // fail open
}
defer res.Body.Close()
var d struct{ IsDisposable bool `json:"is_disposable"` }
if json.NewDecoder(res.Body).Decode(&d) != nil {
return false
}
return d.IsDisposable
}
// internal/handlers/signup.go
package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
"yourapp/internal/cde"
)
type SignupBody struct {
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=8"`
}
func Signup(c *gin.Context) {
var body SignupBody
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if cde.IsDisposable(c.Request.Context(), body.Email) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Please use a real email address."})
return
}
// ...create user
c.JSON(http.StatusOK, gin.H{"ok": true})
}Notes
- Context propagation
- Pass `c.Request.Context()` so the API call gets canceled if the client disconnects. Without it, you keep dialing CheckDisposable Email even when nobody's listening.
- Reuse the client
- The package-level `*http.Client` reuses connections. Don't allocate one per request — Go's HTTP transport is connection-pooled by default.
- Other routers
- For Echo, swap `c.JSON` for `c.JSON(http.StatusBadRequest, ...)`. For chi/net-http, write the response directly. The `cde.IsDisposable` function is identical.
Get a free API key
500 checks/month, no credit card. No credit card. 30 seconds.
Sign up free →