Staging environment — data here is not production data
Browse documentation

Fidera documentation

Hosted onboarding

Issue a secure Flow capability, resume it across web and native devices, and integrate branding, sessions, and handoff.

Hosted onboarding gives one asynchronous Flow a responsive Fidera-hosted journey. A mobile link opens a registered tenant app when it is installed and falls back to the web. On desktop, camera-dependent steps display a QR code that resumes the same Flow on mobile.

Create an asynchronous onboarding Flow, then issue its access link:

curl https://api.fideralabs.com/v1/flows/$FLOW_ID/access-links \
  --request POST \
  --header "Authorization: Bearer $FIDERA_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"expires_in_seconds": 604800}'

The response includes a URL like:

https://verify.fideralabs.com/onboard/acme/{link_id}#token=fl_…

The complete URL is returned only by create and rotate. Store or deliver it at that moment; list responses never contain the fragment secret. The default expiry is seven days and the accepted range is one hour through thirty days. Only one unrevoked link exists per Flow.

Use the dashboard Flow detail page to copy the one-time URL or show its QR. Email and SMS delivery are deliberately outside this release.

Capability security

The link is the applicant credential. Treat it like a password:

  • do not put it in server logs, analytics, support tickets, query strings, or referrer headers;
  • do not prefetch or expand it through link-shortening services;
  • rotate it if it may have been disclosed, which revokes its sessions;
  • revoke it when the applicant should no longer be able to resume.

The secret is in a URL fragment, so it is not sent with the initial HTTP request. The hosted client removes it from browser history and exchanges it for a rotating Secure, HttpOnly, SameSite=Strict cookie. Native SDKs exchange it for a Flow-scoped bearer token held by Keychain or Android Keystore. Fidera stores hashes of link secrets, session tokens, and device instance IDs.

Sealing the Submission deactivates the link. The device that submitted keeps its session — it authenticates by session token, not by the link, so the applicant still sees their result — but the URL can no longer be redeemed by a new device. Presenting the correct secret for a deactivated link returns 410 with error.code gone; every other failure remains an indistinguishable 401, so the status never becomes an enumeration oracle. Issue a fresh link from the Flow if the applicant needs to send anything else, or re-run an individual check against the evidence already held.

Completion revokes write access for every device session. A session that has not been active for 30 minutes appears inactive, but the Flow remains resumable until the link or session expires. There is no abandoned Flow state.

Resume and concurrency

Each browser profile or app installation gets an independent FlowDeviceSession. All sessions read and update the same draft Submission owned by the Flow. Capture progress, applicant declarations, consent, documents, barcode observations, device/network observations, and liveness timings are parts of that evidence bundle—not a separate onboarding journey. Submission writes include the last-read version.

If another device wins the race, the API returns 409 with the current progress in error.details.current. Replace local state with that value and retry the user’s action. Document completion and processing requests accept Idempotency-Key headers and are safe to retry.

Tenant-authenticated session activity is available at:

GET /v1/flows/{flow_id}/device-sessions

The response includes channel, platform, SDK/app version, timestamps, expiry, and derived status. It never contains token or device identifiers.

Applicant API boundary

There are no onboarding-specific applicant endpoints. The capability is exchanged at POST /v1/flow-sessions; the current sanitized journey is read from GET /v1/flow-sessions/current. Applicant input and evidence entities are appended through versioned PATCH /v1/submissions/{submission_id} mutations. Documents use POST /v1/documents and POST /v1/document-completions. Sealing the Submission by setting state: submitted atomically creates the configured pending Checks and starts processing.

intake_fields on the Flow template names the details the journey collects in a short form before document capture — any of legal_name_first, legal_name_middle, legal_name_last, dob, nationality, gender, email, and phone. It defaults to first name, last name, and email, and is editable in Templates → Applicant details or over the API. applicant.missing_details on the session context resolves that list against what is already on file, so the applicant is asked only for what the operator could not supply when creating the Flow. Sealing is refused while any configured detail is unanswered, and an empty list skips the form entirely. Addresses live on their own relationship and are not collectable here. A name matters beyond contact: AML and adverse media have nothing to screen without one. Email is stored trimmed on the Applicant so email-intelligence checks can run asynchronously; phone is stored only as phone_hash. The evidence bundle records only that contact details were provided, and the session context reports has_email / has_phone rather than the values.

They never return matches, component Checks, operator notes, other Applicants, or tenant credentials. Any customer workflow built from the tenant-authenticated Check results belongs in the tenant's system.

GET /v1/flow-sessions/current carries an outcome of pending, approved, or in_review alongside journey_status. It is approved only when the Flow completed and every required Check came back clear; a flag, a provider error, a check that never ran, and a failed Flow all resolve to in_review. The applicant sees a confirmation or a "being reviewed, you can close this page" screen accordingly. The value is derived on each read — no Flow-level decision is persisted, and it never substitutes for an operator reading the individual Check results. FlowOut.outcome reports the same value to the tenant so an operator can see what the applicant was told.

