Java email verification

Verify emails in Java with Verifly

Add email verification to a Java or Spring app with the built-in java.net.http HttpClient — no external HTTP library. Verifly is an API-first, pay-as-you-go service that returns a clean JSON verdict you can parse and branch on.

Verify one email in JavaAPI
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create(
        "https://verifly.email/api/v1/verify?email=user@example.com"))
    .header("Authorization", "Bearer vf_YOUR_KEY")
    .GET()
    .build();

HttpResponse<String> res =
    client.send(req, HttpResponse.BodyHandlers.ofString());
// res.body() is JSON: { "result": "deliverable", "is_valid": true, ... }
System.out.println(res.body());

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 Java 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 Spring Boot controller at signup
Clean an imported list in a batch job or CLI
Filter leads in a service layer before sending
Check addresses from any JVM app with no extra dependency

Email verification on the JVM

Java backends — Spring Boot services, batch processors, enterprise integrations — collect email addresses constantly, and the JVM's built-in tools stop at syntax. Validating with a regex or with Jakarta's @Email constraint confirms an address is well-formed, but a well-formed address is routinely a dead mailbox, a disposable throwaway domain, or a role inbox like support@ that nobody reads. Those slip past validation and turn into hard bounces that erode your sending reputation.

Verifly closes that gap with one HTTP request, and since Java 11 you do not need Apache HttpClient or OkHttp to make it. The built-in java.net.http.HttpClient sends the request; you set a Bearer header, get back a JSON body, and parse it with Jackson or Gson (or any JSON library your project already uses) into a result of deliverable, undeliverable, or risky plus disposable, role, catch-all, and smtp flags. Deserialize into a small record or POJO and the verdict becomes an ordinary switch expression in your service.

Pay-as-you-go pricing fits both a high-throughput microservice and an occasional data-cleanup job — from $2 per 1,000 checks down to $0.60 per 1,000 at volume, with no license or seat to negotiate. Self-register for 100 free credits with no card and no captcha, keep the vf_ key in your application config or a secret store, and reuse it across every service.

Batch-verify a list of emails in Java

For more than a single address, POST the whole set to /verify/batch rather than sending a request per element. Serialize an emails array into the JSON body and read back a results array in order, then stream over it with the Java Streams API to filter and collect. This keeps connection overhead down and cost predictable inside a batch job.

Batch verification with HttpClient
String body = """
    {"emails":["ada@example.com","info@some-domain.com","noreply@disposable.tld"]}
    """;

HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://verifly.email/api/v1/verify/batch"))
    .header("Authorization", "Bearer vf_YOUR_KEY")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

HttpResponse<String> res =
    client.send(req, HttpResponse.BodyHandlers.ofString());

// Parse res.body() with Jackson/Gson into a results list, e.g.:
// record Row(String email, String result, boolean disposable, boolean role) {}
// List<Row> results = mapper.readValue(res.body(), Payload.class).results();
// results.stream()
//        .filter(r -> r.result().equals("deliverable"))
//        .forEach(r -> System.out.println("keep: " + r.email()));

Validate at signup in Spring Boot

The most valuable place to verify in a Java web app is the registration endpoint. Build the HttpClient with a connect timeout and give the request its own timeout so a slow probe never blocks the thread, and catch exceptions to fail open so a transient outage never rejects a legitimate signup. Reject disposable addresses and warn on undeliverable ones before you persist the entity.

Reject bad emails at signup
boolean emailOk(String email) {
    HttpClient client = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(4))
        .build();
    HttpRequest req = HttpRequest.newBuilder()
        .uri(URI.create("https://verifly.email/api/v1/verify?email="
            + URLEncoder.encode(email, StandardCharsets.UTF_8)))
        .header("Authorization", "Bearer vf_YOUR_KEY")
        .timeout(Duration.ofSeconds(8))
        .GET()
        .build();
    try {
        HttpResponse<String> res =
            client.send(req, HttpResponse.BodyHandlers.ofString());
        JsonNode data = new ObjectMapper().readTree(res.body());
        if (data.path("disposable").asBoolean()) return false;
        return !"undeliverable".equals(data.path("result").asText());
    } catch (Exception e) {
        return true; // fail open on network error
    }
}

FAQ

Frequently asked questions

Do I need Apache HttpClient or OkHttp for Verifly?

No. Since Java 11 the built-in java.net.http.HttpClient can call Verifly directly. Apache HttpClient, OkHttp, or Spring's WebClient work too, but none is required — the standard client plus a JSON library is enough.

How do I parse the JSON response in Java?

Use Jackson or Gson to deserialize the body into a record or POJO with fields for result, is_valid, disposable, role, catch_all, and smtp. For a quick check you can also read a JsonNode and pull fields by name.

Isn't the @Email validation annotation enough?

The Jakarta @Email constraint only checks syntax. It passes addresses whose mailbox is deleted, whose domain is disposable, or that are role inboxes. Verifly adds the live SMTP check that annotation-based validation cannot perform.

How should I verify a large list?

POST the whole emails array to /api/v1/verify/batch instead of sending one request per address. You get a single results array back to process with the Streams API, which is faster and cheaper than many individual calls.

How do I keep verification from blocking a request thread?

Set a connectTimeout on the HttpClient and a timeout on the HttpRequest, and catch exceptions to fail open. That bounds the added latency and ensures a slow probe never stalls a signup thread.

What does Java 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 license or subscription, so a batch job and a production microservice bill the same simple way.