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.

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 capture steps, for example a liveness selfie and 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). 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. 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

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.
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.
  • 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.