v1.0.4 API reference is live →

Age verification in one API call

Start a verification from your server, send the user to ProntoID, and receive a signed webhook when they're done. Add Login with ProntoID for returning users, and collect model release forms through the same platform.

HMAC-SHA256 signed webhooks OpenID Connect Built in Switzerland
POST /prod/verification-start
curl -X POST \
  https://7b6fsp0mpi.execute-api.us-east-1.amazonaws.com/prod/verification-start \
  -H "x-api-key: $PRONTO_API_KEY" \
  -H "x-platform-id: $PRONTO_PLATFORM_ID" \
  -H "Content-Type: application/json" \
  -d '{"client_reference": "user_12345"}'
200 OK application/json
{
  "verification_url": "https://secure.prontoid.com/verify?token=vtok_abc123...",
  "verification_token": "vtok_abc123...",
  "expires_at": "2024-11-07T16:30:00Z"
}
How it works

From request to verified, asynchronously

Your server never handles ID documents. ProntoID runs the check and tells you the outcome.

Start a session

Your backend calls verification-start with the user's client_reference.

Your server

Redirect the user

Send them to the returned verification_url before it expires.

Your frontend

User verifies

The user completes age verification on ProntoID's secure pages.

ProntoID

Receive the webhook

Check X-Pronto-Signature, then mark the user as verified.

Your server
Security by default

Trust the result, not the request

Every webhook is signed with your secret, so you can prove it came from ProntoID and wasn't changed on the way.

Signed webhooks

HMAC-SHA256 of the raw body with your whsec_ secret.

Short-lived tokens

Upload session tokens are single-use and expire after 10 minutes.

Server-side keys

API keys and client secrets are only ever sent server to server.

First-party sessions

The hosted upload page swaps your token for an HttpOnly cookie.

// Verify the X-Pronto-Signature header
$secret    = $_ENV['PRONTO_WEBHOOK_SECRET'];
$received  = $_SERVER['HTTP_X_PRONTO_SIGNATURE'] ?? '';
$payload   = file_get_contents('php://input');

$expected  = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $received)) {
    http_response_code(403);
    exit('Invalid signature.');
}

$event = json_decode($payload, true);
if ($event['type'] === 'age_verification.succeeded') {
    // look up $event['data']['object']['client_reference']
}
import hmac, hashlib, os

# Verify the X-Pronto-Signature header (Flask example)
secret   = os.environ["PRONTO_WEBHOOK_SECRET"]
received = request.headers.get("X-Pronto-Signature", "")
payload  = request.data

expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()

if not hmac.compare_digest(expected, received):
    return "Invalid signature.", 403

event = request.get_json()
if event["type"] == "age_verification.succeeded":
    # look up event["data"]["object"]["client_reference"]
    ...
100 req/minRate limit per API key, with a clean 429 above it.
10 minLifetime of a one-time upload session token.
3Code samples per step: PHP, Python and Java.
2Webhook events: age_verification.succeeded and release_form.completed.
FAQ

Developer questions

How do I authenticate with the ProntoID API?

It depends on the endpoint. The Age Verification API uses header authentication with x-api-key and x-platform-id. Platform utilities such as the secure upload flow use body authentication with platform_client_id and platform_api_key. The OIDC flow uses your Client ID and Client Secret. All credentials are in your ProntoID dashboard.

How do I know a verification has finished?

ProntoID sends an age_verification.succeeded event to the webhook URL configured in your dashboard. Verify the X-Pronto-Signature header against the raw request body before you trust the payload, then use client_reference to update the right user.

Can I test webhooks on my local machine?

Yes. Use a tunnelling service such as ngrok (ngrok http 3000) and set the generated HTTPS URL as your webhook endpoint in the dashboard.

Can I use ProntoID as a login provider?

Yes. The OIDC flow returns an ID token with a stable user identifier in sub. Request the age_verification scope to also receive the https://prontoid.com/age_verified claim.

What does the API cost?

Pricing depends on the service and volume. See pricing tiers on prontoid.com, or contact us for platform pricing.

Ship age verification this week

Grab your Platform ID and API key from the dashboard, then follow the step-by-step reference.