All Endpoints
Complete list of AgeOnce API endpoints
All API Endpoints
Complete list of available AgeOnce API endpoints.
Authentication and verification
GET /
Age verification page. Pass OAuth parameters as a query string on the app root. /verify is not a page and returns 404.
GET https://app.ageonce.com/?client_id=...&redirect_uri=...&state=...&age_required=18| Parameter | Type | Description |
|---|---|---|
client_id | string | Your Client ID |
redirect_uri | string | URL for redirect after verification |
state | string | CSRF protection |
age_required | string | Optional. Minimum age (e.g. 18, 21). Default: 18 |
POST /api/oauth/token
Exchange authorization code for age token. Use HTTP Basic Auth with client_id:client_secret (Base64).
POST https://api.ageonce.com/api/oauth/token
Authorization: Basic <base64(client_id:client_secret)>Request Body:
{
"grant_type": "authorization_code",
"code": "string",
"redirect_uri": "string",
"state": "string"
}Response:
{
"access_token": "string",
"token_type": "Bearer",
"expires_in": 600,
"transaction_id": "uuid"
}transaction_id — Audit ID for compliance; searchable in Dashboard Audit Logs.
GET /api/verify/token/:token
Validate an access token. An invalid or expired token returns HTTP 401.
GET https://api.ageonce.com/api/verify/token/{access_token}Response (200):
{
"success": true,
"valid": true,
"age_verified": true,
"age_over": 18,
"verification_level": "first_verification",
"expires_at": "2026-02-11T12:10:00.000Z",
"issued_at": "2026-02-11T12:00:00.000Z",
"session_id": "user-id",
"client_id": "ap_live_your_client_id",
"nonce": null,
"transaction_id": "550e8400-e29b-41d4-a716-446655440000"
}GET /api/.well-known/jwks.json
JSON Web Key Set for local validation.
GET https://api.ageonce.com/api/.well-known/jwks.jsonResponse:
{
"keys": [
{
"kty": "RSA",
"kid": "key_2025_01",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}Issued tokens do not set kid in the JWT header. Use this key and expect issuer https://ageonce.io.
Statistics
GET /api/oauth/usage
Verification counts for your client. Authenticate with the same HTTP Basic credentials as token exchange (client_id:client_secret). Optional query: period (day, month, or all), start_date, end_date.
GET https://api.ageonce.com/api/oauth/usage?period=month
Authorization: Basic <base64(client_id:client_secret)>Response:
{
"client_id": "ap_live_your_client_id",
"period": {
"start": "2026-02-01T00:00:00.000Z",
"end": "2026-02-28T23:59:59.000Z"
},
"usage": {
"total_verifications": 1250,
"age_only_count": 800,
"biometric_count": 400,
"reverification_count": 50
}
}HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Invalid parameters |
| 401 | Unauthorized |
| 403 | Access denied |
| 404 | Not found |
| 500 | Internal error |
Error Response Format
All errors are returned in standard format:
{
"error": "error_code",
"error_description": "Human readable description"
}Error codes
| Code | Description |
|---|---|
invalid_request | Missing or invalid parameters |
unsupported_grant_type | grant_type is not authorization_code |
invalid_client | Invalid client_id or client_secret |
invalid_redirect_uri | redirect_uri is not in the allow list |
invalid_grant | Invalid authorization code |
expired_code | Authorization code has expired |
code_already_used | Authorization code was already exchanged |
invalid_state | state does not match the code |
age_requirement_not_met | User does not meet the requested age |
client_suspended | Client is not active |
payment_required | Verification limit reached |
server_error | Internal server error |