Widget Delivery
The widget is a hosted web app that guides your customer through document and selfie capture. You do not build camera handling, framing guidance, or retry coaching β you deliver a URL.
The URL
POST /v1/sessions returns:
{ "widget_url": "https://{FQDN}/verify/8Kd2mQβ¦" }
The trailing segment is a single-use bootstrap code, not a session identifier. When the page loads, the browser exchanges it for a short-lived in-page token; the code itself grants nothing beyond starting that one verification.
| Property | Behavior |
|---|---|
| Lifetime | 48 hours from session creation |
| Scope | One session. It exposes no tenant data and cannot be used to read a result |
| Expired link | The customer sees an expired-link message β create a new session |
| Already-completed session | Reopening a finished verification shows a completion message rather than starting over |
Because the link is time-limited, generate it when you are ready to send it β not in advance, in bulk.
Three Ways to Deliver It
| Method | How | Good for |
|---|---|---|
| Redirect | Send the customer's browser to widget_url, and use redirect delivery to bring them back | Web onboarding flows |
| Native webview | Open widget_url in a system webview (WKWebView, Android WebView) with camera permission granted | Mobile apps that keep the customer in-app |
| Link out | Send the URL by SMS, WhatsApp, or email | Desktop or agent-assisted flows where the customer's phone has the better camera |
There is no JavaScript SDK, iframe API, or postMessage event stream. Completion is signalled server-side β by the signed webhook or the signed redirect β which is also what makes it trustworthy: the outcome your backend acts on never passes through the customer's browser unsigned.
Camera Requirements
Camera access requires a secure context. In practice:
- Serve or open the widget over HTTPS.
http://localhostandhttp://127.0.0.1also qualify, for local development. - In a native webview, grant camera permission before loading the URL β the OS prompt inside a webview is easy for customers to miss.
- Capture is camera-only by default. A file picker appears only if file upload is enabled for your tenant, so a customer cannot upload a stored photo of a document unless you have asked us to allow it.
Images are capped at 10 MB per capture, which the widget's own encoding stays well within.
What the Customer Sees
- Document type β passport, driver's license, or identity card. Skipped when you set
prefill.document_type, and limited to the types enabled for your tenant. - Document capture β a document-shaped mask (passport photo page and machine-readable zone, ID-1 card outline) with live framing, glare, and blur feedback. Two-sided documents prompt for the back.
- Confirmation β extracted fields are shown so the customer can spot a misread before continuing.
- Selfie β a face oval with capture guidance.
- Result β approved, declined, or an under-review message. In redirect mode the customer is returned to your URL instead.
Capture Retries
A capture that cannot be verified β too blurry to read, a photo of a screen, a face that does not match β returns the customer to the relevant step with specific feedback rather than failing the session outright.
| Behavior | Detail |
|---|---|
| Attempt limit | Your tenant default (3 unless configured otherwise), overridable per session with max_capture_attempts |
| On each failure | The customer sees targeted feedback for the specific problem and retries |
| On exhaustion | The session is declined, and you receive that result like any other, carrying a capture_attempts check that names the limit reached |
Raise the limit for a forgiving consumer flow; lower it where repeated failed captures are themselves a fraud signal.
Branding and Localization
Both are configured per tenant at onboarding β see Tenant Configuration.
Branding applies your logo, company name, and primary, background, and text colors to the widget chrome, so the flow reads as part of your product. The "Powered by Inyo 360" footer always renders and is intentionally not configurable.
Language comes from the session's language field, falling back to your configured default. English, Portuguese, and Spanish ship complete; any xx or xx-XX code is accepted, and any string without a translation falls back to English individually rather than dropping the whole language. Every string the widget renders is served from Inyo's copy store, so wording β including retry feedback and result screens β can be adjusted for your tenant without a release on your side.
Human-Presence Check
The widget may present a brief Cloudflare challenge when it starts, to keep automated traffic from consuming verifications. It is invisible or near-invisible to real customers and requires nothing from your integration.
Tracking Progress
You do not need to watch the customer's progress β the result is pushed to you β but GET /v1/sessions/{session_id} exposes a step field (document_front, document_back, selfie, done) if you want to show an in-progress state in your own UI or measure drop-off between steps.
Next Steps
- Receiving Results β signature verification for both delivery modes
- Tenant Configuration β branding, allowed document types, capture behavior
- Server-to-Server Verification β the alternative when you own the capture UI