Flow ownership

Onboarding is a Flow.kind, not a separate aggregate. Flow.type continues as a backwards-compatible classification for rules and reporting (id_document, id_and_selfie, enhanced, or checks), while Flow.kind identifies the business journey as onboarding or screening. Every onboarding created from the dashboard uses type=enhanced; the dashboard does not expose a separate classification choice. API callers may continue to send the older values for backwards compatibility. Every onboarding captures the identity document plus the same five-step biometric sequence. The selected Flow template controls allowed document types, passport NFC policy and baseline processing checks—not whether the baseline liveness sequence appears. enhanced is additive: after the document and biometric evidence is collected, the Flow also runs AML, IP, email, device, adverse-media, and FATF country-risk checks. Extracted document identity fields feed the person-based checks in the same processing pass. enhanced selects which checks run, not which watchlists the AML screen covers: the screen covers exactly the datasets requested. The console preselects enhanced_due_diligence for onboarding and lets the operator clear it. Access links can be issued only for onboarding Flows. The canonical journey, lifecycle, and completion state remain on the Flow; the independently retryable evidence and Checks remain on the Submission.

Capture and assurance

Capability Hosted web Installed iOS/Android
ID front and back; passport photo page Camera API Native camera
Passport MRZ Photo plus server processing On-device recognition plus server processing
Selfie Front-facing Camera API Native front camera
Active liveness On-device center, blink, head-circle, hand-wave, and smile checks plus video evidence Native face/hand tracking plus video evidence
E-passport chip Not supported Core NFC or Android IsoDep

Set allowed_document_types, passport_nfc_behavior, and document_capture_mode on the Flow template, all editable in Templates → Capture requirements. The NFC behavior is disabled, optional, or required. Optional journeys may continue with photo/MRZ and record lower assurance. Required journeys send web users to a registered native app. Server processing remains authoritative for evidence and assurance.

document_capture_mode is live_or_upload (the default), live_only, or upload_only, and decides whether the journey offers the camera, a file picker, or both. The client tags each image with a FideraDocumentCaptureV1 entity recording method as live_camera or file_upload, and sealing a live_only Submission whose documents claim a file upload is refused. That provenance is client-asserted and therefore low assurance in the same sense as the device fingerprint: it raises the cost of submitting a photo of a photo, it does not prove a camera was used.

Non-passport identity documents require both front and back uploads. For a driver's-license back, hosted web continuously looks for PDF417 and requires a valid AAMVA payload in the full-resolution captured image before continuing. When the live preview contains a valid payload, hosted web automatically captures that exact frame; a manual shutter remains available. The client appends the raw PDF417 payload, parsed AAMVA fields, decoder, and decoder version as a provenance-bearing FideraBarcodeObservationV1 entity. The server independently decodes the uploaded image and remains authoritative.

Sides without a barcode auto-capture on image quality instead. Hosted web gates on a sharpness estimate plus, for any side carrying a portrait, an on-device face detection whose box must exceed a minimum share of the frame — the same signal the iOS SDK checks after capture. Both must hold across consecutive frames before the shutter fires, and the manual shutter stays available throughout. Catching a missing portrait while the camera is still open avoids the face-match failure it would otherwise cause. Hosted active-liveness inference also runs locally in the browser from same-origin, integrity-pinned model assets. Preparation is time-bounded and returns a retryable error if camera, runtime, or model initialization stalls. The configured Flow receives the completed evidence, not the per-frame model inputs.

An App Clip is not used: Apple does not expose the required Core NFC passport operations to app extensions, and Web NFC does not expose the low-level ISO-DEP exchange needed by e-passports.

Branding and native apps

Administrators configure logo, primary color, support/privacy URLs, consent copy, and consent policy version through the flow-branding API. Consent records persist the exact policy version accepted by the applicant. The journey always shows a small “Powered by Fidera” footer.

Register native identifiers through the native-apps API:

  • iOS team ID and bundle ID;
  • Android package name and every release SHA-256 signing fingerprint;
  • enabled environments and tenant path.

Fidera publishes Apple’s AASA file and Android Digital Asset Links at the standard /.well-known paths. Validate production association files before enabling native routing. Universal Links and App Links naturally fall back to the hosted page when the app is not installed.

Audit and webhooks

Audit history records link creation/rotation/revocation, Flow-session start, resume, handoff, expiry/revocation, Submission mutation/sealing, and completion. Subscribe to flow_session.started, flow_session.resumed, flow_session.expired, and submission.completed. The previous onboarding.* event names remain accepted during migration. Treat webhooks as hints and reconcile the tenant-authenticated Flow idempotently.