Back to PicturaCAPTCHA

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

  1. Get your free site key from the dashboard
  2. Add the script tag to your HTML
  3. Add the CAPTCHA container element
  4. 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:

index.html
<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.html
<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

terminal
npm install @pictura/captcha
react-example.tsx
import 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: required
Your site key from the dashboard
data-callbackDefault: -
Function called on successful verification with token
data-expired-callbackDefault: -
Function called when token expires (after 5 min)
data-error-callbackDefault: -
Function called on error
data-sizeDefault: normal
Widget size: compact or normal
data-themeDefault: auto
Theme: light, dark, or auto

Server Verification

Always verify tokens on your server. Never trust client-side verification alone.

server.js
// 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

response.json
// 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

ContactForm.tsx
'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

app/api/contact/route.ts
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)

CaptchaForm.vue
<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)

verify-examples.txt
// 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.

Ready to get started?

Create your free account and get your API keys in seconds.

Get Started Free