VerifyHuman FAQ
Frequently asked questions about VerifyHuman verification, pricing, integrations, and troubleshooting.
💰 Pricing & Plans
How much does each verification cost?
Pricing varies by plan:
- Free Plan: 20 verifications/month - $0 ($0.00 per verification)
- Starter Plan: 1,000 verifications/month - $29 ($0.029 per verification)
- Growth Plan: 10,000 verifications/month - $99 ($0.0099 per verification)
- Enterprise Plan: Unlimited verifications - Custom pricing
Volume discounts: Enterprise customers can negotiate bulk pricing for high-volume usage (50,000+ verifications/month).
How do I upgrade my plan?
- Log into Dashboard: Go to app.verifyhuman.io/dashboard
- Click "Upgrade Plan": In the usage statistics section
- Select New Plan: Choose Starter, Growth, or Enterprise
- Complete Payment: Secure checkout via Stripe
- Instant Activation: New limits take effect immediately
Prorated billing: You only pay for the remaining time in your billing cycle when upgrading.
What happens if I exceed my monthly quota?
Hard limits apply:
- API requests return
HTTP 402 Payment Required - Error message:
"No verification credits remaining" - Your existing integrations will gracefully handle the error
- Verified users retain their status
Options when quota exceeded:
- Upgrade plan for immediate access
- Wait for next billing cycle (limits reset monthly)
- Contact support for emergency quota increase
Can I downgrade my plan?
Yes, with conditions:
- Downgrades take effect at the end of your current billing cycle
- You keep your current quota until the cycle ends
- No refunds for unused verifications
- Cannot downgrade below current month's usage
Example: If you used 2,000 verifications this month, you cannot downgrade to Starter (1,000 limit) until next cycle.
🔧 Technical Questions
How does the throttling system work?
Throttling protects against abuse:
Rules:
- 5 failed verifications within 5 minutes = throttled
- Throttling duration: 5 minutes from last failure
- Scope: Per IP address + user account + API key
- Reset trigger: Successful verification immediately resets the counter
Response when throttled:
{
"status": "throttled",
"message": "Too many verification attempts. Please try again in 5 minutes."
}
Common triggers:
- Poor quality images with multiple failures
- Automated scripts testing the API
- Users retrying quickly after failures
- Network issues causing repeated requests
What happens if verification fails?
Failure scenarios and responses:
No face detected:
{ "verification_id": "ver_abc123", "status": "FAIL", "confidence": 0, "error": "No face detected" }Multiple faces detected:
{ "verification_id": "ver_def456", "status": "FAIL", "confidence": 85.2, "error": "Multiple faces detected" }Low confidence score:
{ "verification_id": "ver_ghi789", "status": "FAIL", "confidence": 65.3, "error": "Low confidence score: 65.3%" }
Credit consumption: Failed verifications still consume credits as they require AI processing.
User guidance for failures:
- Use better lighting and camera quality
- Ensure only one face is visible
- Remove glasses, masks, or obstructions
- Face the camera directly
- Avoid motion blur
Can VerifyHuman integrate with React Native or Flutter apps?
Yes, via REST API integration:
React Native Example:
import DocumentPicker from 'react-native-document-picker';
const verifyUser = async () => {
// Pick image file
const file = await DocumentPicker.pickSingle({
type: DocumentPicker.types.images,
});
// Create form data
const formData = new FormData();
formData.append('clientKey', 'pk_live_your_key');
formData.append('file', {
uri: file.uri,
type: file.type,
name: file.name,
});
// Submit to VerifyHuman API
const response = await fetch('https://app.verifyhuman.io/api/verify', {
method: 'POST',
body: formData,
});
const result = await response.json();
if (result.status === 'PASS') {
// User verified successfully
await AsyncStorage.setItem('verificationToken', result.token);
navigation.navigate('Dashboard');
} else {
// Handle verification failure
Alert.alert('Verification failed', result.error);
}
};
Flutter Example:
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
Future<Map<String, dynamic>> verifyUser() async {
// Pick image
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.camera);
if (image == null) return {'error': 'No image selected'};
// Create multipart request
var request = http.MultipartRequest(
'POST',
Uri.parse('https://app.verifyhuman.io/api/verify')
);
request.fields['clientKey'] = 'pk_live_your_key';
request.files.add(
await http.MultipartFile.fromPath('file', image.path)
);
// Send request
var response = await request.send();
var responseData = await response.stream.toBytes();
var result = json.decode(String.fromCharCodes(responseData));
return result;
}
Platform support: VerifyHuman works with any platform that can make HTTP requests and handle file uploads.
🔌 Integration Questions
How do I test VerifyHuman without using credits?
Use Demo Mode:
- Demo API Key: Use
pk_demo_test123as your client key - Realistic Testing: Upload real images for authentic testing experience
- Always Success: Demo mode always returns successful verification
- Valid Tokens: Generates real JWT tokens for integration testing
- No Credit Usage: Demo requests don't consume your quota
Demo Response Example:
{
"verification_id": "demo_1642186830_4567",
"status": "PASS",
"confidence": 94.2,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
Can I customize the verification badge appearance?
Yes, with CSS customization:
Default badge:
<span class="vh-badge">✔ Human Verified</span>
Custom styling:
.vh-badge {
background: #your-brand-color;
color: white;
font-size: 12px;
font-weight: bold;
padding: 4px 12px;
border-radius: 20px;
margin-left: 8px;
display: inline-block;
}
/* Different styles for different contexts */
.vh-badge.comment-badge {
font-size: 10px;
padding: 2px 8px;
}
.vh-badge.profile-badge {
font-size: 14px;
padding: 6px 16px;
}
WordPress theme integration:
// Add to your theme's functions.php
function custom_verifyhuman_badge_style() {
wp_add_inline_style('verifyhuman-badges', '
.vh-badge {
background: ' . get_theme_mod('primary_color', '#22c55e') . ';
border-radius: ' . get_theme_mod('button_radius', '6px') . ';
}
');
}
add_action('wp_enqueue_scripts', 'custom_verifyhuman_badge_style');
What happens during planned maintenance?
Maintenance procedures:
- Advance notice: 24-48 hours via email and status page
- Status page: status.verifyhuman.io
- Duration: Typically 1-2 hours for major updates
- Graceful degradation: API returns maintenance mode responses
Maintenance mode response:
{
"status": "maintenance",
"message": "VerifyHuman is temporarily unavailable for maintenance. Please try again shortly.",
"estimated_completion": "2024-01-15T12:00:00Z"
}
Integration handling:
- WordPress plugin shows maintenance notice
- Custom integrations should handle
HTTP 503responses
🛡️ Security & Privacy
How secure is facial data storage?
Data protection measures:
- Encryption: All images encrypted with AES-256
- Temporary storage: Images deleted after 90 days automatically
- No facial recognition database: We don't store facial feature mappings
- Access controls: Strict access policies limit data access
- Audit logging: All data access is logged and monitored
What we store:
- ✅ Original uploaded image (encrypted, temporary)
- ✅ Verification metadata (confidence score, timestamp)
- ✅ Processing logs (for debugging)
- ❌ Facial feature vectors or biometric templates
- ❌ Persistent facial recognition database
Is VerifyHuman GDPR compliant?
Yes, with full GDPR compliance:
Data processing basis: Legitimate business interest (fraud prevention)
User rights supported:
- Right to access: Users can download their verification history
- Right to deletion: Account deletion removes all associated data
- Right to portability: Data export available in JSON format
- Right to rectification: Users can update account information
GDPR compliance tools:
- Data Processing Agreement (DPA): Available for Enterprise customers
- Privacy controls: User-facing privacy settings in dashboard
- Data retention: Automatic deletion after specified periods
- Consent management: Clear opt-in/opt-out mechanisms
EU data residency: Enterprise customers can request EU-only data processing.
Can verification be spoofed with photos or videos?
Anti-spoofing measures:
- Liveness detection: Advanced AI-powered liveness analysis
- 3D face analysis: Detects flat images vs. real faces
- Eye movement tracking: Detects unnatural stillness
- Texture analysis: Identifies printed photos or screen displays
- Depth analysis: Uses subtle shadow and lighting cues
Additional security:
- Random pose requirements: Future feature for challenge-response
- Device fingerprinting: Track suspicious device patterns
- Behavioral analysis: Monitor verification attempt patterns
- Manual review queue: Suspicious attempts flagged for human review
Success rates against spoofing:
- Photo spoofing: >99% detection rate
- Video spoofing: >95% detection rate
- Deepfake attempts: >90% detection rate (improving)
🔧 Troubleshooting
"Invalid client key" error
Common causes:
- Typo in API key: Double-check copy/paste accuracy
- Wrong key type: Using client secret instead of client key
- Deactivated key: Key was disabled in dashboard
- Environment mismatch: Using test key in production or vice versa
Solutions:
# Verify your API key format
echo "pk_live_..." # Client key (public) - correct for /verify
echo "sk_live_..." # Client secret (private) - for /validate only
# Test API key validity
curl -X POST https://app.verifyhuman.io/api/verify \
-F "clientKey=pk_live_your_key_here" \
-F "file=@test_image.jpg"
"No file uploaded" error
Common causes:
- Missing file parameter: Form field not named "file"
- Empty file: File size is 0 bytes
- File type validation: Server rejected file before reaching VerifyHuman
- Network timeout: Large file upload timed out
Solutions:
// Correct file upload format
const formData = new FormData();
formData.append('clientKey', 'pk_live_your_key');
formData.append('file', fileInput.files[0]); // Must be named 'file'
// Verify file is not empty
if (fileInput.files[0].size === 0) {
alert('Please select a valid image file');
return;
}
// Check file type client-side
const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg'];
if (!allowedTypes.includes(fileInput.files[0].type)) {
alert('Please upload a JPG or PNG image');
return;
}
WordPress plugin not working
Common issues:
Plugin conflicts:
# Disable other plugins temporarily # Check if VerifyHuman works # Re-enable plugins one by one to identify conflictPHP version compatibility:
// Requires PHP 7.4 or higher if (version_compare(PHP_VERSION, '7.4.0') < 0) { echo 'Please upgrade PHP to 7.4 or higher'; }Memory limits:
// Add to wp-config.php ini_set('memory_limit', '256M');CURL/HTTP issues:
// Test API connectivity $response = wp_remote_get('https://app.verifyhuman.io/health'); if (is_wp_error($response)) { echo 'Cannot connect to VerifyHuman API: ' . $response->get_error_message(); }
📱 Mobile & Performance
Why is verification slow on mobile?
Common performance issues:
Large image files:
- Problem: 10MB+ photos from high-res cameras
- Solution: Resize images before upload
// Image compression example function compressImage(file, maxWidth = 1024, quality = 0.8) { return new Promise((resolve) => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const img = new Image();img.onload = () => { const ratio = Math.min(maxWidth / img.width, maxWidth / img.height); canvas.width = img.width ratio; canvas.height = img.height ratio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob(resolve, 'image/jpeg', quality); };
img.src = URL.createObjectURL(file); }); }
Slow network connection:
- Show progress indicator during upload
- Implement retry logic for failed requests
- Optimize for mobile networks
Processing delays:
- Typical processing time: 1-3 seconds
- Timeout after: 30 seconds
- Use status polling for long-running verifications
How to implement retry logic?
Robust retry implementation:
async function verifyWithRetry(file, clientKey, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const formData = new FormData();
formData.append('clientKey', clientKey);
formData.append('file', file);
const response = await fetch('https://app.verifyhuman.io/api/verify', {
method: 'POST',
body: formData,
timeout: 30000 // 30 second timeout
});
if (response.ok) {
return await response.json();
}
// Handle specific error cases
if (response.status === 429) {
// Throttled - wait before retry
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
if (response.status >= 400 && response.status < 500) {
// Client error - don't retry
throw new Error(`Client error: ${response.status}`);
}
// Server error - retry
if (attempt === maxRetries) {
throw new Error(`Server error after ${maxRetries} attempts`);
}
} catch (error) {
if (attempt === maxRetries) {
throw error;
}
// Wait before retry (exponential backoff)
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
💡 Best Practices
When should I implement verification?
Recommended trigger points:
- Account registration: Verify new users immediately
- Before premium access: Gate paid features behind verification
- Suspicious activity: Trigger re-verification for unusual behavior
- High-value actions: Verify before financial transactions
- Content posting: Verify before allowing user-generated content
Implementation patterns:
// Progressive verification
const verificationPoints = {
registration: 'optional', // Encourage but don't require
firstPost: 'required', // Must verify to post content
premiumUpgrade: 'required', // Must verify for paid features
suspiciousActivity: 'required', // Triggered automatically
highValueAction: 'required' // Payments, sensitive data
};
How to handle verification in user workflows?
UX best practices:
Clear communication:
<!-- Good: Clear explanation --> <div class="verification-prompt"> <h3>Verify Your Identity</h3> <p>Take a quick selfie to prove you're human and protect your account from bots.</p> <ul> <li>✓ Prevents fake accounts</li> <li>✓ Secures your data</li> <li>✓ Takes less than 30 seconds</li> </ul> <button onclick="startVerification()">Verify Now</button> </div>Graceful degradation:
// Handle verification failure gracefully function handleVerificationResult(result) { if (result.status === 'PASS') { // Full access granted showSuccessMessage('Welcome! Your account is now verified.'); redirectToDashboard(); } else if (result.status === 'FAIL') { // Limited access, retry option showRetryMessage('Verification failed. Please try again with better lighting.'); showRetryButton(); } else if (result.status === 'throttled') { // Temporary lockout showThrottleMessage('Please wait 5 minutes before trying again.'); showAlternativeOptions(); // Email verification, etc. } }Progressive disclosure:
- Start with optional verification
- Gradually require verification for more features
- Provide clear value proposition for verification
📞 Support & Contact
How do I get help with integration issues?
Support channels:
Technical Support:
- Email: support@verifyhuman.io
- Response time: 4-24 hours
- Include: API key (client key only), error messages, code samples
Integration Assistance:
- Email: integrations@verifyhuman.io
- For: Custom platform integrations, SDK requests
- Enterprise: Dedicated integration engineer
Billing Questions:
- Email: billing@verifyhuman.io
- For: Plan changes, invoices, refunds
What information should I include in support requests?
Technical issues:
Subject: [API] Verification failures - Low confidence scores
Environment: Production
API Key: pk_live_abc123... (client key only, never include secret)
Error: Multiple "Low confidence score" failures
Sample verification ID: ver_xyz789123
User agent: Chrome 96 on iOS 15
Image details: iPhone camera, good lighting, single face
Steps to reproduce:
1. Upload clear selfie via /api/verify
2. Receive 65% confidence score
3. Verification fails with "Low confidence"
Expected: Should pass with >80% confidence
Actual: Failing at 65% confidence consistently
WordPress issues:
Subject: [WordPress] Plugin badges not displaying
WordPress version: 6.1.1
PHP version: 8.0.25
Plugin version: VerifyHuman 2.0.0
Active plugins: WooCommerce, Yoast SEO, VerifyHuman
Theme: Twenty Twenty-Three
Issue: Verified badges not showing in comments
API key configured: Yes (pk_live_...)
Verification working: Yes
Badge setting enabled: Yes
Browser console errors: [paste any JavaScript errors]
Is there a status page for service monitoring?
Status page includes:
- 🟢 Real-time service status
- 📊 Performance metrics (response times, uptime)
- 🔔 Incident notifications and updates
- 📈 Historical uptime data
- 📧 Email/SMS notifications for outages
Subscribe to updates:
- Email notifications for incidents
- Slack integration for team channels
- RSS/Atom feeds for automated monitoring
- Webhook notifications for custom alerting
🚀 Advanced Features
Can I get raw confidence scores for custom logic?
Yes, via API response:
{
"verification_id": "ver_abc123",
"status": "PASS",
"confidence": 87.3, // Raw confidence score (0-100)
"token": "eyJ0eXAi..."
}
Custom threshold implementation:
function processVerificationResult(result) {
const confidence = result.confidence;
if (confidence >= 90) {
// High confidence - full access
grantFullAccess(result.verification_id);
} else if (confidence >= 75) {
// Medium confidence - limited access
grantLimitedAccess(result.verification_id);
} else if (confidence >= 60) {
// Low confidence - manual review
flagForManualReview(result.verification_id);
} else {
// Very low confidence - reject
rejectAccess(result.error);
}
}
How do I implement custom webhooks?
Webhook endpoint setup:
# Flask webhook receiver example
from flask import Flask, request, jsonify
import hmac
import hashlib
app = Flask(__name__)
@app.route('/webhook/verifyhuman', methods=['POST'])
def handle_verifyhuman_webhook():
# Verify webhook signature
payload = request.get_data()
signature = request.headers.get('X-VerifyHuman-Signature')
expected = hmac.new(
webhook_secret.encode(),
payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
return jsonify({'error': 'Invalid signature'}), 401
# Process webhook data
data = request.get_json()
event_type = data['event']
if event_type == 'verification.completed':
handle_verification_completed(data['verification'])
elif event_type == 'user.verified':
handle_user_verified(data['user'])
elif event_type == 'throttling.triggered':
handle_throttling_alert(data['throttle_info'])
return jsonify({'status': 'received'})
def handle_verification_completed(verification):
# Custom business logic
user_id = verification['user_id']
status = verification['status']
if status == 'PASS':
# Grant access, send welcome email, etc.
activate_user_account(user_id)
send_welcome_email(user_id)
else:
# Handle failure - retry prompts, etc.
send_retry_notification(user_id)
Still have questions? Contact our support team at support@verifyhuman.io.