# How it works

> One session per applicant — created by your backend, completed in the hosted flow, decided by rules or a reviewer.

Source: https://docs.okyc.stream/get-started/how-it-works

```text
Your backend ──POST /v1/sessions (sk_…)──▶ OKYC API ──▶ { id, url, client_token, status, expires_at }
     │
     └── sends url (or client_token) to your frontend / app
Your frontend ──@okyc/web · @okyc/react · mobile SDK──▶ hosted flow ──events (UX only)──▶ your UI
OKYC ──webhook session.approved / declined / review…──▶ your backend ──GET /v1/sessions/:id──▶ details
```

## 1. Design a workflow

A [workflow](https://docs.okyc.stream/concepts/workflows.md) lists the steps an applicant completes (consent, phone OTP, PAN, Aadhaar,
selfie, bank account, documents…) and the [rules](https://docs.okyc.stream/concepts/rules.md) that turn check results into a decision.
Build it in the dashboard under **Workflows** and publish it. Each published version is immutable; running
sessions keep the version they started with.

## 2. Create a session (backend)

Your backend calls [`POST /v1/sessions`](https://docs.okyc.stream/backend/sessions.md) with a secret key, the `workflow_id` and your own
`reference_id` for the user. The response has a `url` for the hosted flow and a `client_token` (`st_…`), both
scoped to that one session.

## 3. The applicant completes the flow

Open the `url` with an SDK: [web](https://docs.okyc.stream/web/web-sdk.md) (modal, inline, popup or redirect), [React](https://docs.okyc.stream/web/react.md) or
[mobile](https://docs.okyc.stream/mobile.md). The token travels in the URL fragment (`#t=…`), so it never reaches servers or logs. The
flow reports progress events (`ready`, `step_started`, `step_completed`, `complete`, `exit`, `error`) that you
can use for your UI.

## 4. OKYC decides

When all steps are submitted the session moves to `processing`, checks run, and the workflow rules decide:
`approved`, `declined` or `review` (a person in your team decides in the dashboard). See
[statuses](https://docs.okyc.stream/concepts/statuses.md).

## 5. Your backend acts on the webhook

OKYC sends a signed [webhook](https://docs.okyc.stream/backend/webhooks.md) (`session.approved`, `session.declined`, `session.review`…).
Verify the signature, dedupe on the event `id`, then fetch the session for details. This is the only result
you should trust.
