Java SDK
Java email checker SDK. Maven/Gradle setup, verify emails with Java. Code examples included.
The official EmailVerify SDK for Java provides a robust interface for email verification with Spring Boot integration support.
Installation
Maven
<dependency>
<groupId>com.emailverify</groupId>
<artifactId>emailverify-java</artifactId>
<version>1.0.0</version>
</dependency>Gradle
implementation 'com.emailverify:emailverify-java:1.0.0'Requirements
- Java 11 or higher
- Maven or Gradle
Quick Start
import com.emailverify.Client;
import com.emailverify.model.VerificationResult;
public class Main {
public static void main(String[] args) {
Client client = new Client(System.getenv("EMAILVERIFY_API_KEY"));
VerificationResult result = client.verify("user@example.com");
System.out.println("Status: " + result.getStatus());
System.out.println("Score: " + result.getScore());
}
}Configuration
Client Builder
import com.emailverify.Client;
import java.time.Duration;
Client client = Client.builder()
.apiKey(System.getenv("EMAILVERIFY_API_KEY"))
.timeout(Duration.ofSeconds(30))
.retries(3)
.baseUrl("https://api.emailverify.ai")
.build();Configuration Properties
| Property | Type | Default | Description |
|---|---|---|---|
apiKey | String | Required | Your API key |
timeout | Duration | 30s | Request timeout |
retries | int | 3 | Number of retry attempts |
baseUrl | String | API URL | Custom API endpoint |
Types
VerificationResult
public class VerificationResult {
private String email;
private String status; // "valid", "invalid", "unknown", "accept_all"
private ResultDetails result;
private double score;
private String reason;
// Getters...
}
public class ResultDetails {
private Boolean deliverable;
private boolean validFormat;
private boolean validDomain;
private boolean validMx;
private boolean disposable;
private boolean role;
private boolean catchall;
private boolean free;
private Boolean smtpValid;
// Getters...
}BulkJob
public class BulkJob {
private String id;
private String status; // "pending", "processing", "completed", "failed"
private int total;
private int processed;
private int valid;
private int invalid;
private int unknown;
private Instant createdAt;
private Instant completedAt;
// Getters...
}Single Verification
Basic Verification
VerificationResult result = client.verify("user@example.com");
System.out.println("Email: " + result.getEmail());
System.out.println("Status: " + result.getStatus());
System.out.println("Score: " + result.getScore());
System.out.println("Deliverable: " + result.getResult().getDeliverable());
System.out.println("Disposable: " + result.getResult().isDisposable());Verification with Options
import com.emailverify.model.VerifyOptions;
VerifyOptions options = VerifyOptions.builder()
.smtpCheck(true)
.timeout(Duration.ofSeconds(5))
.build();
VerificationResult result = client.verify("user@example.com", options);Async Verification
import java.util.concurrent.CompletableFuture;
CompletableFuture<VerificationResult> future = client.verifyAsync("user@example.com");
future.thenAccept(result -> {
System.out.println("Status: " + result.getStatus());
}).exceptionally(ex -> {
System.err.println("Error: " + ex.getMessage());
return null;
});Bulk Verification
Submit Job
import java.util.Arrays;
import java.util.List;
List<String> emails = Arrays.asList(
"user1@example.com",
"user2@example.com",
"user3@example.com"
);
BulkJob job = client.verifyBulk(emails);
System.out.println("Job ID: " + job.getId());Check Status
BulkJob status = client.getBulkJobStatus(job.getId());
System.out.println("Status: " + status.getStatus());
System.out.println("Progress: " + status.getProcessed() + "/" + status.getTotal());
System.out.println("Valid: " + status.getValid());
System.out.println("Invalid: " + status.getInvalid());Get Results
List<VerificationResult> results = client.getBulkJobResults(job.getId());
for (VerificationResult result : results) {
System.out.println(result.getEmail() + ": " + result.getStatus());
}With Webhook
import com.emailverify.model.BulkOptions;
BulkOptions options = BulkOptions.builder()
.webhookUrl("https://your-domain.com/webhooks/emailverify")
.build();
BulkJob job = client.verifyBulk(emails, options);Credit Management
import com.emailverify.model.Credits;
Credits credits = client.getCredits();
System.out.println("Available: " + credits.getAvailable());
System.out.println("Used: " + credits.getUsed());
System.out.println("Total: " + credits.getTotal());Error Handling
Exception Types
import com.emailverify.exception.*;
try {
VerificationResult result = client.verify("invalid-email");
} catch (AuthenticationException e) {
System.err.println("Invalid API key");
} catch (RateLimitException e) {
System.err.println("Rate limited. Retry after " + e.getRetryAfter() + " seconds");
} catch (ValidationException e) {
System.err.println("Invalid input: " + e.getMessage());
} catch (EmailVerifyException e) {
System.err.println("API error: " + e.getMessage());
}Custom Exception Handler
public class VerificationService {
private final Client client;
public Optional<VerificationResult> safeVerify(String email) {
try {
return Optional.of(client.verify(email));
} catch (RateLimitException e) {
logger.warn("Rate limited, retry after: {}", e.getRetryAfter());
return Optional.empty();
} catch (EmailVerifyException e) {
logger.error("Verification failed: {}", e.getMessage());
return Optional.empty();
}
}
}Spring Boot Integration
Dependency
Add the Spring Boot starter:
<dependency>
<groupId>com.emailverify</groupId>
<artifactId>emailverify-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>Configuration
# application.yml
emailverify:
api-key: ${EMAILVERIFY_API_KEY}
timeout: 30s
retries: 3Or in application.properties:
emailverify.api-key=${EMAILVERIFY_API_KEY}
emailverify.timeout=30s
emailverify.retries=3Auto-Configuration
The client is automatically configured and available for injection:
import com.emailverify.Client;
import org.springframework.stereotype.Service;
@Service
public class EmailVerificationService {
private final Client emailVerifyClient;
public EmailVerificationService(Client emailVerifyClient) {
this.emailVerifyClient = emailVerifyClient;
}
public boolean isValidEmail(String email) {
VerificationResult result = emailVerifyClient.verify(email);
return "valid".equals(result.getStatus());
}
}REST Controller
import com.emailverify.Client;
import com.emailverify.model.VerificationResult;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/verify")
public class VerificationController {
private final Client client;
public VerificationController(Client client) {
this.client = client;
}
@PostMapping
public ResponseEntity<?> verify(@RequestBody VerifyRequest request) {
try {
VerificationResult result = client.verify(request.getEmail());
return ResponseEntity.ok(new VerifyResponse(
result.getEmail(),
result.getStatus(),
result.getScore()
));
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body(new ErrorResponse("Verification failed"));
}
}
}
record VerifyRequest(String email) {}
record VerifyResponse(String email, String status, double score) {}
record ErrorResponse(String error) {}Custom Validator Annotation
// Annotation
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = ValidEmailValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidEmail {
String message() default "Invalid email address";
boolean rejectDisposable() default true;
double minScore() default 0.5;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
// Validator
import com.emailverify.Client;
import com.emailverify.model.VerificationResult;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class ValidEmailValidator implements ConstraintValidator<ValidEmail, String> {
private final Client client;
private boolean rejectDisposable;
private double minScore;
public ValidEmailValidator(Client client) {
this.client = client;
}
@Override
public void initialize(ValidEmail annotation) {
this.rejectDisposable = annotation.rejectDisposable();
this.minScore = annotation.minScore();
}
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
if (email == null || email.isBlank()) {
return false;
}
try {
VerificationResult result = client.verify(email);
if (!"valid".equals(result.getStatus())) {
return false;
}
if (rejectDisposable && result.getResult().isDisposable()) {
return false;
}
return result.getScore() >= minScore;
} catch (Exception e) {
return false;
}
}
}
// Usage
public class RegisterRequest {
@ValidEmail(rejectDisposable = true, minScore = 0.7)
private String email;
// getters, setters...
}Async Service
import com.emailverify.Client;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
@Service
public class AsyncVerificationService {
private final Client client;
public AsyncVerificationService(Client client) {
this.client = client;
}
@Async
public CompletableFuture<VerificationResult> verifyAsync(String email) {
return client.verifyAsync(email);
}
@Async
public CompletableFuture<List<VerificationResult>> verifyBatchAsync(List<String> emails) {
return CompletableFuture.supplyAsync(() -> {
BulkJob job = client.verifyBulk(emails);
// Poll for completion
while (true) {
BulkJob status = client.getBulkJobStatus(job.getId());
if ("completed".equals(status.getStatus())) {
break;
}
if ("failed".equals(status.getStatus())) {
throw new RuntimeException("Bulk job failed");
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
return client.getBulkJobResults(job.getId());
});
}
}Complete Examples
Registration Service
import com.emailverify.Client;
import com.emailverify.model.VerificationResult;
public class RegistrationService {
private final Client client;
public RegistrationService(Client client) {
this.client = client;
}
public ValidationResult validateEmail(String email) {
VerificationResult result = client.verify(email);
// Reject invalid emails
if ("invalid".equals(result.getStatus())) {
return ValidationResult.invalid("invalid_email",
"This email address is invalid");
}
// Reject disposable emails
if (result.getResult().isDisposable()) {
return ValidationResult.invalid("disposable",
"Please use a permanent email address");
}
// Warn about role-based emails
if (result.getResult().isRole()) {
return ValidationResult.warning("role_based",
"Using a personal email is recommended",
result.getScore());
}
return ValidationResult.valid(result.getScore());
}
}
class ValidationResult {
private final boolean valid;
private final String reason;
private final String message;
private final Double score;
private ValidationResult(boolean valid, String reason, String message, Double score) {
this.valid = valid;
this.reason = reason;
this.message = message;
this.score = score;
}
public static ValidationResult valid(double score) {
return new ValidationResult(true, null, null, score);
}
public static ValidationResult invalid(String reason, String message) {
return new ValidationResult(false, reason, message, null);
}
public static ValidationResult warning(String reason, String message, double score) {
return new ValidationResult(true, reason, message, score);
}
// Getters...
}Concurrent Verification
import com.emailverify.Client;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class ConcurrentVerifier {
private final Client client;
private final ExecutorService executor;
public ConcurrentVerifier(Client client, int threads) {
this.client = client;
this.executor = Executors.newFixedThreadPool(threads);
}
public List<VerificationResult> verifyAll(List<String> emails) {
List<CompletableFuture<VerificationResult>> futures = emails.stream()
.map(email -> CompletableFuture.supplyAsync(
() -> client.verify(email), executor))
.collect(Collectors.toList());
return futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
}
public void shutdown() {
executor.shutdown();
}
}
// Usage
ConcurrentVerifier verifier = new ConcurrentVerifier(client, 10);
try {
List<String> emails = Arrays.asList("user1@example.com", "user2@example.com");
List<VerificationResult> results = verifier.verifyAll(emails);
results.forEach(r -> System.out.println(r.getEmail() + ": " + r.getStatus()));
} finally {
verifier.shutdown();
}Best Practices
1. Use Connection Pooling
// The client uses connection pooling by default
// For high-throughput applications, configure the pool size
Client client = Client.builder()
.apiKey(apiKey)
.maxConnections(100)
.build();2. Handle Nullable Fields
VerificationResult result = client.verify(email);
// Use Optional for nullable fields
Optional.ofNullable(result.getResult().getDeliverable())
.ifPresent(deliverable -> System.out.println("Deliverable: " + deliverable));3. Resource Management
// Client implements AutoCloseable
try (Client client = new Client(apiKey)) {
VerificationResult result = client.verify(email);
// Process result
}