Java SDK
A typed client for the Emnet verification API with no framework dependencies — it drops into a Spring, Quarkus or plain-Java service without a dependency fight.
Install
The SDK is distributed with your early-access key, together with its install instructions. Request a key by writing to sales@emnetid.com.
Jackson and SLF4J. That is all. HTTP is the JDK’s own java.net.http.HttpClient, and the SDK deliberately does not inherit any Spring BOM — so it can never drag a framework version into your build. Requires Java 21 or later.
Create a client
EmnetClient is immutable and thread-safe. Create one per application and reuse it — creating one per request wastes connections.
EmnetClient emnet = new EmnetClient(
System.getenv("EMNET_BASE_URL"),
System.getenv("EMNET_API_KEY"));EmnetClient emnet = EmnetClient.builder()
.baseUrl(System.getenv("EMNET_BASE_URL"))
.apiKey(System.getenv("EMNET_API_KEY"))
.connectTimeout(Duration.ofSeconds(10))
.requestTimeout(Duration.ofSeconds(30))
.build();Builder options
| Option | Default | Notes |
|---|---|---|
baseUrl | — | Required. Your base URL is issued with your early-access key; read it from EMNET_BASE_URL. |
apiKey | — | Required. Load from the environment or a secret manager. |
connectTimeout | 10s | TCP connect timeout. |
requestTimeout | 30s | Per-request timeout. Raise it only if your network genuinely needs it. |
httpClient | JDK default | Supply your own HttpClient for proxying or custom TLS. |
objectMapper | Preconfigured | Supply your own Jackson mapper if you must; the default already handles dates and unknown fields. |
Spring configuration
@Configuration
class EmnetConfig {
@Bean
EmnetClient emnetClient(
@Value("${emnet.base-url}") String baseUrl,
@Value("${emnet.api-key}") String apiKey) {
return EmnetClient.builder()
.baseUrl(baseUrl)
.apiKey(apiKey)
.build();
}
}emnet:
base-url: ${EMNET_BASE_URL} # no default — issued with your key
api-key: ${EMNET_API_KEY} # no default — fail fast if it is missingMethods
startPersonVerification()
AuthorizeUrlResponse start = emnet.startPersonVerification();
start.authorizeUrl(); // redirect the user here
start.state(); // store this against their sessioncompletePersonVerification(code, state)
VerifiedIdentity identity = emnet.completePersonVerification(code, state);
// or with the request object
VerifiedIdentity identity = emnet.completePersonVerification(
new FaydaCallbackRequest(code, state));Requires a secret key. See Claims & identity keys for what the result contains.
getSession(sessionId)
VerificationSessionView view = emnet.getSession(4711L);
view.status(); // "COMPLETED"
view.assuranceLevel();
view.completedAt();Error handling
| Exception | When | Carries |
|---|---|---|
EmnetApiException | The API returned a non-2xx status | status() and body() |
EmnetException | Transport failure, timeout or a response that could not be parsed | Message and cause |
EmnetApiException extends EmnetException, so catching the latter catches both.
try {
VerifiedIdentity identity = emnet.completePersonVerification(code, state);
users.markVerified(userId, identity);
} catch (EmnetApiException e) {
switch (e.status()) {
case 400 -> return badRequest("This verification link has expired. Please start again.");
case 403 -> throw new IllegalStateException("Publishable key used server-side — use a secret key");
case 429 -> return retryLater(); // honour Retry-After
case 503 -> return providerUnavailable();
default -> {
log.warn("Emnet returned {}", e.status()); // status only, never the body
return genericFailure();
}
}
} catch (EmnetException e) {
log.warn("Emnet call failed: {}", e.getMessage());
return genericFailure();
}body() exists for debugging in a controlled environment. Logging it risks writing personal data into a log aggregator that a much wider group can read. Log the status; look at the body only when you are actively debugging.
What the SDK will never do
- Log your API key, a national identifier or a released claim — at any log level.
- Retry automatically. Retry policy is yours, because only you know whether the operation is safe to repeat.
- Cache verification results. Store what you need in your own database.
- Pull in a web framework, a DI container or a logging implementation.
Testing
Point a test key at the API in your integration tests — test verifications are free and unlimited, so there is no reason to mock the transport. For unit tests, inject a stub HttpClient through the builder.
@Test
void completesAVerification() {
EmnetClient emnet = EmnetClient.builder()
.baseUrl(System.getenv("EMNET_BASE_URL"))
.apiKey(System.getenv("EMNET_TEST_API_KEY")) // sk_test_...
.build();
AuthorizeUrlResponse start = emnet.startPersonVerification();
assertThat(start.authorizeUrl()).startsWith("https://");
assertThat(start.state()).isNotBlank();
}Other languages
Java is the only officially supported SDK today. Every endpoint is plain JSON over HTTPS, so any language integrates directly — see the API reference, or generate a client from the OpenAPI document shipped with the SDK.