npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@privateav/sdk

v3.4.13

Published

PrivateAV SDK - Lightweight redirect-based age verification

Downloads

153

Readme

PrivateAV SDK v3.4.11

A lightweight SDK for integrating PrivateAV age verification into your website or application.

Features

  • Ultra-lightweight: ~18KB minified
  • Simple integration: 5 lines of code to get started
  • Two modes: Same-tab redirect or new-tab popup
  • TypeScript support: Full type definitions included
  • Auto-environment detection: Works seamlessly across environments
  • Secure: HMAC-signed state parameters, automatic session management
  • Compliant: Enforces minimum age of 25

Changelog

3.4.11

  • Fixed CDN documentation URLs (files are at package root, not /dist/)

3.4.9

  • Prevents onCancel from firing after a successful new-tab verification when the popup closes.

Installation

npm install @privateav/sdk

Or load directly from jsDelivr CDN (no bundler required):

<script src="https://cdn.jsdelivr.net/npm/@privateav/sdk@latest/privateav.min.js"></script>

Quick Start

With npm/bundler

import { PrivateAV } from '@privateav/sdk';

const sp = new PrivateAV({
  apiKey: 'pk_...',  // Your public key from the dashboard
  returnUrl: window.location.origin + '/verified'
});

// Start verification - redirects user to PrivateAV
await sp.verify();

With CDN (no bundler)

<script src="https://cdn.jsdelivr.net/npm/@privateav/sdk@latest/privateav.min.js"></script>
<script>
  const sp = new PrivateAV({
    apiKey: 'pk_...',
    returnUrl: window.location.origin + '/verified'
  });

  document.getElementById('verify-btn').onclick = () => sp.verify();
</script>

That's it! The SDK handles session creation automatically.

Configuration

| Option | Type | Required | Description | |--------|------|----------|-------------| | apiKey | string | Yes | Your public API key (pk_...) | | returnUrl | string | Yes | URL to redirect after verification | | cancelUrl | string | No | URL to redirect to if user closes the verification window (new-tab mode) | | environment | string | No | 'production' or 'staging' (auto-detected) | | mode | string | No | 'redirect' (default) or 'new-tab' | | defaultChallengeAge | number | No | Default minimum age (25 or higher) | | defaultVerificationMode | string | No | 'L1' or 'L2' | | onComplete | function | No | Callback for new-tab mode | | onCancel | function | No | Called when user closes popup (new-tab mode). Return false to suppress automatic cancelUrl redirect. | | onError | function | No | Error handler |

Verification Options

Override settings per-verification:

await sp.verify({
  challengeAge: 30,           // Override minimum age for this session
  verificationMode: 'L2',     // Force ID verification for this session
  externalUserId: 'user-123', // Your user ID (returned in webhooks)
  skipIntro: true,            // Skip intro screen
  autoReturn: true            // Auto-redirect after success
});

Verification Modes

  • L1: Age estimation using computer vision (faster, less friction)
  • L2: Full ID document verification (more thorough)

Integration Modes

Same-Tab Redirect (Default)

User is redirected to PrivateAV, then back to your returnUrl:

const sp = new PrivateAV({
  apiKey: 'pk_...',
  returnUrl: '/age-verified'
});

await sp.verify();
// User is redirected to PrivateAV...
// After verification, user returns to /age-verified?sessionId=xxx&status=verified

New-Tab Mode

Verification opens in a popup window:

const sp = new PrivateAV({
  apiKey: 'pk_...',
  returnUrl: '/age-verified',
  cancelUrl: '/age-cancelled',
  mode: 'new-tab',
  onComplete: (result) => {
    console.log('Verification complete:', result.sessionId, result.status);
    // Validate on your server, then update UI
  },
  onCancel: () => {
    console.log('User closed the verification window');
    // Return false if you want to handle navigation manually
    // return false;
  },
  onError: (error) => {
    console.error('Verification error:', error.message);
  }
});

await sp.verify();

If cancelUrl is provided, the SDK will redirect the opener to cancelUrl with status=cancelled and sessionId when the user closes the verification window. Return false from onCancel to suppress the automatic redirect.

Server-Side Validation (Required!)

After verification completes, always validate the result on your server before granting access:

