Verification Sessions
Query HVF session status and understand the session lifecycle.
Overview
A verification session is created when you redirect a user to CAIRL's hosted verification flow (HVF). Sessions have a 30-minute TTL and are identified by the session_id parameter returned in the callback URL.
Session lifecycle
pending → authenticated → verified → complete
↘ failed
↘ expired| Status | Meaning |
|---|---|
pending | Session started, user has not yet authenticated |
authenticated | User has logged in to CAIRL |
verified | User completed identity verification |
complete | Authorization code has been issued — session is done |
failed | Verification could not be completed |
expired | 30-minute TTL elapsed before completion |
Query a session
After your callback URL receives the authorization code, you can confirm session status with your API key:
GET /api/verify/hvf-session/{session_id}
Authorization: Bearer YOUR_API_KEYResponse:
{
"success": true,
"session": {
"sessionId": "hvf_abc123...",
"status": "complete",
"scopes": ["age_18_plus", "identity_verified"],
"isTestMode": false,
"createdAt": "2026-03-24T10:00:00.000Z",
"expiresAt": "2026-03-24T10:30:00.000Z"
}
}Error responses:
| HTTP | Condition |
|---|---|
401 | Missing or invalid API key |
403 | API key does not own this session |
404 | Session not found or expired |
Starting a session
Sessions are initiated by redirecting the user:
GET https://cairl.app/verify/start
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=age_18_plus
&state=RANDOM_CSRF_TOKEN
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256See the Quickstart for the full PKCE flow.
Handling session outcomes
Your redirect_uri receives one of two outcomes:
Success:
https://yourapp.com/callback?code=AUTH_CODE&state=YOUR_STATEFailure:
https://yourapp.com/callback?error=ERROR_CODE&state=YOUR_STATEerror value | Meaning |
|---|---|
access_denied | User declined the consent screen |
verification_failed | User abandoned verification or it could not complete |
session_expired | 30-minute TTL elapsed |
Always validate state before processing code. If the state does not match what you stored, reject the request.
Webhook notifications
Rather than polling session status, configure a webhook endpoint to receive real-time notifications:
verification.session.completed— session reachedcompletestatusverification.session.failed— session ended in failureverification.session.expired— session expired (coming soon — not yet delivered)
See the Webhooks reference for setup and payload details.
Session security
- Sessions are single-use: once
complete, the session cannot be reused - Sessions belong to exactly one API key — cross-key access returns
403 - Session IDs are not guessable (cryptographically random)
- Your
redirect_urimust exactly match your registered callback URL - Live keys require HTTPS redirect URIs; test keys allow
http://localhost