In a mobile app (Flutter, React Native, native)

Open the hosted_url in a Custom Tab (Android) or an SFSafariViewController (iOS): the wallet opens from that view through its deep link, and the user comes back into your app through your success_url as a universal link (https, so compatible). Your backend then confirms through GET /verify/sessions/{id}, exactly as on the web. success_url means the verification succeeded, never that the user is of age: a proof of age that is false lands there too, like any verified result. Read the result server-side (claims.age_over_18 with the age_over_18 shortcut) and apply your own rule to it. Never put the license token inside the app: your backend creates the journey and reads the result.

Native use cases, through the session API

When you want to draw the screen yourself, the direct session API (technical reference) gives you the raw authorization request, to display however you like.

Your own QR screen (cross-device)

Create the session through POST /verify/sessions, display the authorization request in your interface (QR or link), and poll the session status: the user scans with their phone's wallet while sitting in front of your screen. It is the mode the hosted page uses, without its layout.

Kiosk, counter, in-person handover

Same mechanics on a kiosk or a counter tablet: your screen displays the QR, the customer scans, the agent sees the result arrive. The session expires on its own if nobody answers: nothing to clean up.

Proof already in hand: direct verification

If your journey already gave you the presentation (SD-JWT VC or mdoc) through another channel, POST /verify/sd-jwt-vc and POST /verify/mdoc verify it with no session and no page: one request, one answer.

The three rules that never change. The license token stays server-side. The result is confirmed through an authenticated GET /verify/sessions/{id}, never on the basis of a URL parameter or a browser event. And there is nothing to store: no ID copy, no photo, only the verified answer you asked for, as explained in the FAQ.