Quickstart
Get a test key, start a verification, and read back verified claims. Everything below runs on a free test key against the provider’s sandbox.
Before you start
- An early-access test secret key (step 1).
- A server you can run — the callback exchange must happen server-side.
- A redirect URL we can send users back to, registered on your account.
1 · Request a test key
Emnet is in early access. Request a secret test key by writing to sales@emnetid.com; a self-serve developer dashboard follows at general availability. Your base URL is issued with your early-access key — the examples below read it from EMNET_BASE_URL.
sk_test_…Emnet stores only a hash of your key, so we cannot show it to you again or recover it. Put it in your secret manager now. If it is lost or exposed, email security@emnetid.com at once with the key’s prefix and last four characters (never the key itself); we revoke it immediately and issue a replacement to your account’s registered contact.
2 · Install the SDK
The SDK is distributed with your early-access key, together with its install instructions. See the Java SDK guide for what it contains.
Prefer no dependency at all? Every step below is a plain HTTPS call — see the API reference for curl equivalents.
3 · Start a verification
Create the client once and reuse it — it is immutable and thread-safe. Then ask for an authorization URL.
EmnetClient emnet = new EmnetClient(
System.getenv("EMNET_BASE_URL"),
System.getenv("EMNET_API_KEY")); // sk_test_...
AuthorizeUrlResponse start = emnet.startPersonVerification();
// Keep the state alongside your user, then redirect them.
session.setAttribute("emnetState", start.state());
response.sendRedirect(start.authorizeUrl());The state value ties the redirect back to the user who began it. Store it against your session or user record — you must send it back in step 5, and comparing it is what stops someone else’s verification being attached to your user.
4 · Your user authenticates
They authenticate with Fayda and consent to releasing the claims your account is entitled to. Their credentials never pass through your servers or ours. Fayda then redirects them back to your registered URL with two query parameters:
GET /verify/callback?code=8f3c9a1b7e2d&state=a7f3d21c9b0e HTTP/1.15 · Exchange the code for claims
This call requires a secret key and must happen on your server. Check the state first.
String expected = (String) session.getAttribute("emnetState");
if (expected == null || !expected.equals(state)) {
throw new IllegalStateException("state mismatch — reject this callback");
}
VerifiedIdentity identity = emnet.completePersonVerification(code, state);
String key = identity.identityKey(); // stable per-tenant pseudonym
String name = identity.claims().get("name");
String birthdate = identity.claims().get("birthdate");
String assurance = identity.assuranceLevel(); // e.g. "L2"
users.markVerified(currentUserId, key, name, birthdate, assurance);6 · Store the result
Persist against your own user record:
identityKey— index it. This is how you recognise the same person later and how you detect duplicate signups.- The claims you actually need, and nothing more.
assuranceLevel,providerandverifiedAt— your audit trail for how this attribute was established.
Keep the claims your product genuinely uses. Every additional personal attribute you persist is one more thing to protect, disclose and eventually delete.
Full example
@RestController
@RequestMapping("/verify")
class VerificationController {
private final EmnetClient emnet = EmnetClient.builder()
.baseUrl(System.getenv("EMNET_BASE_URL"))
.apiKey(System.getenv("EMNET_API_KEY"))
.build();
@GetMapping("/start")
void start(HttpSession session, HttpServletResponse response) throws IOException {
AuthorizeUrlResponse start = emnet.startPersonVerification();
session.setAttribute("emnetState", start.state());
response.sendRedirect(start.authorizeUrl());
}
@GetMapping("/callback")
ResponseEntity<?> callback(@RequestParam String code,
@RequestParam String state,
HttpSession session) {
String expected = (String) session.getAttribute("emnetState");
if (expected == null || !expected.equals(state)) {
return ResponseEntity.badRequest().body("state mismatch");
}
session.removeAttribute("emnetState");
try {
VerifiedIdentity identity = emnet.completePersonVerification(code, state);
users.markVerified(session.getId(), identity);
return ResponseEntity.ok().build();
} catch (EmnetApiException e) {
log.warn("verification failed: status={}", e.status()); // never log the body
return ResponseEntity.status(502).body("verification failed");
}
}
}Next
- Verification flow — what happens between the two calls, and how to handle abandonment.
- Errors — what each status code means and how to respond.
- Going live — the checklist for switching to live keys.