Go email verification
Verify emails in Go with Verifly
Add email verification to a Go service with the standard net/http client and encoding/json — no third-party SDK. Verifly is an API-first, pay-as-you-go service that returns a typed-friendly JSON verdict you can decode into a struct.
req, _ := http.NewRequest("GET",
"https://verifly.email/api/v1/verify?email=user@example.com", nil)
req.Header.Set("Authorization", "Bearer vf_YOUR_KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var r struct {
Result string `json:"result"`
IsValid bool `json:"is_valid"`
}
json.NewDecoder(resp.Body).Decode(&r)
fmt.Println(r.Result, r.IsValid)Real-time SMTP mailbox checks
Single, batch, and async bulk verification
Disposable, role account, and catch-all detection
Pay-as-you-go credits with no subscription lock-in
Search fit
Built for Go email verification
Use Verifly when you need a simple API, predictable pricing, and clean JSON results before emails hit your product, CRM, or campaign tool.
Email verification the Go way
Go's standard library is deliberately batteries-included, and net/http plus encoding/json cover everything you need to talk to a REST service. That philosophy pairs well with Verifly: there is no vendor SDK to vendor into your go.mod, no generics-heavy wrapper, just a struct definition and a decode call. You build a request, set a Bearer header, and unmarshal the response into a struct whose fields map to result, is_valid, and the boolean flags.
The reason a Go backend needs this at all is the same reason every backend does. Parsing an address with net/mail confirms the syntax and nothing more — it cannot tell you the mailbox behind ceo@acme.com was deprovisioned last quarter, that the domain is a disposable throwaway, or that you are looking at a role inbox. Verifly runs a live SMTP probe and answers with a result of deliverable, undeliverable, or risky alongside disposable, role, catch-all, and smtp flags. Decoded into a struct, that becomes an ordinary switch statement in your handler.
Go is a common choice for high-throughput services and CLIs, and Verifly's pricing suits both. Pay-as-you-go from $2 per 1,000 checks down to $0.60 per 1,000 at volume means a chatty ingestion pipeline and a one-off cleanup command bill the same way. Self-register for 100 free credits with no card and no captcha, then reuse the vf_ key across every binary you ship.
Batch-verify a slice of emails in Go
When you hold a slice of addresses, marshal them into a request body and POST to /verify/batch rather than spawning a goroutine per address. The endpoint takes an emails array and returns a results array in order, which you decode into a slice of structs and range over. This is both faster and cheaper than hammering the single endpoint concurrently.
emails := []string{
"ada@example.com",
"info@some-domain.com",
"noreply@disposable.tld",
}
body, _ := json.Marshal(map[string][]string{"emails": emails})
req, _ := http.NewRequest("POST",
"https://verifly.email/api/v1/verify/batch", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer vf_YOUR_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var out struct {
Results []struct {
Email string `json:"email"`
Result string `json:"result"`
Disposable bool `json:"disposable"`
Role bool `json:"role"`
} `json:"results"`
}
json.NewDecoder(resp.Body).Decode(&out)
for _, r := range out.Results {
if r.Result == "deliverable" {
fmt.Println("keep:", r.Email)
}
}Validate at signup in an HTTP handler
The most valuable spot to verify in a Go web service is the registration handler. Use a client with an explicit timeout so a slow probe never stalls the request, and treat a network error as fail-open so signups are never blocked by an outage. Reject disposable addresses outright and warn on undeliverable ones before you persist the user.
var client = &http.Client{Timeout: 8 * time.Second}
func emailOK(email string) bool {
req, _ := http.NewRequest("GET",
"https://verifly.email/api/v1/verify?email="+url.QueryEscape(email), nil)
req.Header.Set("Authorization", "Bearer vf_YOUR_KEY")
resp, err := client.Do(req)
if err != nil {
return true // fail open on network error
}
defer resp.Body.Close()
var r struct {
Result string `json:"result"`
Disposable bool `json:"disposable"`
}
json.NewDecoder(resp.Body).Decode(&r)
if r.Disposable {
return false
}
return r.Result != "undeliverable"
}FAQ
Frequently asked questions
Do I need a Go SDK to use Verifly?
No. Verifly is a plain REST API, so the standard net/http client and encoding/json are all you need. Define a struct that matches the response fields and decode into it — no third-party dependency required.
How do I map the response to a Go struct?
Create a struct with json tags for result, is_valid, disposable, role, catch_all, and smtp, then use json.NewDecoder(resp.Body).Decode(&r). Only tag the fields you actually use; the rest are ignored.
Should I verify a large slice concurrently?
Prefer POST /api/v1/verify/batch with the whole emails array over a goroutine per address. One request returns all results in order, which is faster, cheaper, and avoids opening many connections.
How do I keep verification from blocking a request?
Use an http.Client with an explicit Timeout and treat a non-nil error as fail-open. That guarantees a slow or failed probe never stalls a signup or ingestion path.
What values can the result field hold?
It is deliverable, undeliverable, or risky. Pair it with the boolean flags disposable, role, catch_all, and smtp — a common pattern is a switch on result plus an early reject when disposable is true.
What does Go email verification cost?
Pay-as-you-go from $2 per 1,000 checks down to $0.60 per 1,000 at volume, with 100 free credits on self-register. No subscription, so a CLI cleanup and a production service share the same simple billing.