AgeOnce Docs
API Reference

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
ParameterTypeDescription
client_idstringYour Client ID
redirect_uristringURL for redirect after verification
statestringCSRF protection
age_requiredstringOptional. Minimum age (e.g. 18, 21). Default: 18

Learn more →


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.

Learn more →


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"
}

Learn more →


GET /api/.well-known/jwks.json

JSON Web Key Set for local validation.

GET https://api.ageonce.com/api/.well-known/jwks.json

Response:

{
  "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.

Learn more →


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

CodeDescription
200Success
400Invalid parameters
401Unauthorized
403Access denied
404Not found
500Internal error

Error Response Format

All errors are returned in standard format:

{
  "error": "error_code",
  "error_description": "Human readable description"
}

Error codes

CodeDescription
invalid_requestMissing or invalid parameters
unsupported_grant_typegrant_type is not authorization_code
invalid_clientInvalid client_id or client_secret
invalid_redirect_uriredirect_uri is not in the allow list
invalid_grantInvalid authorization code
expired_codeAuthorization code has expired
code_already_usedAuthorization code was already exchanged
invalid_statestate does not match the code
age_requirement_not_metUser does not meet the requested age
client_suspendedClient is not active
payment_requiredVerification limit reached
server_errorInternal server error

On this page