Create a verification session
POST /api/verification/init — the request body, the verification types, the supported countries, the session the call returns, and the ways it fails.
Last updated: 2026-09-04
Starts a verification session and returns the URL to send the shopper to. This is the only call that creates state, the only billable one, and one of the three routes that require an API key.
POST https://api.eidas-pro.com/api/verification/init
Requires the x-merchant-api-key header — see authentication. Answers 201 Created on success.
Request body
curl -X POST https://api.eidas-pro.com/api/verification/init \
-H "x-merchant-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"verificationType": "age",
"method": "idin",
"redirectUrl": "https://shop.example.com/checkout/age-check",
"metadata": { "orderId": "1234" }
}'
| Field | Type | Required | Notes |
|---|---|---|---|
verificationType | age country both | yes | The only required field. |
method | eudi idin itsme | no | Target a specific verification method instead of the deployment's default. Only request one that /api/config lists. |
redirectUrl | string | no | Where the shopper's browser is sent after the identity step. Must be https on a public domain name. |
countryWhitelist | string array | no | ISO 3166-1 alpha-2 codes. Part of the country-verification contract. |
countryBlacklist | string array | no | ISO 3166-1 alpha-2 codes. Part of the country-verification contract. |
metadata | object | no | Opaque JSON echoed through the session. Use it to carry your own order or cart id. |
captchaToken | string | no | Required only when the deployment has a CAPTCHA secret configured. Maximum 2048 characters. |
licenseKey | string | no | Accepted for wire compatibility with older clients and ignored. Do not send it in new code. |
Unknown properties are rejected, not ignored: a body carrying a field that is not in this table answers 400 with code VALIDATION_ERROR. That is worth knowing when you are porting code from another provider — a field this API has never had, such as an age threshold parameter, will fail the whole request rather than being quietly dropped.
There is no request field that sets the age threshold
The implemented path checks a fixed 18-and-over threshold. No request field selects a different age, and inventing one gets the request rejected as an unknown property. If your use case needs a different threshold, treat that as a product question, not an API parameter.
Verification types
verificationType accepts three values at the request-validation level:
age— is the shopper at least the threshold age?country— is the shopper's verified country one you allow?both— age and country in one session.
GET /api/config's supportedVerificationTypes tells you which of these a given deployment can actually deliver — read it rather than assuming all three work. The currently implemented path — bank-identity methods delivered through a broker — serves age only, so supportedVerificationTypes lists age once a broker method is configured there, and is empty when none is. Sending country or both to that path answers 400 rather than silently downgrading them to an age check that can never satisfy what you asked for. countryWhitelist and countryBlacklist are accepted by the request body for the same reason and are not evaluated by that path.
Supported countries
GET /api/config reports 32 under supportedCountries — the 27 EU member states plus Iceland, Liechtenstein, Norway, Switzerland, and the United Kingdom:
AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL
PL PT RO SK SI ES SE IS LI NO CH GB
Read the live endpoint rather than hard-coding this list, and read supportedMethods from the same response to learn which verification methods that particular deployment can actually serve. An empty supportedMethods array means none are configured there yet.
Response
{
"sessionId": "0f3c1c2b-9a4d-4d1f-8c1a-2b6d5e4f7a90",
"expiresAt": "2026-09-04T12:15:00.000Z",
"authorizationUrl": "https://broker.example/authorize?..."
}
| Field | Notes |
|---|---|
sessionId | UUID. Every other call in the flow takes it, so store it against your order. |
expiresAt | ISO 8601 timestamp. Sessions on the broker path live 15 minutes from creation. |
authorizationUrl | Where to send the shopper's browser. Present on the redirect-based path. |
qrCodeUrl | Declared by the response contract for paths that present a QR code. Absent on the redirect-based path — treat it as optional and never assume it is there. |
Send the shopper to authorizationUrl, then wait for the verdict: watch the event stream or poll the status from the browser, and read the authoritative answer from the result endpoint on your server.
Failures
| Status | code | Cause |
|---|---|---|
400 | VALIDATION_ERROR | Missing or invalid verificationType, an unknown property, a method or verification type the active path cannot serve, or a failed CAPTCHA check. |
400 | REDIRECT_HOST_NOT_ALLOWED | redirectUrl is not https on a public domain name. Rejected here, at session creation, rather than after a real shopper has finished a bank flow. |
401 | INVALID_MERCHANT_KEY | Key missing, unknown, revoked, or expired — identical response for all of them. |
402 | NO_SUBSCRIPTION | Valid key, no active subscription. |
403 | LAYER_NOT_ENTITLED | Active subscription that does not include the electronic-identity layer. |
429 | RATE_LIMIT_EXCEEDED | Per-minute ceiling reached. Wait the seconds in the Retry-After header (also repeated as retryAfter in the body). |
503 | METHOD_UNAVAILABLE | The deployment has no credentials configured for the requested method, so it fails closed. |
503 | BROKER_UNAVAILABLE | The identity provider could not be reached right now. Retryable; no session was created. |
Branch on code, not on the human-readable message — see errors and status codes.