Email verification API in Java
To verify an email in Java, check the format with a regex, then call https://simpleverifier.com/api/v1/verify with java.net.http.HttpClient, a Bearer token and a 30-second request timeout. Parse status from the JSON: valid, risky or invalid. Return an empty Optional on errors and let the address through.
By SimpleVerifier Team
Before you start
- Create a key on the API keys page. Keys start with
sv_live_and are shown once. - Pass the key in from
System.getenv("SIMPLEVERIFIER_KEY")or your configuration system; don't hard-code it. - API access comes with Pro at $39/month (10,000 calls a month included, then $1.50 per 1,000), Business at $99/month (100,000 calls, then $1.00 per 1,000) and Agency at $249/month (300,000 calls, then $1.00 per 1,000). See pricing.
1. Add the client
Java 11 or later for HttpClient, plus Jackson (com.fasterxml.jackson.core:jackson-databind) to read the JSON. Create one instance and reuse it; HttpClient is thread-safe.
// SimpleVerifier.java — Java 11+, Jackson for JSON
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Optional;
import java.util.regex.Pattern;
public final class SimpleVerifier {
private static final String API_URL = "https://simpleverifier.com/api/v1/verify";
private static final Pattern EMAIL_SHAPE = Pattern.compile("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
private static final ObjectMapper JSON = new ObjectMapper();
private final HttpClient http = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
private final String apiKey;
public SimpleVerifier(String apiKey) {
this.apiKey = apiKey;
}
/** "valid", "risky" or "invalid"; empty when the API could not answer. */
public Optional<String> emailStatus(String email) {
String address = email == null ? "" : email.trim();
if (!EMAIL_SHAPE.matcher(address).matches()) {
return Optional.of("invalid"); // no API call made
}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL + "?email=" + URLEncoder.encode(address, StandardCharsets.UTF_8)))
.header("Authorization", "Bearer " + apiKey)
.timeout(Duration.ofSeconds(30))
.GET()
.build();
try {
HttpResponse<String> response = http.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
return Optional.empty(); // 401, 402, 429, 503: fail open
}
JsonNode body = JSON.readTree(response.body());
return Optional.ofNullable(body.path("status").textValue());
} catch (IOException e) {
return Optional.empty(); // includes HttpTimeoutException
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return Optional.empty();
}
}
}2. Use it
Block only invalid. An empty result means the API didn't answer, so accept the address.
SimpleVerifier verifier = new SimpleVerifier(System.getenv("SIMPLEVERIFIER_KEY"));
Optional<String> status = verifier.emailStatus(form.getEmail());
if (status.isPresent() && status.get().equals("invalid")) {
errors.put("email", "This email address cannot receive mail. Please check it.");
}
// "valid", "risky" or empty (API unavailable): accept the address.What the API returns
GET or POST https://simpleverifier.com/api/v1/verify with email runs the syntax, domain, disposable-domain and live mailbox checks in one call and returns:
{
"email": "[email protected]",
"status": "valid",
"reason": "Mailbox exists",
"mailbox_checked": true
}Every snippet above follows the same rule: only a successful response with status set to invalid blocks a person.
| Result | What it means | What to do |
|---|---|---|
| valid | The mail server confirmed the mailbox exists. | Accept. |
| risky | The domain is real but the mailbox couldn't be confirmed: catch-all domains, role addresses like info@, providers that hide mailbox status. | Accept on signup forms. Store the status and keep these out of cold campaigns. |
| invalid | Bad format, no mail server, a disposable domain, or the mailbox doesn't exist. | Reject and ask the person to check the address. |
| timeout, 429 or 503 | The check didn't finish: a slow mail server, too many calls this minute, or a brief outage. | Accept (fail open) and log it. Re-check later if it matters. |
| 401 or 402 | The key is wrong or revoked, or the subscription isn't active. | Accept, and alert yourself: every check is being skipped until it's fixed. |
Errors return JSON with an error message. Each key can make 120 calls a minute; for thousands of addresses, upload a CSV in the dashboard instead.
Phone numbers and spreadsheets
The same key works with /api/v1/phone?phone=…&country=… to validate a phone number and normalise it to E.164, with live carrier lookups when your plan has the $20/month phone add-on. The request and response are in the API reference. To check a column of addresses without code, use the Google Sheets add-on with the same key.
Common questions
- Does a timeout throw?
- HttpClient throws HttpTimeoutException, a subclass of IOException, when the 30-second request timeout passes. The client catches it and returns an empty Optional.
- I use Spring Boot. Is there a better fit?
- Yes: a Bean Validation constraint, so @DeliverableEmail sits next to @Email on your request DTO. See the Spring Boot guide.
- How much does the SimpleVerifier API cost?
- API access comes with Pro at $39/month (10,000 calls a month included, then $1.50 per 1,000), Business at $99/month (100,000 calls, then $1.00 per 1,000) and Agency at $249/month (300,000 calls, then $1.00 per 1,000). The per-1,000 price applies on monthly billing; on yearly billing the included calls are a monthly limit and further calls get HTTP 402 until the 1st (UTC). Starter has no API access. Each key can make 120 calls a minute.
- Should I reject risky addresses?
- Not on a signup or contact form. Risky means the mailbox couldn't be confirmed, which includes every address at a catch-all company domain. Accept it, store the status, and leave risky addresses out of cold outreach.
- What if the API is slow or down?
- Let the address through. A mailbox check can take several seconds when a mail server is slow, so cap the wait at about 30 seconds (less on a busy form) and treat a timeout, a 429 or a 503 as unknown rather than invalid.