# Session Lifecycle

A session is one verification attempt. Privy generates its `session_id` when
the merchant backend calls `POST /v1/sessions`.

The same `session_id` appears in:

- The create-session response.
- Each front-channel widget event.
- The exchange response and the server callback.
- The `session_id` claim of the verified-data JWT.

Use `session_id` to correlate front-channel activity with the backend result.
Also use it to deduplicate result processing.

> A `session_id` alone does not prove that verification succeeded. API version
> 1.0.0 has no endpoint that gets the session status by `session_id`.
> `POST /v1/sessions/exchange` cannot poll the status. It accepts only a
> single-use `exchange_code` that Privy issues after successful verification.
> The only authoritative evidence of success is the Privy-signed JWT after the
> merchant backend verifies it.

## Create-session timeout

If the create-session request times out, the merchant backend does not receive
`session_url`, and the widget cannot load. Create a new session. The retry can
return a new `session_id`. The previous unused session expires automatically
and is not charged.

## Verification in progress

Keep the active `session_id`, `session_url`, and `expires_at` on the merchant
backend while verification is in progress. Use the returned `expires_at`. A
fixed session duration is not guaranteed.

The user can interrupt the flow, for example by closing the application. If the
same `session_url` is available and has not expired, you can load it again.
Exact resumption at the same widget step is not guaranteed.

If `session_url` is not available or the session expired, create a new session.
The user starts the flow again.

> Treat `session_url` as sensitive. It gives access to the verification widget
> for that session. Do not log or expose the full URL.
