API reference
Emnet verification API v1. Three endpoints, JSON over HTTPS, authenticated with a bearer API key.
Base URL
$EMNET_BASE_URL/v1Your base URL is issued with your early-access key. The environment is resolved from your key — a test key reaches the sandbox, a live key reaches production. There is no separate hostname and no environment parameter. All requests must use HTTPS.
Authentication
Authorization: Bearer sk_live_…See Authentication for key types and rules. The badges below show which key types each endpoint accepts.
Start a verification
Creates a verification session and returns the URL to send the user to, plus the state value you must store and compare when they return.
Request
No parameters and no body. Everything is derived from your key.
curl "$EMNET_BASE_URL/v1/verification/person/fayda/authorize-url" \
-H "Authorization: Bearer sk_test_…"Response — 200
| Field | Type | Description |
|---|---|---|
authorizeUrl | string | Provider URL to redirect the user to. Single-use and time-limited. |
state | string | Opaque value tying the callback to this session. Store it; compare it on return. |
{
"authorizeUrl": "https://…/authorize?client_id=…&state=a7f3d21c9b0e",
"state": "a7f3d21c9b0e4f8a1c2e9b7d6a5c3e1f"
}Other statuses: 401 invalid key · 429 rate limited · 503 provider unavailable.
Complete a verification
Exchanges the authorization code for verified claims. Secret keys only — a publishable key receives 403. Always call this from your server.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Authorization code from the provider redirect. Single-use. |
state | string | Yes | The state value from the redirect. Compare it with your stored copy first. |
curl -X POST "$EMNET_BASE_URL/v1/verification/person/fayda/callback" \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"code":"8f3c9a1b7e2d","state":"a7f3d21c9b0e4f8a1c2e9b7d6a5c3e1f"}'Response — 200
| Field | Type | Description |
|---|---|---|
sessionId | integer | Identifier for this verification session. |
identityKey | string | Pseudonymous, stable-per-account identifier for the person. |
claims | object | Verified attributes released to your account, as string values. |
availableClaims | array | Claims the provider could return for your account. |
assuranceLevel | string | Assurance level of the authentication, e.g. "L2". |
livenessEvidence | string | Liveness signal where available; may be absent. |
provider | string | Identity provider, e.g. "FAYDA". |
source | string | Service within the provider, e.g. "esignet". |
verifiedAt | string | ISO-8601 UTC completion timestamp. |
environment | string | Which registry answered: "LIVE" (production registry, billable) or "TEST" (sandbox or simulator). Always equals your key’s environment. |
Consumer rule. Under your production profile, grant a tier or any decision from a result only if environment is exactly "LIVE". An absent or unrecognised value is refused, never defaulted. Emnet publishes the rule and does not enforce your side of it. The same value is on the session status view, so a poll and the result agree.
{
"sessionId": 4711,
"identityKey": "3f9c1a0b7e5d4c2a9b8e7f6d5c4b3a29…",
"claims": {
"name": "Yigermal Fantaye",
"birthdate": "1996-04-11",
"gender": "male"
},
"availableClaims": ["name", "birthdate", "gender", "address", "phone"],
"assuranceLevel": "L2",
"livenessEvidence": "PRESENTED",
"provider": "FAYDA",
"source": "esignet",
"verifiedAt": "2026-07-26T09:14:22Z",
"environment": "LIVE"
}Other statuses: 400 invalid or already-used code · 401 invalid key · 403 publishable key, or a claim your account is not entitled to · 429 rate limited · 503 provider unavailable.
Read a session
Returns the status and metadata of a verification session. Never returns claims, which is why a publishable key may call it.
Path parameter
| Name | Type | Description |
|---|---|---|
id | integer | The sessionId. |
curl "$EMNET_BASE_URL/v1/verification/person/session/4711" \
-H "Authorization: Bearer sk_live_…"Response — 200
| Field | Type | Description |
|---|---|---|
sessionId | integer | The session identifier. |
provider | string | Identity provider used. |
status | string | Session state, e.g. "COMPLETED". |
assuranceLevel | string | Assurance level, once completed. |
livenessEvidence | string | Liveness signal where available. |
environment | string | "LIVE" or "TEST" — the same value the verification result carries, so a poll and the result agree. |
completedAt | string | Completion timestamp, if completed. |
{
"sessionId": 4711,
"provider": "FAYDA",
"status": "COMPLETED",
"assuranceLevel": "L2",
"livenessEvidence": "PRESENTED",
"environment": "LIVE",
"completedAt": "2026-07-26T09:14:22Z"
}A session belonging to another account is reported as not found. Returning 403 would confirm that the session exists, which is information the API will not give up.
Other statuses: 401 invalid key · 404 unknown session, or not yours · 429 rate limited.
Error format
Every error shares one shape. Messages are safe to log — they never contain personal data.
{
"error": "invalid_request",
"message": "The authorization code has already been used.",
"status": 400
}See Errors for the full list and how to respond to each.
OpenAPI specification
The API is described by a hand-authored OpenAPI 3.0 document that is kept in step with the server by hand rather than generated from it — so it describes the contract we commit to, not an accident of implementation. It ships in the Java SDK repository at openapi/emnet-identity-v1.yaml and can be used to generate a client in any language.