// Node.js / Express example
app.get('/age-verified', async (req, res) => {
  const { sessionId } = req.query;

  // Validate with your SECRET key (sk_...)
  const response = await fetch(
    `https://api.privateav.com/api/v1/sessions/${sessionId}`,
    {
      headers: {
        'Authorization': `Bearer ${process.env.PRIVATEAV_SECRET_KEY}`
      }
    }
  );

  const session = await response.json();

  if (session.status === 'VERIFIED') {
    // Grant access
    req.session.ageVerified = true;
    res.redirect('/content');
  } else {
    res.redirect('/age-verification-failed');
  }
});

Security Note: Never trust client-side verification status alone. Always validate server-side using your secret key.

Webhooks (Recommended)

For reliable verification tracking, configure webhooks in your dashboard:

// Webhook payload example
{
  "event": "verification.completed",
  "sessionId": "abc-123",
  "verified": true,
  "externalUserId": "your-user-id",  // If provided during verify()
  "timestamp": "2025-01-15T10:30:00Z"
}

Complete Example

HTML + CDN

<!DOCTYPE html>
<html>
<head>
  <title>Age Verification</title>
  <script src="https://cdn.jsdelivr.net/npm/@privateav/sdk@latest/privateav.min.js"></script>
</head>
<body>
  <button id="verify-btn">Verify Your Age</button>

  <script>
    const sp = new PrivateAV({
      apiKey: 'pk_...',
      returnUrl: window.location.origin + '/verified'
    });

    document.getElementById('verify-btn').onclick = () => sp.verify();
  </script>
</body>
</html>

React Component

import { useState } from 'react';
import { PrivateAV } from '@privateav/sdk';

function AgeGate() {
  const [verifying, setVerifying] = useState(false);

  const sp = new PrivateAV({
    apiKey: process.env.NEXT_PUBLIC_PRIVATEAV_KEY,
    returnUrl: window.location.origin + '/verified'
  });

  const handleVerify = async () => {
    setVerifying(true);
    try {
      await sp.verify();
    } catch (error) {
      console.error('Failed to start verification:', error);
      setVerifying(false);
    }
  };

  return (
    <button onClick={handleVerify} disabled={verifying}>
      {verifying ? 'Redirecting...' : 'Verify Your Age'}
    </button>
  );
}

TypeScript

Full TypeScript support included:

import { PrivateAV, PrivateAVConfig, VerificationResult } from '@privateav/sdk';

const config: PrivateAVConfig = {
  apiKey: process.env.NEXT_PUBLIC_PRIVATEAV_KEY!,
  returnUrl: '/verified',
  mode: 'new-tab',
  onComplete: (result: VerificationResult) => {
    console.log(`Session ${result.sessionId}: ${result.status}`);
  }
};

const sp = new PrivateAV(config);

Skip Parameters

For streamlined embedded flows:

// Skip intro screen (go directly to camera)
await sp.verify({ skipIntro: true });

// Auto-redirect after success (no success screen)
await sp.verify({ autoReturn: true });

// Both - minimal user interaction
await sp.verify({ skipIntro: true, autoReturn: true });

Error Handling

const sp = new PrivateAV({
  apiKey: 'pk_...',
  returnUrl: '/verified',
  onError: (error) => {
    if (error.message.includes('popup')) {
      alert('Please allow popups for age verification');
    } else if (error.message.includes('rate limit')) {
      alert('Too many attempts. Please wait a moment.');
    } else {
      console.error('Verification error:', error);
    }
  }
});

API Keys

PrivateAV uses two types of API keys:

| Key Type | Prefix | Use Case | |----------|--------|----------| | Public Key | pk_ | Client-side SDK (this package) | | Secret Key | sk_ | Server-side validation only |

Important: This SDK only works with public keys (pk_). For server-side integrations using secret keys, use the Direct API instead.

Browser Support

  • Chrome 60+
  • Firefox 60+
  • Safari 12+
  • Edge 79+
  • Mobile browsers (iOS Safari, Chrome for Android)

Security Best Practices

  1. Use public keys client-side - Never expose secret keys in browser code
  2. Validate server-side - Always verify results using your secret key
  3. Configure webhooks - For reliable, tamper-proof verification notifications
  4. Register callback URLs - Pre-register your returnUrl in the dashboard
  5. Use HTTPS - SDK enforces HTTPS in production

Cleanup

When done with the SDK (e.g., in SPA route changes):

sp.destroy();

Migration from v3.0.x

If you were using merchant-generated session IDs:

// Old (v3.0.x)
safePassage.verify({ sessionId: crypto.randomUUID() });

// New (v3.4+) - sessionId is auto-generated
await sp.verify();

The SDK now creates sessions automatically via the API when using public keys.

Support