Dashboard

Authentication Guide

Last Updated: November 30, 2025

Learn how to authenticate with VerifyHuman API using unified API keys with product scopes.


๐Ÿ“‹ Table of Contents


๐Ÿ”‘ Unified API Keys

VerifyHuman uses a unified API key system with product scopes. A single API key can access multiple verification products based on the scopes you enable when creating it.

Key Format

All API keys use the unified vhk- prefix:

Type Format Example
API Key vhk-{32chars} vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
API Secret vhsk-{48chars} vhsk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4

Key Components


๐ŸŽฏ Product Scopes

When creating an API key, you select which products the key can access:

Scope Product Purpose Plan Required
verifyhuman VerifyHuman Liveness & bot detection All plans
verifyage VerifyAge Age verification All plans
verifyidentity VerifyIdentity KYC with ID verification All plans
verifycompliance VerifyCompliance KYC+ with AML/sanctions Pro & Enterprise only

A single key can have multiple scopes. For example, one key with verifyhuman + verifyage scopes can be used for both products.


๐Ÿ” Getting Your API Keys

Step-by-Step

  1. Log in to your Dashboard
  2. Navigate to API Keys in the sidebar
  3. Click "Create New API Key"
  4. Name your key (e.g., "Production", "Staging")
  5. Select scopes - choose which products this key can access:
    • VerifyHuman (Liveness & bot detection)
    • VerifyAge (Age verification)
    • VerifyIdentity (KYC)
    • VerifyCompliance (KYC+) - Pro/Enterprise plans only
  6. Click "Generate API Key"
  7. Copy both your API Key and API Secret - they're shown only once!
  8. Store securely in your environment variables

Managing Multiple Keys

Create separate keys for different environments:

Environment Purpose Key Naming Example
Development Local testing "Development - VerifyHuman"
Staging Pre-production testing "Staging - VerifyHuman"
Production Live application "Production - VerifyHuman"

๐Ÿ“ก Authentication Methods

Use the X-API-Key header for all API requests. The same unified key works for all products based on its scopes:

// All endpoints use the same unified API key format
const API_KEY = 'vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6';

// VerifyHuman endpoint (requires 'verifyhuman' scope)
const response = await fetch('https://app.verifyhuman.io/api/verify', {
    method: 'POST',
    headers: {
        'X-API-Key': API_KEY
    },
    body: formData
});

// VerifyAge endpoint (requires 'verifyage' scope)
const response = await fetch('https://app.verifyhuman.io/api/v1/verify-age/verify', {
    method: 'POST',
    headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});

// VerifyIdentity endpoint (requires 'verifyidentity' scope)
const response = await fetch('https://app.verifyhuman.io/api/identity/v1/submit', {
    method: 'POST',
    headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});

// VerifyCompliance endpoint (requires 'verifycompliance' scope, Pro/Enterprise only)
const response = await fetch('https://app.verifyhuman.io/api/kyc/v1/submit_plus', {
    method: 'POST',
    headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});

Method 2: Form Data Authentication

For VerifyHuman specifically, you can include the key in form data:

const formData = new FormData();
formData.append('clientKey', 'vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6');
formData.append('file', imageFile);

const response = await fetch('https://app.verifyhuman.io/api/verify', {
    method: 'POST',
    body: formData
});

Method 3: Widget Initialization

For embeddable widgets, pass the key during initialization:

<script src="https://app.verifyhuman.io/widget.js"></script>
<script>
VerifyHuman.init({
    apiKey: 'vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6',
    onSuccess: function(result) {
        console.log('Verified!', result);
    },
    onFailure: function(error) {
        console.error('Failed:', error);
    }
});
</script>

๐Ÿ“‹ Plan-Based Product Access

API keys are scoped to specific products based on your subscription plan:

Plan Access Matrix

Plan VerifyHuman VerifyAge VerifyIdentity VerifyCompliance
Free โœ… โœ… โœ… โŒ
Starter โœ… โœ… โœ… โŒ
Growth โœ… โœ… โœ… โŒ
Pro โœ… โœ… โœ… โœ…
Enterprise โœ… โœ… โœ… โœ…

Plan Restriction Errors

Attempting to use a product not available in your plan returns:

{
  "error": "VerifyCompliance requires Pro or Enterprise plan",
  "status": "ERROR",
  "upgrade_url": "https://app.verifyhuman.io/dashboard/billing"
}

Wrong Key Scope Errors

Using the wrong key type for an endpoint returns:

{
  "error": "Invalid API key or wrong product scope",
  "status": "ERROR",
  "hint": "This endpoint requires a unified API key with verifyage scope (vhk-...)"
}

๐Ÿ›ก๏ธ Security Best Practices

โœ… DO:

  1. Store keys in environment variables

    # .env file (never commit to Git)
    VERIFYHUMAN_KEY=vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...
    VERIFYAGE_KEY=vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...
    VERIFYIDENTITY_KEY=vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...
    VERIFYCOMPLIANCE_KEY=vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...
    
  2. Use separate keys for each environment

    • Development key for local testing
    • Staging key for pre-production
    • Production key for live apps
  3. Rotate keys periodically

    • Generate new keys every 90 days
    • Update environment variables
    • Delete old keys after transition
  4. Validate verification results server-side

    // Don't trust client-side verification alone
    async function validateVerification(verificationId) {
        const response = await fetch(
            `https://app.verifyhuman.io/api/status/${verificationId}`,
            { headers: { 'X-API-Key': process.env.VERIFYHUMAN_KEY } }
        );
        return await response.json();
    }
    

