Skip to main content
Use this guide to add Minerva identity verification (IDV) to your customer onboarding. You create a verification session for a customer profile, deliver the verification flow to your customer, and react to the outcome in your own systems. The guide covers the API calls end to end: creating the profile and the session, the two ways to deliver the flow, the state model, and the webhooks your production systems should subscribe to.

How it fits together

Four pieces work together:
  • A profile is the customer record in Minerva, created through the Profiles API.
  • An IDV session is one verification attempt tied to a profile. It carries the capture flow (consent, liveness and document captures, questionnaire) and the review outcome.
  • Review is the decision layer. Most sessions pass without a human; some are held for an analyst in your Minerva workspace to accept or reject.
  • Webhooks tell your systems when a session changes state, so you do not have to poll.

Before you begin

  • You need an application API key for your workspace. Create one from the Developers page; API Keys has the walkthrough. Keys are server-side credentials, so never ship one in a browser or a mobile app.
  • You need a profile for the customer. If it does not exist yet, create it first (Step 1).
  • Every endpoint in this guide uses the base URL https://api.gominerva.com/idv/v1 and authenticates with Authorization: Api-Key <YOUR_API_KEY>.
Identity verification is rolling out across Minerva workspaces. Contact support@gominerva.com to enable it for your workspace. The API surface may still change while the rollout completes.

Step 1: Create the profile

Every verification session belongs to a Minerva profile. You have two options:
  • Create the profile on its own with POST https://api.gominerva.com/clm/v1/profiles, then create the session yourself with the rest of this guide. See Create a profile.
  • Create and onboard the profile in one call with POST https://api.gominerva.com/clm/v1/onboarding/profiles, using an onboarding block to enable screening, identity verification, or both. See Create and screen a profile.
An onboarding block that enables both components looks like this:
A few rules for the block:
  • Enabling IDV requires an email address on the profile and a workflow: either an explicit workflowId or your workspace’s default.
  • sequence is one of screening_first (the default), idv_first, or parallel.
  • When IDV onboarding is enabled, Minerva starts the verification session for the profile as part of the run. The rest of this guide covers the explicit flow, where your backend creates the session and delivers the invite itself.

Step 2: Create the IDV session

Create a verification session for the profile:
Fields to know:
  • profile_id is required. The profile must already exist in your workspace: a missing profile returns 400 idv_profile_not_found, and an unavailable profiles service returns 503 idv_profile_lookup_unavailable.
  • workflow picks a preset flow: liveness_and_id, liveness_only, or id_only. You can instead pass a workflow_id you configured, pass an inline steps manifest, or omit all three to use your workspace’s default workflow.
  • idempotency_key is an optional retry key (1 to 160 characters of letters, digits, and ., _, :, -). A retry with the same key and the same request returns the original session instead of creating a second one; reusing the key for a materially different request returns 409 idv_session_idempotency_conflict.
The response is 201 with the session, a one-time session_token, and token_expires_at:
session_token is the end-user capture credential for this session. It is surfaced only once, expires (15 minutes by default), and cannot be recovered or rotated; an idempotent replay returns it empty on purpose.

Step 3: Deliver the verification flow

Choose one of two delivery modes for the session you just created.

