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.

What you get
sk_test_…
You will see this value once

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.

VerificationController.java
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());
Store the state

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:

Redirect back to you
GET /verify/callback?code=8f3c9a1b7e2d&state=a7f3d21c9b0e HTTP/1.1

5 · Exchange the code for claims

This call requires a secret key and must happen on your server. Check the state first.

Callback handler
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, provider and verifiedAt — your audit trail for how this attribute was established.
Do not store what you were not asked to store

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

Spring MVC, both halves
@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.