Overview

sCaptcha is a privacy-first CAPTCHA service that protects your website from bots without collecting user data. Unlike traditional CAPTCHA services, we don't track users, store cookies, or build profiles.

Privacy First

No data collection, tracking, or cookies

Two CAPTCHA Types

Vision (image selection) and Text challenges

Theme Support

Light, dark, and auto themes

Mobile Friendly

Responsive design for all devices

Quick Start

Get sCaptcha working on your website in under 5 minutes:

1

Get Your Keys

Register and create a website in your dashboard to get your sitekey and secret.

Your Keys
Site Key: YOUR_SITEKEY (public, goes in HTML)
Secret: YOUR_SECRET (private, for server verification)
2

Include Resources

Add sCaptcha CSS and JavaScript to your page:

HTML
<!-- sCaptcha CSS -->
<link rel="stylesheet" href="https://scaptcha.searshor.com/api/v3/css?sitekey=YOUR_SITEKEY">

<!-- sCaptcha JavaScript -->
<script src="https://scaptcha.searshor.com/api/v3/js?sitekey=YOUR_SITEKEY"></script>
3

Add CAPTCHA Widget

Place the sCaptcha widget in your form:

HTML
<form id="myForm">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    
    <!-- sCaptcha Widget -->
    <div class="s-recaptcha" 
         data-sitekey="YOUR_SITEKEY"
         data-callback="onSuccess"
         data-error-callback="onError"
         data-theme="auto"></div>
    
    <button type="submit" id="submitBtn" disabled>Submit</button>
</form>
4

Handle Success

Create JavaScript callbacks for success and error:

JavaScript
function onSuccess(token) {
    console.log('CAPTCHA verified:', token);
    document.getElementById('submitBtn').disabled = false;
}

function onError(error) {
    console.error('CAPTCHA error:', error);
    alert('CAPTCHA verification failed: ' + error);
}

document.getElementById('myForm').addEventListener('submit', function(e) {
    const captchaResponse = document.querySelector('input[name="s-captcha-response"]');
    if (!captchaResponse || !captchaResponse.value) {
        e.preventDefault();
        alert('Please complete the CAPTCHA');
    }
});
5

Verify Server-side

Verify the CAPTCHA response on your server:

PHP
<?php
$captchaResponse = $_POST['s-captcha-response'];
$secret = 'YOUR_SECRET';
$sitekey = 'YOUR_SITEKEY';

// Decode the response
$decoded = json_decode(base64_decode($captchaResponse), true);

if ($decoded && $decoded['success'] && $decoded['sitekey'] === $sitekey) {
    // Check expiry (tokens expire in 1 minute)
    if ((time() - $decoded['timestamp']) <= 60) {
        echo "CAPTCHA verified successfully!";
        // Process form data
    } else {
        echo "CAPTCHA token expired";
    }
} else {
    echo "CAPTCHA verification failed";
}
?>

Installation

CDN Method (Recommended)

The easiest way to use sCaptcha is via our CDN. No downloads required:

HTML
<!-- CSS -->
<link rel="stylesheet" href="https://scaptcha.searshor.com/api/v3/css?sitekey=YOUR_SITEKEY">

<!-- JavaScript -->
<script src="https://scaptcha.searshor.com/api/v3/js?sitekey=YOUR_SITEKEY"></script>

Basic Configuration

HTML Attributes

Configure sCaptcha using data attributes on the widget element:

Attribute Type Required Description
data-sitekey string ✅ Yes Your public site key from the dashboard
data-callback string ❌ No Function name to call on successful verification
data-error-callback string ❌ No Function name to call on error
data-theme string ❌ No Theme: light, dark, or auto
data-captcha-type string ❌ No Override: v3_vision or v3_text

Complete Example

HTML
<div class="s-recaptcha" 
     data-sitekey="sCaptcha_abc123xyz789"
     data-callback="handleSuccess"
     data-error-callback="handleError"
     data-theme="auto"
     data-captcha-type="v3_vision"></div>

CAPTCHA Types

Vision CAPTCHA

Users select images based on instructions (e.g., "Select all cats").

Pros:

  • More engaging user experience
  • Harder for basic bots to solve
  • Visual feedback
  • Mobile-friendly touch interface

Cons:

  • Requires good vision
  • Not screen reader friendly
  • Larger file sizes