Email invite

  • The recipient is always the email address on the linked profile, resolved at send time. The request does not accept a recipient. A profile without an email returns 422 idv_profile_email_missing.
  • Success is a 202 with invited: true and invite_expires_at. A delivery_state of sent means the email provider durably accepted the message.
  • The emailed link is valid for 72 hours by default and stays reusable within that window, so a customer can reopen the email or continue on another device.
  • Pass an Idempotency-Key header to make email retries safe (direct links ignore it; without a header Minerva generates its own key). A replay with the same key never sends a second email; it reports the delivery’s durable state instead: 202 with delivery_state: "sent" once the provider has accepted the message, or 502 invite_delivery_failed otherwise. While a send is still in flight, including an ambiguous provider outcome, a different key is refused with 409 idv_state_conflict; retry once it settles. After the earlier send has settled (delivered or terminally failed), a new key can replace it and email again.
  • Optional presentation fields: locale and org_name (which overrides the theme company name in the email).
  • The response is a 200 with verify_url and invite_expires_at. Hand the link to the user immediately: redirect to it or open it in a web view.
  • Direct links work only with application keys. Dashboard-authenticated callers receive 403 idv_direct_invite_forbidden.
  • The link is single-use and expires within 15 minutes (900 seconds, and the lifetime cannot be raised).
  • The one-time credential sits in the URL fragment (#code=...), which browsers never send to servers and Minerva never logs. Treat the whole URL as a secret.
  • If Minerva cannot construct a secure public link, the request fails closed with 503 idv_direct_invite_unavailable.

Which mode should you use?

An integration cannot mint an arbitrary long-lived link. Treat the email invite as the user-delivery path and the direct link as the immediate-handoff path for a user who is ready right now.

Embed the hosted flow on your site

The hosted verification page can run in an iframe for a workflow that allows your site’s HTTPS origin. An Owner or Admin in your Minerva workspace can configure it:
  1. Open Configuration → Verification Workflows in the Minerva dashboard and edit the workflow.
  2. Under Embedding security, turn on Allow iframe embedding. Enter each Allowed parent origin on its own line, for example https://example.com, then save the workflow. Add https://www.example.com separately if you use that origin too; the two origins do not match each other.
  3. Have your backend create a new session with this workflow_id and request a direct link with delivery: "none". Put the returned verify_url in the iframe immediately. The direct link is single-use and expires within 15 minutes.
Keep your application API key on your backend and treat the full verify_url as a secret: its fragment contains the invite credential. Do not log, store, or expose it beyond the customer’s immediate handoff. If your site sets a restrictive Content Security Policy, allow https://idv.gominerva.com in frame-src. For workflows with camera capture, your site’s Permissions Policy must also permit camera delegation to the frame; the allow="camera" attribute cannot override a policy that blocks it. A questionnaire-only flow does not need camera access. Embedding is off by default. The setting and allowed origins are copied when a session is created, so existing sessions retain their prior framing policy. When embedding is disabled, the origin does not match, or the policy cannot be loaded, the hosted page denies framing. Other hosted routes remain unavailable for embedding.

Optional questionnaire-only approval

The same workflow editor has Approve questionnaire-only submissions automatically under Review and flags. An Owner or Admin in your Minerva workspace can turn it on when every workflow step is a questionnaire; individual steps may be optional. You can enable it on an existing workflow without recreating the questionnaire. The switch is off by default and independent of iframe embedding. A completed submission with at least one answer on a step the applicant has not skipped can then receive automatic_pass and an idv.session.approved webhook without human review. This approves self-reported answers; it does not verify the person’s identity, documents, or biometrics. Leave the switch off if your policy requires a reviewer to verify those details. For API-managed workflows, the corresponding fields are iframe_enabled, allowed_frame_origins, and auto_approve_questionnaire_only on the workflow object. When you change any of these fields with a full workflow PUT, include "supported_features": ["workflow_security_and_questionnaire_approval_v1"] in the request. Only assert this capability if your editor reads and preserves all three fields; an older editor cannot update a policy it does not understand. Use an exact HTTPS origin with no path, or a leftmost subdomain wildcard such as https://*.example.com. A wildcard for subdomains does not include the apex origin. These settings apply to new sessions after the workflow is saved.

What the customer sees

Verification runs on Minerva’s white-label page at idv.gominerva.com, styled with the theme attached to the session. The customer:
  1. Opens the link from the email, or arrives through your handoff.
  2. Reviews and accepts the consent notice.
  3. Completes the workflow steps, for example a questionnaire, liveness selfie, or photos of an identity document.
  4. Submits the session for assessment.
The customer experience shows progress and completion only. It never shows review states, flags, or analyst details; those live in your Minerva workspace and in webhooks.

Step 4: Track progress

Read GET /sessions/{sessionId} with your application key, or subscribe to webhooks and let Minerva push transitions to you (recommended for production). Every IDV webhook carries the same sessionId you use with GET /sessions/{sessionId}, and it does not change for the life of the session, so use it to continue the same session in your system. A session carries two independent state axes.

Flow status

Review status

The capture endpoint GET /sessions/{sessionId}/status belongs to the hosted verification page: it accepts only the session’s capture or invite credential, not your application API key. Track backend progress from GET /sessions/ {sessionId}, GET /sessions?profile_id=..., or webhooks.

Step 5: Cancel a session

  • Cancellation is irreversible and moves the session to canceled.
  • It consumes the capture token and the invite, so the link stops working for further capture.
  • Re-canceling an already canceled session is a no-op, not an error.
  • A session that is currently being assessed cannot be canceled: the call returns 409 idv_state_conflict (the same code covers other terminal states).
  • The optional reason is recorded internally and is never shown to the customer.

Step 6: Read results and review outcomes

Structured results

GET /sessions/{sessionId}/data returns the authorized, decrypted results for a session:
  • The document record: type, issuing country and subdivision, and confidence.
  • OCR field values with per-field confidence.
  • Questionnaire answers, with the step and question each answer belongs to.
  • Any mismatch details between the captured data and the profile.
Two properties to design around:
  • Every access, success or denial, is written to an audit log before the response is returned. If the audit write fails, the request fails closed with no data.
  • The endpoint is available to application keys and in-scope dashboard users only. It is never reachable with a session’s capture credential.

Review

Most sessions complete without a human. A clean assessment passes automatically (automatic_pass) and the session emits idv.session.approved. Questionnaire-only sessions require human review by default; a workflow can opt into automatic approval of completed questionnaires with at least one answer on a step the applicant has not skipped, as described above. That outcome reflects self-reported answers, not verified identity. When the assessment will not auto-decide, the session lands on requires_review and waits for a reviewer in your Minerva workspace. Reviewers can escalate a session (escalation, which keeps it open) or make the terminal decision: accepted or rejected. You can also record decisions from the API:
Decisions against a finished session return 409 idv_review_terminal, and inadmissible transitions return 409 idv_review_invalid_transition. The outcome also flows to the profile: profile_status_updated fires with the new screening status, and when the profile has an onboarding run, profile_onboarding.completed fires with the outcome so your onboarding flow can finish. See Webhooks for the exact values.
A potential match is a candidate for analyst review. It is not a confirmed identity match, a legal conclusion, or an instruction to accept or reject a customer. Apply your organization’s policies and human-review requirements when determining the final disposition.

Worked example: email invite

An end-to-end walkthrough for one customer, Alex Morgan.
  1. Create the profile with the Profiles API:
Response (abridged):
  1. Create the IDV session for that profile:
Response (abridged):
  1. Send the invite email:
Response:
  1. Track progress with GET /sessions/{sessionId} or webhooks, and read the results with GET /sessions/{sessionId}/data when the assessment is done.
Use the same first two calls as the email example, then request the link back and hand it over immediately:
Response:
Redirect the browser to verify_url or open it in your app’s web view right away. The link is single-use and stops working within 15 minutes, so do not queue it, email it, or store it for later.

Web and mobile integration walkthrough

This sequence uses an email invite. For an embedded web experience, configure the workflow first and use a direct link in your iframe as described in Embed the hosted flow on your site. The common integration looks like this: Walking through it:
  1. The customer taps a button in your web or mobile app. The tap calls your backend, never Minerva directly.
  2. Your backend creates the profile (or reuses an existing one), creates the IDV session, and sends the email invite.
  3. The customer receives the email, opens the verification page, consents, completes the capture steps, and submits.
  4. Minerva assesses the session. Your backend receives IDV webhooks: idv.session.completed with the outcome (idv.session.approved, idv.session.requires_review, or idv.session.failed), and idv.document.captured for each uploaded artifact.
  5. Update the customer’s experience: show something like “verification received, we are finishing your setup.” Never surface flags, review states, or analyst details to the customer.
  6. If the session was held for review, an analyst reviews it in your Minerva workspace and marks the profile accepted or rejected. That disposition closes the loop with profile_onboarding.completed (and profile_status_updated), your signal to continue or stop the onboarding flow. Every onboarding delivery carries externalId (your reference), so you can close the loop against the same customer record you started. When the session runs inside a Minerva onboarding run, the delivery also carries the session’s stable sessionId under meta.idv; for per-session correlation, the IDV session events are the authoritative source.
Server-side start and invite, in Node.js:
A webhook receiver that validates the shared key and processes deliveries idempotently:
The idv kind sends every meta value as a string, so booleans arrive quoted ("true"). See Webhooks for the full event catalog, payload shapes, retry schedule, and dedupe guidance.

Errors and limits

Errors use one envelope: {"error": {"code": "...", "message": "..."}}, with Cache-Control: no-store. Common codes:
  • 400: returned as idv_profile_id_required or idv_profile_id_invalid when profile_id is missing or malformed on session create.
  • 400: returned as idv_profile_not_found when the profile does not exist in the calling workspace.
  • 400: returned as schema_validation_failed when the request body fails schema validation.
  • 401: returned as missing_authentication when the request carries no credentials, or as unauthorized when the key is rejected. Responses never reveal whether an object exists.
  • 403: returned as idv_direct_invite_forbidden when delivery: "none" is requested without an application principal.
  • 404: returned as idv_session_not_found when the session does not exist in the calling workspace.
  • 409: returned as idv_state_conflict when the session is not in a state that allows the action, for example canceling while the assessment runs, or a new invite uses a different Idempotency-Key while a send is still in flight.
  • 409: returned as idv_session_idempotency_conflict when an idempotency key was reused for a materially different create.
  • 409: returned as idv_invite_conflict when the invite state changed before the request completed; retry the request.
  • 409: returned as idv_review_terminal when a review decision was submitted for a session that is already accepted or rejected.
  • 409: returned as idv_review_invalid_transition when the review decision is not admissible from the session’s current review state.
  • 409: returned as idv_session_unavailable when the session cannot be changed right now. It applies to capture calls (acquire, consent, artifact reservation and upload, step answers, skip, document type, submit) and to cancel and review. No change was made; re-read the session before you retry the request.
  • 409: returned as idv_session_consent_required by capture calls (acquire, artifact reservation and upload, step answers, skip, document type, submit) when the session has no recorded consent. The consent call itself never returns it. There are two causes:
    • The customer has not recorded consent yet. Record consent, then retry the call.
    • The session has no privacy contact, because it was created from a preset workflow, from inline steps, or with no active default workflow to apply. Consent cannot be recorded for such a session, and the consent call returns 409 idv_state_conflict. Create a new session with a workflow_id whose workflow sets privacy_contact_email.
  • 422: returned as idv_profile_email_missing when an email invite was requested but the linked profile has no email address.
  • 502: returned as invite_delivery_failed or invite_delivery_retrying when the email provider could not confirm delivery. The invite stays valid; retry the invite call.
  • 503: returned as idv_profile_lookup_unavailable when the profiles service was unavailable and the request failed closed.
  • 503: returned as idv_direct_invite_unavailable when no secure public verify base is available for a direct link.
Limits to design around:
  • The capture token (session_token) lives 15 minutes by default.
  • Email invites live 72 hours by default; direct links at most 15 minutes.
  • The sessions list returns 50 records per page by default; the workflow and theme lists return 20. Every list endpoint caps at 100 (larger values are clamped).
  • Each workspace can keep up to 10 destinations by default. Enterprise customers can request more.

Security

  • Keep application API keys server-side. The hosted verification page authenticates the customer with its own capture or invite credential, so your client apps never need a key.
  • Validate x-webhook-key on every delivery before processing the body, and acknowledge quickly with a small 2xx response.
  • Read verification results only through the audited GET /sessions/{sessionId}/data endpoint, and store what you need under your own data-protection policy. Document images and OCR text are sensitive personal data.
  • Never surface review states, flags, or analyst details to the customer; the customer-facing flow deliberately does not expose them.
  • Use a separate application per environment, and rotate or deactivate keys when integrations change.
  • API Keys: create an application key and configure webhooks from the Developers page.
  • Webhooks: the delivery contract, payload shapes, and retry schedule.
  • Screening Integration Guide: interpret screening results alongside identity verification.
  • Profiles: the customer record an IDV session is tied to.