PicturaCAPTCHA Documentation
Everything you need to integrate PicturaCAPTCHA into your website. Get started in under 5 minutes.
Getting Started
PicturaCAPTCHA is completely free with no limits. Follow these steps:
Quick Start
- Get your free site key from the dashboard
- Add the script tag to your HTML
- Add the CAPTCHA container element
- Verify tokens on your server
How It Works
PicturaCAPTCHA uses a multi-layered approach to distinguish humans from bots:
Behavioral Analysis
Tracks mouse movements, scroll velocity, typing patterns, and touch interactions. Humans have natural, varied patterns - bots move mechanically.
Risk Scoring
AI calculates a risk score (0-100). Low-risk users pass automatically. Higher risk triggers a challenge.
Biometric Detection
Our unique hold-to-verify feature detects human touch patterns and pressure variations - impossible for bots to replicate.
Smart Challenges
7 challenge types: math, patterns, image selection, text typing, word unscramble, slider, and biometric hold.
Auto-Verify Technology
When users answer correctly, PicturaCAPTCHA automatically verifies them - no need to click a submit button. Wrong answers show immediate feedback and load a new challenge. After 3 failed attempts, users must wait 60 seconds before trying again.
Installation
1. Add the Script
Add this script tag to your HTML head or before the closing body tag:
<script src="https://picturaai.sbs/api/captcha/widget.js" async defer></script>2. Add the Container
Place this where you want the CAPTCHA to appear:
<form id="myForm" method="POST" action="/submit">
<input type="email" name="email" required />
<!-- PicturaCAPTCHA Widget -->
<div id="pictura-captcha"
data-sitekey="YOUR_SITE_KEY"
data-callback="onCaptchaVerify">
</div>
<button type="submit">Submit</button>
</form>
<script>
function onCaptchaVerify(token) {
// Token is automatically added to form
console.log('User verified! Token:', token);
}
</script>NPM Package
npm install @pictura/captchaimport React from 'react'
import { createReactCaptcha } from '@pictura/captcha'
const PicturaCaptcha = createReactCaptcha(React)
export function ContactForm() {
const [token, setToken] = React.useState('')
return (
<form>
<PicturaCaptcha
siteKey="YOUR_SITE_KEY"
onVerify={setToken}
/>
<button disabled={!token}>Submit</button>
</form>
)
}Configuration
data-sitekeyDefault: requireddata-callbackDefault: -data-expired-callbackDefault: -data-error-callbackDefault: -data-sizeDefault: normaldata-themeDefault: autoServer Verification
Always verify tokens on your server. Never trust client-side verification alone.
// POST to your server with the captcha token
const { captchaToken } = req.body;
// Verify with PicturaCAPTCHA API
const response = await fetch('https://picturaai.sbs/api/captcha/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.PICTURA_CAPTCHA_SECRET, // Your secret key
token: captchaToken, // Token from client
ip: req.ip // Optional: user IP
})
});
const result = await response.json();
if (result.success) {
// User is human - proceed with form submission
console.log('Verification successful');
} else {
// Verification failed
console.log('Bot detected:', result.error);
throw new Error('CAPTCHA verification failed');
}Response Format
// Success
{
"success": true,
"challenge_ts": "2024-01-15T12:00:00Z",
"hostname": "yoursite.com"
}
// Failure
{
"success": false,
"error": "invalid-token" // or "expired-token", "already-used"
}Framework Guides
React / Next.js
'use client'
import { useState } from 'react';
export function ContactForm() {
const [token, setToken] = useState('');
const [submitted, setSubmitted] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!token) {
alert('Please complete the CAPTCHA');
return;
}
const res = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: e.target.email.value,
captchaToken: token
})
});
if (res.ok) setSubmitted(true);
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
{/* Import SmartCaptcha component */}
<SmartCaptcha
siteKey="YOUR_SITE_KEY"
onVerify={(t) => setToken(t)}
/>
<button type="submit">Submit</button>
</form>
);
}Next.js API Route
import { NextResponse } from 'next/server';
export async function POST(req: Request) {
const { email, captchaToken } = await req.json();
// Verify CAPTCHA
const captchaRes = await fetch(
'https://picturaai.sbs/api/captcha/verify',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.PICTURA_CAPTCHA_SECRET,
token: captchaToken
})
}
);
const captchaData = await captchaRes.json();
if (!captchaData.success) {
return NextResponse.json(
{ error: 'CAPTCHA verification failed' },
{ status: 400 }
);
}
// Process form...
return NextResponse.json({ success: true });
}Vue / Nuxt (Client)
<template>
<form @submit.prevent="submitForm">
<input v-model="email" type="email" required />
<div id="pictura-captcha" data-sitekey="YOUR_SITE_KEY" data-callback="onCaptchaVerify"></div>
<button type="submit">Submit</button>
</form>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const email = ref('')
const captchaToken = ref('')
onMounted(() => {
window.onCaptchaVerify = (token) => {
captchaToken.value = token
}
})
const submitForm = async () => {
await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: email.value, captchaToken: captchaToken.value })
})
}
</script>
<!-- Include once in app head -->
<!-- <script src="https://picturaai.sbs/api/captcha/widget.js" async defer></script> -->Backend verification (Node, Python, PHP)
// Node.js (Express)
const verify = await fetch('https://picturaai.sbs/api/captcha/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ secret: process.env.PICTURA_CAPTCHA_SECRET, token: captchaToken })
}).then(r => r.json())
# Python (FastAPI / Flask style)
import requests
verify = requests.post('https://picturaai.sbs/api/captcha/verify', json={
'secret': os.getenv('PICTURA_CAPTCHA_SECRET'),
'token': captcha_token,
}).json()
// PHP
$verify = json_decode(file_get_contents('https://picturaai.sbs/api/captcha/verify', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json
",
'content' => json_encode([
'secret' => getenv('PICTURA_CAPTCHA_SECRET'),
'token' => $captchaToken,
]),
]
])) , true);Security Best Practices
Keep secrets secure
Never expose your secret key in client-side code. Use environment variables.
Verify every submission
Always verify tokens server-side before processing any form.
Tokens are single-use
Each token can only be verified once to prevent replay attacks.
Tokens expire quickly
Tokens expire after 5 minutes. Users must re-verify if they wait too long.
Domain validation
Tokens are tied to your registered domain and cannot be used elsewhere.
Rate limiting
We rate limit verification requests to prevent abuse.