Skip to main content
Use a dedicated wallet endpoint to verify a person from your own application. You do not need to create or publish a workflow, or provide a workflow_id. Your backend starts the verification and retrieves its result; your interface guides the person through the wallet’s required authentication.
An API integration still requires the person to authenticate and approve sharing their identity. You cannot verify someone by submitting their personal identifier without that interaction.

How verification works

  1. Your backend checks the wallet catalog, then calls an available wallet’s start endpoint using your application API key.
  2. Didit returns a verification reference and the action the person needs to take.
  3. Your application opens the authentication page or displays the wallet’s approval instructions.
  4. The person authenticates with their wallet.
  5. Your backend retrieves the verified result and handles completion notifications.
Wallet authentication is asynchronous. A successful start request means authentication has started; it does not mean the identity has been verified. Always check the final result before treating the person as verified.

Backend integration

Use List digital ID wallets to obtain the current endpoints, required fields and availability for your application. Keep your x-api-key on your backend. Do not place it in a browser bundle or mobile application. Use a distinct Idempotency-Key for each new verification attempt and reuse that key when retrying the same start request. Changing the request while reusing its key is a conflict, not a new verification attempt. Each wallet has its own start URL, such as /v3/id-verification/wallets/ftn/ for Finnish Trust Network. The request_id identifies the standalone verification for subsequent operations. Use vendor_data for your own reference, up to 2,000 UTF-8 bytes, and metadata for an optional JSON object. Both are returned with the result and completion webhook. These operations use the API key of the application that started the verification. Polling and authentication availability depend on the selected wallet. A cancel declines a pending verification without charging for it, and returns a completed one unchanged. For Smart-ID and Mobile-ID, a cancel that arrives while a poll is checking the approval waits a few seconds for that poll. It then declines the verification, or returns it as verified if the person had already approved. A verification the person is completing at that moment cannot be cancelled: the response is 409 with error: "verification_in_progress" and a Retry-After header. Retry after that many seconds to read the completed result.

Register your return destination

Redirect wallets send the person back to your application after authentication. Register the exact hostname before starting a verification:
Then send an HTTPS return_url, such as https://app.example.com/identity/complete, in the start request. Use bare hostnames in allowed_return_hosts, without a scheme, path or wildcard. Register each subdomain you use separately, up to 20 hostnames. Updating allowed_return_hosts replaces the registered list, so include every hostname you want to keep. GET /v3/webhook/ returns the current list; see Webhook configuration. You do not need a workflow or a white-label domain to register a return destination. The destination is a browser return page; configure completion webhooks separately for your backend.

Example: Finnish Trust Network

After registering your return hostname, start a Finnish Trust Network verification:
Save the returned request_id and send the person’s browser to wallet_verification.next_action.url when its type is redirect. After the person returns, retrieve the result from your backend:
Check wallet_verification.outcome: Only use the identity when the outcome is verified and simulated is false for a real identity check. A pending response can carry a next action; terminal responses have no next action.

Authentication experiences

Redirect wallets return an authentication URL. Open that URL in the person’s browser, let them complete the wallet’s authentication process and return them to your registered destination. Read the result from your backend instead of trusting a return URL parameter as proof of identity. Smart-ID and Mobile-ID use an approval prompt on the person’s phone. Your interface collects the required personal identifier; Mobile-ID also needs the associated phone number. Display the comparison code and instruct the person to approve only when it matches the code on their phone. Their PIN belongs in the wallet or phone prompt, never in your form or an API request. Poll from your backend at the returned poll_interval_seconds for prompt feedback. Didit also checks pending phone approvals in the background, so completion can reach your webhook after the person closes your page. The available interaction depends on the selected wallet. Do not assume every wallet supports an embedded form, a QR code or authentication without a browser.

Completion webhooks

Configure an application webhook destination for status.updated using the webhook integration guide. Use webhook_version: "v3" for the decision structure described here. Verify the webhook signature on your backend before processing it. The webhook’s session_id matches the request_id returned by the wallet API. A completed wallet identity appears in the webhook’s decision.id_verifications array with verification_method: "wallet". You can also use the identifier to retrieve the dedicated wallet API result. Handle approval and decline notifications, including cancelled and expired verifications. Make your webhook handler idempotent because failed deliveries are retried. A browser return is not a completion webhook and its query parameters are not proof of identity.

Returned identity

Use the normalized identity fields for names and dates of birth when those fields are returned. Wallet-specific attributes describe the identity information shared by the selected wallet. The available attributes vary by wallet and country. An authenticated identity does not imply that a portrait, address or every other requested attribute is available.

Test in sandbox

An application in Didit sandbox mode simulates wallet verification without contacting a wallet provider or charging credits. The response identifies these requests with wallet_verification.simulated: true. A simulated approval is sample data, not a verified real-world identity. For a redirect wallet, follow the returned URL to exercise the callback and return to your application. For Smart-ID or Mobile-ID, use the polling endpoint to complete the simulated approval; no notification is sent to a phone. To test failure handling, set sandbox_scenario to wallet_cancelled, wallet_timeout or wallet_provider_error when starting a request. Live applications reject sandbox_scenario. Didit sandbox simulation is separate from testing against a provider’s own test environment. Successful simulation does not establish live provider access or production availability.

Availability and pricing

Endpoint coverage and production wallet activation are separate. A wallet can have an API reference page while remaining unavailable for live authentication. Check the wallet’s country coverage and production status before implementing a live journey. See digital ID wallet pricing for published rates and availability. Wallet verification is separate from document capture and the free monthly document-verification allowance.

Choosing an integration

Use these APIs when you want to own the surrounding interface and application logic. Use the Sessions API when you want Didit’s hosted verification journey, workflow rules and configured fallback steps. Both approaches still require the wallet’s authentication and consent process.