AgeOnce Docs

Quickstart

Start integrating AgeOnce in 5 minutes

Quickstart

This guide will help you integrate AgeOnce into your project in minutes.

Prerequisites

Redirect URI is the URL on your server where the user will be redirected after verification.

Step 1: Get credentials

Sign up and log in to AgeOnce Dashboard

Complete checkout (choose a plan) — this creates your organization and OAuth credentials

After checkout you'll see Client ID and Client Secret once. Save them — the Client Secret will not be shown again

Go to Settings and add your Redirect URI (e.g. https://yoursite.com/callback)

Already have an account? Client ID is always visible in Settings. If you lost the Client Secret, use Regenerate Client Secret — the new secret will be shown once.

Step 2: Redirect user to verification

When a user needs to pass age verification, redirect them to AgeOnce:

https://app.ageonce.com/verify?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&state=RANDOM_STATE

Parameters

ParameterDescription
client_idYour Client ID from the dashboard
redirect_uriURL for redirect after verification
stateRandom string for CSRF protection

Step 3: Handle callback

After successful verification, the user will be redirected to your redirect_uri with the code parameter:

https://yoursite.com/callback?code=AUTHORIZATION_CODE&state=YOUR_STATE

Step 4: Exchange code for token

Make a POST request to /api/oauth/token:

curl -X POST https://app.ageonce.com/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "code": "AUTHORIZATION_CODE",
    "redirect_uri": "YOUR_REDIRECT_URI"
  }'
const response = await fetch('https://app.ageonce.com/api/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    client_id: process.env.AGEONCE_CLIENT_ID,
    client_secret: process.env.AGEONCE_CLIENT_SECRET,
    code: authorizationCode,
    redirect_uri: process.env.AGEONCE_REDIRECT_URI,
  }),
});

const { age_token, transaction_id } = await response.json();
import requests

response = requests.post('https://app.ageonce.com/api/oauth/token', json={
    'client_id': os.environ['AGEONCE_CLIENT_ID'],
    'client_secret': os.environ['AGEONCE_CLIENT_SECRET'],
    'code': authorization_code,
    'redirect_uri': os.environ['AGEONCE_REDIRECT_URI'],
})

data = response.json()
age_token = data['age_token']
transaction_id = data.get('transaction_id')  # Audit ID
$response = file_get_contents('https://app.ageonce.com/api/oauth/token', false, stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/json',
        'content' => json_encode([
            'client_id' => getenv('AGEONCE_CLIENT_ID'),
            'client_secret' => getenv('AGEONCE_CLIENT_SECRET'),
            'code' => $authorizationCode,
            'redirect_uri' => getenv('AGEONCE_REDIRECT_URI'),
        ]),
    ],
]));

$data = json_decode($response, true);
$ageToken = $data['age_token'];
$transactionId = $data['transaction_id'] ?? null;  // Audit ID

Response

{
  "age_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 600,
  "transaction_id": "550e8400-e29b-41d4-a716-446655440000"
}
FieldDescription
age_tokenJWT token with age verification claims
token_typeAlways "Bearer"
expires_inToken lifetime in seconds
transaction_idUnique ID for this verification (Audit ID). Use for compliance, receipts, and searching in Dashboard Audit Logs.

Step 5: Validate token

age_token is a JWT containing age information. You can:

  1. Validate via API — POST request to /api/oauth/validate
  2. Validate locally — using the public key from /api/oauth/jwks
{
  "sub": "anonymous",
  "age_verified": true,
  "min_age": 18,
  "age_over": 18,
  "verification_id": "550e8400-e29b-41d4-a716-446655440000",
  "verified_at": "2026-02-11T12:00:00Z",
  "client_id": "your_client_id",
  "iat": 1739275200,
  "exp": 1739361600,
  "iss": "ageonce"
}
ClaimDescription
verification_idTransaction ID — same as transaction_id from token exchange. Use for audit trail and compliance.

Done! You can now check age_verified to grant access to age-restricted content.

Next steps

On this page