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.
If you are still exploring the integration, start in Sandbox. Sandbox recipes do not create HVF sessions; they use synthetic fixtures so you can test Checkbox, OAuth, and Connect without credentials, billing, wallet debits, or enrollments.
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. Use test credentials first. Live credentials should be enabled only after production gates and wallet readiness are complete.
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