API Reference
Exact browser-facing endpoints, parameters, response formats, callback query parameters, and popup message contracts for custom integrations.
API Reference
This page documents the exact browser-facing contract used by the SDK.
Use it when you want API-style reference tables rather than implementation walkthroughs.
End-To-End Sequence
| Step | Result |
|---|---|
1. Merchant frontend calls /api/v1/oidc/create | UNQVerify creates a verification session |
| 2. UNQVerify returns a broker authorization URL | Frontend redirects the browser to that URL |
| 3. Broker flow returns to the UNQVerify callback | UNQVerify completes the verification exchange |
4. UNQVerify redirects the user to your RedirectUri with jwt | Your app verifies the token and updates state |
Environments
| Environment | Public key prefix | API base | Verification issuer |
|---|---|---|---|
| Test | pk_test_ | https://test.api.aldersverificering.dk | https://test.aldersverificering.dk |
| Production | pk_live_ | https://api.aldersverificering.dk | https://aldersverificering.dk |
Create Verification Session
Starts a browser verification flow and returns a redirect URL as plain text.
Endpoints
| Environment | Method | Full URL |
|---|---|---|
| Test | POST | https://test.api.aldersverificering.dk/api/v1/oidc/create |
| Production | POST | https://api.aldersverificering.dk/api/v1/oidc/create |
Headers
| Header | Required | Example | Notes |
|---|---|---|---|
x-public-key | Yes | pk_test_abc123 | Must match the target environment |
Content-Type | Yes | application/json | Required by the SDK request, even though no JSON body is sent |
Query Parameters
| Parameter | Type | Required | Example | Notes |
|---|---|---|---|---|
RedirectUri | string | Yes | https://shop.example.com/verify-result | Must be a real callback page in your app |
AgeToVerify | number | Yes | 18 | Minimum required age |
Request Body
| Body | Required | Format |
|---|---|---|
| Request body | No | Empty |
Success Response
| Property | Value |
|---|---|
| HTTP status | 200 OK |
| Content type | Plain text |
| Response body | Redirect URL string to the MitID/OIDC authorization flow |
Example response body:
https://aldersverificering.dk/oidc/authorize?client_id=...Real test example:
Request:
POST https://test.api.aldersverificering.dk/api/v1/oidc/create?RedirectUri=https%3A%2F%2Funqverify-app.myshopify.com%2F&AgeToVerify=18Response body:
https://pp.netseidbroker.dk/op/connect/authorize?client_id=0b5ac04e-5dbb-4bb8-a697-93152896a2f6&redirect_uri=https%3A%2F%2Ftest.api.aldersverificering.dk%2Fapi%2Fv1%2Foidc%2Fcallback%3FredirectUri%3Dhttps%253A%252F%252Funqverify-app.myshopify.com%252F%26nonce%3D17959b87-7d8a-4aac-b88c-05a005bb194f%26internalCustomerId%3D6952c411cd0a2cfed100fcc5%26internalRequestEventId%3D69bd093ceef79d9928ef28c0&response_type=code&scope=openid%20age_verify%3A18&prompt=login&nonce=17959b87-7d8a-4aac-b88c-05a005bb194fThat returned URL is the MitID broker portal entrypoint. Your frontend should treat it as an opaque redirect target and send the browser to it exactly as returned.
Response URL Semantics
| Part | Meaning |
|---|---|
Host, for example pp.netseidbroker.dk | The MitID/OIDC broker endpoint |
client_id | Broker client configured for the selected environment |
redirect_uri | UNQVerify callback endpoint, not your merchant callback directly |
scope | Includes the requested age verification scope, for example age_verify:18 |
nonce | Per-request anti-replay value generated by the backend |
You should not parse business logic out of this URL. Use it only as the next redirect target.
Error Response
| Property | Value |
|---|---|
| HTTP status | Non-2xx |
| Response body | Plain text error body |
Example error handling shape:
const response = await fetch(url, options)
if (!response.ok) {
const errorBody = await response.text()
throw new Error(`API error: ${response.status} - ${errorBody}`)
}Example Request
curl -X POST \
'https://test.api.aldersverificering.dk/api/v1/oidc/create?RedirectUri=https%3A%2F%2Fshop.example.com%2Fverify-result&AgeToVerify=18' \
-H 'Content-Type: application/json' \
-H 'x-public-key: pk_test_your_key'Redirect Callback Contract
After the user completes verification, the browser returns to your RedirectUri.
Query Parameters Returned To Your Callback Page
| Parameter | Type | Required | Example | Notes |
|---|---|---|---|---|
jwt | string | Yes | eyJhbGciOiJSUzI1NiIs... | Signed verification token |
Expected Callback Behavior
| Step | Required | Notes |
|---|---|---|
Read jwt from the URL | Yes | Missing jwt should be treated as TOKEN_INVALID |
| Verify JWT signature against JWKS | Yes | Do not trust the token before verification |
Check exp | Yes | Reject expired tokens |
Check aldersverificeringdk_verification_result | Yes | false means UNDER_AGE, not a token error |
Remove jwt from the browser URL | Recommended | Prevents reuse through copied URLs, logs, and browser history |
Verification JWT Claims
| Claim | Type | Example | Meaning |
|---|---|---|---|
iss | string | https://test.aldersverificering.dk | Issuer used to choose the correct JWKS endpoint |
exp | number | 1773980000 | Unix timestamp for token expiry |
iat | number | 1773978200 | Token issue time when present |
aldersverificeringdk_verification_result | boolean | true | Whether the user met the age threshold |
aldersverificeringdk_verification_age | number | 21 | Verified age returned from the flow |
JWKS Endpoints
Use the token issuer to choose the correct JWKS endpoint for RS256 signature verification.
| Token issuer | JWKS URL |
|---|---|
https://test.aldersverificering.dk | https://test.api.aldersverificering.dk/well-known/openid-configuration/jwks |
https://aldersverificering.dk | https://api.aldersverificering.dk/well-known/openid-configuration/jwks |
Popup Message Contract
If you use popup flow, the callback page posts the verification result back to the opener window.
Success Message
| Field | Type | Required | Example | Notes |
|---|---|---|---|---|
type | string | Yes | UNQVERIFY_RESULT | Message discriminator |
payload | object | Yes | See JWT claims table above | Decoded verification payload |
Example:
{
"type": "UNQVERIFY_RESULT",
"payload": {
"iss": "https://test.aldersverificering.dk",
"exp": 1773980000,
"aldersverificeringdk_verification_result": true,
"aldersverificeringdk_verification_age": 21
}
}Failure Message
| Field | Type | Required | Example | Notes |
|---|---|---|---|---|
type | string | Yes | UNQVERIFY_FAILURE | Message discriminator |
error | string | Yes | Token has expired | Human-readable error text |
code | string | Yes | TOKEN_INVALID | Machine-readable outcome code |
Example:
{
"type": "UNQVERIFY_FAILURE",
"error": "User does not meet the age requirement",
"code": "UNDER_AGE"
}Recommended Outcome Codes
| Code | Meaning |
|---|---|
UNDER_AGE | Verification completed but the user did not meet the age requirement |
POPUP_CLOSED | The user closed the popup before completion |
USER_CANCELLED | The user explicitly cancelled the verification flow |
POPUP_BLOCKED | Browser refused to open the popup |
POPUP_TIMEOUT | Popup flow exceeded your local timeout |
UNTRUSTED_ORIGIN | Popup message came from an origin you do not trust |
NETWORK_ERROR | Failed to create the verification session |
TOKEN_INVALID | Returned JWT failed verification or claim validation |
UNKNOWN_ERROR | Any other technical failure |
Storage Contract Used By The SDK
If you want parity with the current SDK behavior:
| Field | Value |
|---|---|
| Cookie name | unqverify_token |
| Cookie attributes | path=/; SameSite=Lax; Secure |
| Minimum lifetime | 3600 seconds |
| Actual lifetime | Greater of JWT expiry and 1 hour |
This storage contract is browser-readable because it is set from JavaScript. It is appropriate for UI state, but backend authorization should still validate the JWT or rely on a server-issued session.