Tokens & Authentication
Understanding JWT tokens, validation, and the token lifecycle.
What are LoomAPI tokens?
LoomAPI issues JWT (JSON Web Token) tokens for approved verifications. These tokens are time-limited (default 24 hours) and contain verification metadata without storing any PII or biometric data.
Tokens provide a tokenized verification approach instead of passing raw identity data. Each token represents a single verified user session and can be validated on-demand without exposing sensitive information.
Token Structure
LoomAPI JWT tokens are standard JSON Web Tokens that contain verification metadata without storing PII. They indicate age verification status—they are not identity documents and do not contain personal information.
Key claims in LoomAPI JWT tokens:
tenantId- The tenant that owns the verificationverificationId- The unique verification IDexp- Expiration timestamp (Unix epoch, default 24 hours)iat- Issued at timestamp (Unix epoch)
Tokens are signed with HS256 algorithm. The issuer and audience are configured on the backend (default issuer: project-halo, audience: age-verification).
Token Validation
The recommended way to validate tokens is via the POST /tokens/validate endpoint. This ensures the token is valid, not expired, and belongs to your tenant.
For server-side validation, you can also verify the JWT directly using a JWT library:
// Example only: Server-side JWT verification
// Note: The recommended approach is to use POST /tokens/validate endpoint
const jwt = require('jsonwebtoken');
// Verify the token
// Note: JWT_SECRET, issuer, and audience are configured on the LoomAPI backend
// Contact support for the correct values if validating tokens server-side
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
algorithms: ['HS256'],
issuer: 'project-halo', // Backend-configured issuer
audience: 'age-verification', // Backend-configured audience
});
// Check claims
if (decoded.tenantId !== expectedTenantId) {
throw new Error('Tenant mismatch');
}
// Token is valid
console.log('Verification ID:', decoded.verificationId);
console.log('Issued at:', new Date(decoded.iat * 1000));
console.log('Expires at:', new Date(decoded.exp * 1000));Token Lifecycle
- Verification starts - User initiates verification via
/verify/start - Verification completes - Evidence is submitted via
/verify/complete - Token issued - If approved, a JWT token is returned (expires in 24 hours by default)
- Token validation - On each request, validate the token via
/tokens/validate - Token expires - After expiration, the token is no longer valid and a new verification is required
Token Lifecycle Flow
Validation Response
The /tokens/validate endpoint returns:
valid- Boolean indicating if token is validover18- Boolean indicating if user is verified as over 18reason- Error reason if invalid (e.g., TOKEN_EXPIRED, TOKEN_NOT_FOUND, TENANT_MISMATCH)