EmailVerify LogoEmailVerify

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

PropertyTypeDefaultDescription
apiKeyStringRequiredYour API key
timeoutDuration30sRequest timeout
retriesint3Number of retry attempts
baseUrlStringAPI URLCustom 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: 3

Or in application.properties:

emailverify.api-key=${EMAILVERIFY_API_KEY}
emailverify.timeout=30s
emailverify.retries=3

Auto-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
}

Next Steps

On this page