Skip to Content
VerifySession lifecycle

Session lifecycle

A verification session is one person’s single run through a workflow’s checks on Valyd’s verification page. It moves through a small state machine that always ends in a terminal decision. This page is the lifecycle over time; the exact status values and how to act on each live in Decisions & statuses, and the end-to-end integration is in Run a verification.

The states over time

  1. Created (NOT_STARTED). Your backend calls verify.sessions.create with a workflowId. The response carries the verification page url, a sessionToken, and expiresAt. Tag it with vendorData (your internal user ref, echoed back on the webhook) and bound its lifetime with ttlSeconds.
  2. In progress (IN_PROGRESS → optionally IN_REVIEW). The user opens the url and completes the workflow’s checks. A session that needs manual or async review passes through IN_REVIEW first; otherwise it goes straight to a terminal state.
  3. Terminal decision (APPROVED · DECLINED · ABANDONED · EXPIRED). The lifecycle ends. Terminal is terminal: an abandoned or expired session is never resumed — create a new one.

Two signals, one authority

When the user finishes, Valyd sends two things — treat only one as authoritative:

  • The redirect ?status= is a hint. The user’s browser returns to your redirect_url with ?session_id=…&status=…. Never grant access on that query param — it is a UI hint only.
  • The decision call is authoritative. Read the real outcome from verify.sessions.decision(id), which carries the session status plus the per-check breakdown. See Run a verification, step 4.
  • A signed webhook fires on the terminal state. Valyd POSTs to your callback with the event and decision. The webhook is a notification — still call the decision API for the full per-check detail. See Webhooks.

What to do at each stage

IF status is NOT_STARTED or IN_PROGRESS: → wait; the run is not finished. Keep the session pending. IF status is IN_REVIEW: → wait for the review outcome; do not grant access yet. IF status is APPROVED: → fetch the decision, then grant access / complete onboarding. IF status is DECLINED: → fetch the decision to see which checks failed; deny and offer a retry if your policy allows. IF status is ABANDONED or EXPIRED: → treat as not verified; create a new session if the user still needs to verify.
Last updated on