Vision CAPTCHA Setup
<div class="s-recaptcha" 
     data-sitekey="YOUR_VISION_SITEKEY"
     data-captcha-type="v3_vision"></div>

Text CAPTCHA

Users type distorted characters they see in an image.

Pros:

  • Screen reader compatible
  • Works with keyboard navigation
  • Smaller file sizes
  • Universal accessibility

Cons:

  • Can be difficult to read
  • May frustrate users
  • Less engaging
Text CAPTCHA Setup
<div class="s-recaptcha" 
     data-sitekey="YOUR_TEXT_SITEKEY"
     data-captcha-type="v3_text"></div>

Themes & Styling

Built-in Themes

sCaptcha supports three theme modes:

Light Theme

Light Theme
<div class="s-recaptcha" 
     data-sitekey="YOUR_SITEKEY"
     data-theme="light"></div>

Dark Theme

Dark Theme
<div class="s-recaptcha" 
     data-sitekey="YOUR_SITEKEY"
     data-theme="dark"></div>

Auto Theme

Automatically matches user's system preference:

Auto Theme
<div class="s-recaptcha" 
     data-sitekey="YOUR_SITEKEY"
     data-theme="auto"></div>

Custom Styling

You can customize sCaptcha's appearance with CSS:

Custom CSS
/* Customize the widget container */
.scaptcha-widget {
    border-radius: 12px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

/* Customize the checkbox */
.scaptcha-checkbox:checked + .scaptcha-checkbox-label .scaptcha-checkmark {
    background: #your-brand-color;
    border-color: #your-brand-color;
}

/* Customize buttons */
.scaptcha-btn-verify {
    background: #your-brand-color;
}

.scaptcha-btn-verify:hover {
    background: #your-brand-color-dark;
}

Callbacks

Success Callback

Called when CAPTCHA is successfully completed:

Success Callback
function onCaptchaSuccess(token) {
    console.log('CAPTCHA completed successfully');
    console.log('Token:', token);
    
    // Enable form submission
    document.getElementById('submitButton').disabled = false;
    
    // Optional: Show success message
    showMessage('CAPTCHA verified!', 'success');
    
    // The token is automatically added to your form as 's-captcha-response'
}

Error Callback

Called when CAPTCHA verification fails:

Error Callback
function onCaptchaError(error) {
    console.error('CAPTCHA error:', error);
    
    // Handle different error types
    switch(error) {
        case 'network-error':
            showMessage('Network error. Please check your connection.', 'error');
            break;
        case 'timeout':
            showMessage('CAPTCHA timed out. Please try again.', 'error');
            break;
        case 'invalid-sitekey':
            showMessage('Configuration error. Please contact support.', 'error');
            break;
        default:
            showMessage('CAPTCHA verification failed. Please try again.', 'error');
    }
    
    // Keep submit button disabled
    document.getElementById('submitButton').disabled = true;
}

Multiple Callbacks

Handle multiple CAPTCHA widgets on the same page:

Multiple Callbacks
// For login form
function onLoginCaptchaSuccess(token) {
    document.getElementById('loginSubmit').disabled = false;
}

// For registration form  
function onRegisterCaptchaSuccess(token) {
    document.getElementById('registerSubmit').disabled = false;
}

// For contact form
function onContactCaptchaSuccess(token) {
    document.getElementById('contactSubmit').disabled = false;
}

Server Verification

Always verify CAPTCHA responses on your server. The token is automatically added to your form as s-captcha-response.

PHP Verification

PHP
<?php
function verifyCaptcha($response, $secret, $sitekey) {
    if (empty($response)) {
        return ['success' => false, 'error' => 'No CAPTCHA response'];
    }
    
    // Decode the response token
    $decoded = json_decode(base64_decode($response), true);
    
    if (!$decoded) {
        return ['success' => false, 'error' => 'Invalid token format'];
    }
    
    // Verify required fields
    if (!isset($decoded['success']) || !isset($decoded['sitekey']) || !isset($decoded['timestamp'])) {
        return ['success' => false, 'error' => 'Invalid token structure'];
    }
    
    // Verify sitekey matches
    if ($decoded['sitekey'] !== $sitekey) {
        return ['success' => false, 'error' => 'Sitekey mismatch'];
    }
    
    // Check token expiry (1 minute)
    if ((time() - $decoded['timestamp']) > 60) {
        return ['success' => false, 'error' => 'Token expired'];
    }
    
    // Verify success flag
    if (!$decoded['success']) {
        return ['success' => false, 'error' => 'Verification failed'];
    }
    
    return ['success' => true, 'data' => $decoded];
}

// Usage
$response = $_POST['s-captcha-response'] ?? '';
$secret = 'YOUR_SECRET_KEY';
$sitekey = 'YOUR_SITE_KEY';

$result = verifyCaptcha($response, $secret, $sitekey);

if ($result['success']) {
    echo "CAPTCHA verified successfully!";
    // Process form data
} else {
    echo "CAPTCHA verification failed: " . $result['error'];
}
?>

Node.js Verification

Node.js
function verifyCaptcha(response, secret, sitekey) {
    if (!response) {
        return { success: false, error: 'No CAPTCHA response' };
    }
    
    try {
        // Decode the response token
        const decoded = JSON.parse(Buffer.from(response, 'base64').toString());
        
        // Verify required fields
        if (!decoded.success || !decoded.sitekey || !decoded.timestamp) {
            return { success: false, error: 'Invalid token structure' };
        }
        
        // Verify sitekey matches
        if (decoded.sitekey !== sitekey) {
            return { success: false, error: 'Sitekey mismatch' };
        }
        
        // Check token expiry (1 minute)
        const now = Math.floor(Date.now() / 1000);
        if ((now - decoded.timestamp) > 60) {
            return { success: false, error: 'Token expired' };
        }
        
        // Verify success flag
        if (!decoded.success) {
            return { success: false, error: 'Verification failed' };
        }
        
        return { success: true, data: decoded };
        
    } catch (error) {
        return { success: false, error: 'Invalid token format' };
    }
}

// Express.js usage
app.post('/submit', (req, res) => {
    const captchaResponse = req.body['s-captcha-response'];
    const result = verifyCaptcha(captchaResponse, SECRET_KEY, SITE_KEY);
    
    if (result.success) {
        res.json({ message: 'Form submitted successfully!' });
    } else {
        res.status(400).json({ error: result.error });
    }
});

Python Verification

Python
import json
import base64
import time

def verify_captcha(response, secret, sitekey):
    if not response:
        return {'success': False, 'error': 'No CAPTCHA response'}
    
    try:
        # Decode the response token
        decoded_bytes = base64.b64decode(response)
        decoded = json.loads(decoded_bytes.decode('utf-8'))
        
        # Verify required fields
        if not all(key in decoded for key in ['success', 'sitekey', 'timestamp']):
            return {'success': False, 'error': 'Invalid token structure'}
        
        # Verify sitekey matches
        if decoded['sitekey'] != sitekey:
            return {'success': False, 'error': 'Sitekey mismatch'}
        
        # Check token expiry (1 minute)
        if (time.time() - decoded['timestamp']) > 60:
            return {'success': False, 'error': 'Token expired'}
        
        # Verify success flag
        if not decoded['success']:
            return {'success': False, 'error': 'Verification failed'}
        
        return {'success': True, 'data': decoded}
        
    except Exception as e:
        return {'success': False, 'error': 'Invalid token format'}

# Django usage
def submit_form(request):
    captcha_response = request.POST.get('s-captcha-response', '')
    result = verify_captcha(captcha_response, SECRET_KEY, SITE_KEY)
    
    if result['success']:
        return JsonResponse({'message': 'Form submitted successfully!'})
    else:
        return JsonResponse({'error': result['error']}, status=400)

Error Handling

Common Errors

Error Cause Solution
invalid-sitekey Sitekey not found or inactive Check your sitekey in the dashboard
domain-mismatch Request from unauthorized domain Add domain to your website configuration
network-error Connection to sCaptcha servers failed Check internet connection and try again
timeout Request timed out Retry the CAPTCHA challenge
rate-limit Too many requests Wait before trying again

Graceful Degradation

Handle cases where sCaptcha fails to load:

Fallback Handling
// Check if sCaptcha loaded successfully
setTimeout(function() {
    if (typeof window.sCaptcha === 'undefined') {
        console.warn('sCaptcha failed to load');
        
        // Option 1: Show alternative verification
        showAlternativeVerification();
        
        // Option 2: Allow form submission with server-side verification
        document.getElementById('submitBtn').disabled = false;
        document.getElementById('captchaWarning').style.display = 'block';
    }
}, 5000); // Wait 5 seconds for sCaptcha to load

function showAlternativeVerification() {
    const captchaContainer = document.querySelector('.s-recaptcha');
    captchaContainer.innerHTML = `
        <div class="fallback-verification">
            <p>CAPTCHA verification temporarily unavailable.</p>
            <label>
                <input type="checkbox" required> 
                I confirm I am not a robot
            </label>
        </div>
    `;
}

API Reference

JavaScript API

Global Methods

window.sCaptcha.render(element, options)

Manually render a CAPTCHA widget.

Manual Rendering
const widget = window.sCaptcha.render(document.getElementById('captcha'), {
    sitekey: 'YOUR_SITEKEY',
    theme: 'dark',
    callback: 'onSuccess',
    'error-callback': 'onError'
});
window.sCaptcha.reset(widgetId)

Reset a CAPTCHA widget to its initial state.

Reset Widget
// Reset specific widget
window.sCaptcha.reset(widgetId);

// Reset all widgets
Object.keys(window.sCaptchaInstances).forEach(sitekey => {
    window.sCaptchaInstances[sitekey].reset();
});

REST API Endpoints

GET /api/v3/js

Load sCaptcha JavaScript library.

Parameters:
  • sitekey (required) - Your site key
Request
GET https://scaptcha.searshor.com/api/v3/js?sitekey=YOUR_SITEKEY

GET /api/v3/css

Load sCaptcha CSS styles.

Parameters:
  • sitekey (required) - Your site key
Request
GET https://scaptcha.searshor.com/api/v3/css?sitekey=YOUR_SITEKEY

Troubleshooting

Common Issues

❌ CAPTCHA widget not appearing

Possible causes:
  • JavaScript not loaded or blocked
  • Incorrect sitekey
  • Domain not authorized
Solutions:
  1. Check browser console for errors
  2. Verify sitekey is correct
  3. Ensure domain is added to website configuration
  4. Check if JavaScript is enabled

❌ Form submitting without CAPTCHA

Solutions:
  1. Check for s-captcha-response field in form data
  2. Implement server-side verification
  3. Disable submit button until CAPTCHA completes
Form Validation
document.getElementById('myForm').addEventListener('submit', function(e) {
    const captchaResponse = document.querySelector('input[name="s-captcha-response"]');
    
    if (!captchaResponse || !captchaResponse.value) {
        e.preventDefault();
        alert('Please complete the CAPTCHA verification');
        return false;
    }
});

❌ "Domain not authorized" error

Solutions:
  1. Go to your dashboard → My Websites
  2. Edit your website configuration
  3. Add your domain to the "Domains" field
  4. Support wildcards: *.example.com

Debug Mode

Enable debug mode to see detailed console logs:

Debug Mode
// Enable debug mode
window.sCaptcha = window.sCaptcha || {};
window.sCaptcha.debug = true;

// Check CAPTCHA status
console.log('sCaptcha instances:', window.sCaptchaInstances);
console.log('sCaptcha config:', window.sCaptcha);

Frequently Asked Questions

Can I use sCaptcha on multiple domains?

Yes! Add all your domains (separated by commas) in your website configuration. You can also use wildcards like *.example.com.

How long are CAPTCHA tokens valid?

Tokens expire after 1 minute for security. Always verify them immediately on your server.

Can I customize the appearance?

Yes! Use the built-in themes (light/dark/auto) or add custom CSS to match your brand.

Is sCaptcha GDPR compliant?

Absolutely! We don't collect any personal data, use cookies, or track users. No consent required.

What happens if sCaptcha is down?

Implement fallback verification in your JavaScript. Consider allowing form submission with enhanced server-side validation.

Can I use both Vision and Text CAPTCHA?

Yes, but you need separate sitekeys for each type. Configure them in your dashboard.

Support & Resources

Live Demo

Test both CAPTCHA types interactively

Try Demo

Code Examples

Ready-to-use integration examples

View Example

Contact Support

Get help with integration issues

Email Support

GitHub

Report issues and contribute

GitHub Repo (soon)