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.

Verify one email in GoAPI
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.

Validate emails in a net/http or Gin handler at signup
Clean an imported slice of addresses in a CLI tool
Filter leads inside a goroutine worker pool before sending
Gate a background job so it only mails deliverable addresses

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.

Batch verification with net/http
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.

Reject bad emails at signup
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.