Developers
Integration Guide
Add privacy-preserving age verification to your application.
Zero Knowledge
Verify age (18+) without ever receiving personal user data or birthdates.
Server Verified
Cryptographically signed JWTs ensure proofs cannot be forged or re-used.
Simple API
One endpoint to verify tokens generated by the user's client.
Become a Partner
To integrate Proof of Age, you need a unique Partner ID. This ensures your verification actions are isolated and secure.
Verification API
When a user completes verification in the Proof of Age app, they receive a uniquetoken. Your application can send this token to our API to validate their age status.
/api/proofs/verifyRequest Body
{
"token": "eyJhbGciOiJIUzI1Ni...",
"partner": "acme-ltd" // optional — enforces partner match
}If partner is provided and it doesn't match the token's embedded partner, the API returns a 403 error.
Response
{
"valid": true,
"data": {
"age_range": "18+",
"timestamp": "2026-02-10T12:00:00.000Z",
"issuer": "World ID Proof of Age",
"valid": true,
"nullifier_hash": "0x0a37cbb6...",
"partner": "acme-ltd",
"expires": "2026-02-10T13:00:00.000Z"
}
}Sybil Resistance
Each proof token includes a nullifier_hash that is unique per user per partner. This means:
- A single user cannot generate multiple valid proofs for the same partner.
- The same
nullifier_hashalways maps to the same real human for your app. - Proofs cannot be shared — the nullifier is bound to the original verifier.
Example Implementation
async function verifyUserAge(token: string) {
const response = await fetch('https://proof-of-age.app/api/proofs/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token }),
});
const result = await response.json();
if (result.valid && result.data.age_range === '18+') {
// Store result.data.nullifier_hash to identify
// returning users without knowing their identity
return {
verified: true,
userId: result.data.nullifier_hash,
partner: result.data.partner,
};
}
return { verified: false };
}