Create AgeKey PAR Endpoint
The Create AgeKey PAR (Pushed Authorization Request) endpoint allows you to securely submit age verification data ahead of navigating the user to the AgeKey creation flow. This server-to-server endpoint stores the verification result and returns a short-lived request_uri that's used in the subsequent authorization flow.
This endpoint implements the OAuth 2.0 Pushed Authorization Requests (PAR) specification for secure parameter transmission.
PAR endpoint
- cURL
- JavaScript
- Python
curl -X POST "https://api.agekey.org/v1/oidc/create/par" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret" \
-d "scope=openid" \
-d "response_type=none" \
-d "type=age_verification" \
-d "redirect_uri=https://yourapp.com/agekey/create-callback" \
-d "state=abc123xyz789" \
-d "authorization_details=%5B%7B%22type%22%3A%22age_verification%22%2C%22age%22%3A%7B%22date_of_birth%22%3A%222000-01-02%22%7D%2C%22method%22%3A%22id_doc_scan%22%2C%22verification_id%22%3A%22b861f598-f58a-49e9-b98a-a2ee5bdfb4bb%22%2C%22verified_at%22%3A%222025-10-07T12%3A34%3A56Z%22%2C%22attributes%22%3A%7B%22face_match_performed%22%3Atrue%2C%22issuing_country%22%3A%22US%22%7D%2C%22provenance%22%3A%22%2Fveratad%2Froc%22%7D%5D"
const axios = require('axios');
const qs = require('querystring');
const formData = {
client_id: 'your-client-id',
client_secret: 'your-client-secret',
scope: 'openid',
response_type: 'none',
type: 'age_verification',
redirect_uri: 'https://yourapp.com/agekey/create-callback',
state: 'abc123xyz789',
authorization_details: JSON.stringify([{
type: 'age_verification',
age: { date_of_birth: '2000-01-02' },
method: 'id_doc_scan',
verification_id: 'b861f598-f58a-49e9-b98a-a2ee5bdfb4bb',
verified_at: '2025-10-07T12:34:56Z',
attributes: {
face_match_performed: true,
issuing_country: 'US'
},
provenance: '/veratad/roc'
}])
};
const response = await axios.post(
'https://api.agekey.org/v1/oidc/create/par',
qs.stringify(formData),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
import requests
import json
form_data = {
'client_id': 'your-client-id',
'client_secret': 'your-client-secret',
'scope': 'openid',
'response_type': 'none',
'type': 'age_verification',
'redirect_uri': 'https://yourapp.com/agekey/create-callback',
'state': 'abc123xyz789',
'authorization_details': json.dumps([{
'type': 'age_verification',
'age': {'date_of_birth': '2000-01-02'},
'method': 'id_doc_scan',
'verification_id': 'b861f598-f58a-49e9-b98a-a2ee5bdfb4bb',
'verified_at': '2025-10-07T12:34:56Z',
'attributes': {
'face_match_performed': True,
'issuing_country': 'US'
},
'provenance': '/veratad/roc'
}])
}
response = requests.post(
'https://api.agekey.org/v1/oidc/create/par',
data=form_data,
headers={'Content-Type': 'application/x-www-form-urlencoded'}
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | Your AgeKey client ID |
client_secret | string | Yes | Your AgeKey client secret |
scope | string | Yes | Always set to openid |
response_type | string | Yes | Always set to none |
type | string | Yes | Always set to age_verification |
redirect_uri | string | Yes | Where users return after AgeKey creation |
state | string | Yes | Client-generated value for CSRF protection and maintaining application state |
authorization_details | string | Yes | URL-encoded JSON array of verification data |
Authorization details format
The authorization_details parameter must be a URL-encoded JSON array containing age signal information:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always age_verification |
age | object | Yes | Age information object |
age.date_of_birth | string | No* | Date of birth in ISO 8601 format (YYYY-MM-DD) |
age.at_least_years | number | No* | Minimum age threshold verified |
age.years | number | No* | Exact age in years |
method | string | Yes | Verification method used (see supported methods below) |
verification_id | string | Yes | A unique ID for revoking or auditing the verification. The ID is chosen by you, the contributor, not by the AgeKey service. Up to 100 characters. Alphanumeric plus _+/=.-. UUID v7 format is recommended. |
verified_at | string | Yes | Verification completion time (date or date-time in ISO 8601) |
attributes | object | No | Method-specific verification attributes |
provenance | string | No | Verification source path (for example /veratad/roc, /in_house/fae) |
*Either date_of_birth, at_least_years, or years is required depending on the verification method.
Example:
[
{
"type": "age_verification",
"age": {
"date_of_birth": "2000-01-02"
},
"method": "id_doc_scan",
"verification_id": "b861f598-f58a-49e9-b98a-a2ee5bdfb4bb",
"verified_at": "2025-10-07T12:34:56Z",
"attributes": {
"face_match_performed": true,
"issuing_country": "US"
},
"provenance": "/veratad/roc"
}
]
Supported verification methods
| Method | Age Format | Required Attributes* | Optional Attributes* |
|---|---|---|---|
email_age_estimation | at_least_years | None | None |
facial_age_estimation | at_least_years | None | on_device (boolean) |
national_id_number | date_of_birth preferred | issuing_country (ISO 3166-1 alpha-2) | None |
digital_credential | date_of_birth preferred | platform (singpass, connect_id, privy, digilocker, korean_real_name), issuing_country (ISO 3166-1 alpha-2) | None |
id_doc_scan | date_of_birth preferred | None | face_match_performed (boolean), issuing_country (ISO 3166-1 alpha-2) |
payment_card_network | at_least_years: 18 | card_type (credit, debit, unknown) | None |
*Attributes parsing is strict, if the attributes given for a particular method aren't required or optional then the request fails.
Response
On success, returns a request_uri that expires in 90 seconds:
{
"request_uri": "urn:agekey:request:AjcP1Yt7Np0",
"expires_in": 90
}
Important: The request_uri expires in 90 seconds. Users must complete AgeKey creation within this window.