โŒ DON'T:

  1. Never hardcode keys in source code

    // โŒ BAD - Don't do this!
    const API_KEY = 'vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...';
    
  2. Never commit keys to Git

    # Add to .gitignore
    .env
    .env.local
    .env.production
    
  3. Never expose keys in client-side error messages

  4. Never share keys in support tickets, forums, or screenshots


โš™๏ธ Environment Configuration

Node.js / JavaScript

// config.js
module.exports = {
    verifyHuman: process.env.VERIFYHUMAN_KEY,
    verifyAge: process.env.VERIFYAGE_KEY,
    verifyIdentity: process.env.VERIFYIDENTITY_KEY,
    verifyCompliance: process.env.VERIFYCOMPLIANCE_KEY,
    apiUrl: 'https://app.verifyhuman.io'
};

Python

# config.py
import os

VERIFYHUMAN_CONFIG = {
    'verify_human_key': os.environ.get('VERIFYHUMAN_KEY'),
    'verify_age_key': os.environ.get('VERIFYAGE_KEY'),
    'verify_identity_key': os.environ.get('VERIFYIDENTITY_KEY'),
    'verify_compliance_key': os.environ.get('VERIFYCOMPLIANCE_KEY'),
    'api_url': 'https://app.verifyhuman.io'
}

React / Next.js

// .env.local (not committed to Git)
NEXT_PUBLIC_VERIFYHUMAN_KEY=vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

// In your component
const apiKey = process.env.NEXT_PUBLIC_VERIFYHUMAN_KEY;

PHP

// config.php
<?php
$verifyhuman_config = [
    'verify_human_key' => getenv('VERIFYHUMAN_KEY'),
    'verify_age_key' => getenv('VERIFYAGE_KEY'),
    'verify_identity_key' => getenv('VERIFYIDENTITY_KEY'),
    'api_url' => 'https://app.verifyhuman.io'
];

๐Ÿ”„ Key Rotation

Rotation Process

  1. Generate new key in your dashboard
  2. Add new key to environment variables alongside old key
  3. Deploy changes to all environments
  4. Monitor for errors for 24-48 hours
  5. Remove old key from environment
  6. Delete old key in dashboard

Zero-Downtime Rotation

// Support both keys during transition
const PRIMARY_KEY = process.env.VERIFYHUMAN_KEY_NEW;
const FALLBACK_KEY = process.env.VERIFYHUMAN_KEY_OLD;

async function verifyWithFallback(formData) {
    try {
        return await callApi(formData, PRIMARY_KEY);
    } catch (error) {
        if (error.status === 401) {
            console.warn('Primary key failed, trying fallback');
            return await callApi(formData, FALLBACK_KEY);
        }
        throw error;
    }
}

๐Ÿ“Š Rate Limiting

Limits by Plan

Plan Requests/Minute Monthly Credits
Free 10 50 trial credits
Starter 60 1,000 credits
Growth 300 5,000 credits
Pro 600 20,000 credits
Enterprise 1,000+ Custom

Rate Limit Response (429)

{
  "error": "Rate limit exceeded",
  "status": "ERROR",
  "retry_after": 60,
  "limit": "60 requests/minute"
}

Rate Limit Headers

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1700000000

Handling Rate Limits

async function verifyWithRetry(formData, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        const response = await fetch('https://app.verifyhuman.io/api/verify', {
            method: 'POST',
            headers: { 'X-API-Key': process.env.VERIFYHUMAN_KEY },
            body: formData
        });

        if (response.status === 429) {
            const retryAfter = response.headers.get('Retry-After') || 60;
            console.log(`Rate limited. Retrying in ${retryAfter}s...`);
            await new Promise(r => setTimeout(r, retryAfter * 1000));
            continue;
        }

        return await response.json();
    }

    throw new Error('Max retries exceeded');
}

๐Ÿงช Testing Authentication

Demo Keys (No Credits Consumed)

Use demo keys for development testing:

vhk-demo_test123456789abcdefghijklm    # Demo key for all products

All products use the unified key format with product-specific scopes.

Demo mode:

Test Your Key

# Test VerifyHuman key
curl -X POST https://app.verifyhuman.io/api/verify \
  -H "X-API-Key: vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \
  -F "file=@test_selfie.jpg"

# Test VerifyAge key
curl -X POST https://app.verifyhuman.io/api/v1/verify-age/init \
  -H "X-API-Key: vhk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \
  -H "Content-Type: application/json" \
  -d '{"use_case": "alcohol", "min_age": 21}'

โ“ Troubleshooting

Common Errors

Error Cause Solution
"Invalid API key" Key is incorrect or inactive Check key in dashboard, ensure correct format
"Wrong product scope" Using wrong key type for endpoint Use correct key prefix for the endpoint
"Product not available in plan" Plan doesn't include product Upgrade plan or use available products
"Rate limit exceeded" Too many requests Implement exponential backoff
"Account not verified" Email not verified Check email for verification link

Debugging Checklist

  1. โœ… Correct key prefix for the endpoint?
  2. โœ… Key is active in dashboard?
  3. โœ… No extra spaces or line breaks?
  4. โœ… Using correct header format (X-API-Key)?
  5. โœ… Plan includes the product you're trying to use?

๐Ÿ“š Next Steps


๐Ÿ“ž Support

Need help with authentication?