Skip to main content
A user who reaches the journey from inside your own app has already signed in to you, and asking for their mobile number again asks them to prove the same thing twice. A handoff is a single-use address that opens the journey with them already signed in. Hosted compares this with journey_url, the link on every record that you send over any channel. Create the verification the way you always do. Creating is idempotent per user and workflow, so you can create once and hand off on every visit after that.
Create the handoff
Response

Rules

  • Create the handoff at the moment you open the browser, not in advance. It is valid for expires_in_seconds, and it stops working once it has been used.
  • One handoff carries the whole visit. While that browser keeps its site storage the user stays signed in, so backgrounding your app and coming back needs nothing new. Create another when you open a new browser, or when you open the journey for a different user.
  • Keep your API key on your server. Your app asks your backend for the handoff, and your backend asks us. A key shipped inside an app is a key you cannot rotate away from your users.
  • Pass the URL through unchanged, fragment included. Everything after the # is what signs the user in, so a component that drops or rewrites the fragment breaks the handoff.
  • Treat the URL as a credential. Do not log it, store it, print it into a QR code, or send it anywhere you would not send a password. When you want something you can send, send journey_url.
A handoff that has expired or has already been used is not an error. The journey opens and asks the user for their mobile number, exactly as journey_url does. A late handoff costs the user a sign-in, never the journey.

What the in-app browser must support

A workflow with a selfie or premises-photos step captures through the camera, and a workflow with a DigiLocker step sends the user out to a consent screen and back. Whichever browser component you open the handoff in has to carry both. iOS. Open the handoff in a WKWebView with allowsInlineMediaPlayback set, an empty mediaTypesRequiringUserActionForPlayback, NSCameraUsageDescription declared in your Info.plist, and a persistent WKWebsiteDataStore. SFSafariViewController does not offer the camera to the page, so the selfie and premises-photos steps cannot be completed in it. Android. Open the handoff in a Chrome Custom Tab, or in a WebView that holds the CAMERA runtime permission, grants RESOURCE_VIDEO_CAPTURE in WebChromeClient.onPermissionRequest, and has DOM storage enabled.

Getting the user back into your app

On submit the journey redirects to your return_url. It must be one of the return URLs registered for your account and it must use https, so a custom scheme such as acme://kyc/done is rejected. Register a universal link (iOS) or an app link (Android) that your app intercepts: submitting then closes the browser and lands the user back in your own screens.
The redirect carries verification_id and status, which render a landing screen and are not proof of the outcome. Confirm the result by polling GET /verifications/{verification_id}, as in Reading the result.