Pika⚡
Pika⚡
Captcha API — Crie sua conta
Mínimo 8 caracteres
Pika⚡Captcha
Menu
Recursos
Tempo real · 5s
?
Carregando...
Pika⚡Captcha
Visão geral
Suas métricas de captcha em tempo real
Sites ativos
—
Verificações totais
—
Sucesso
—
Falhas
—
Taxa de sucesso
—
Sites recentes
Meus sites
Gerencie suas site keys e domínios
Documentação
Integre o PikaCaptcha em qualquer projeto

Como funciona

O PikaCaptcha usa Proof of Work (PoW) — o frontend resolve um desafio SHA256 antes de submeter o formulário. O resultado é verificado pelo seu backend via /api/siteverify, exatamente como o reCAPTCHA.

1
Frontend: GET /api/challenge
Busca um desafio usando a siteKey pública
2
Frontend: resolve o PoW + POST /api/verify
Resolve SHA256 e envia o nonce. Recebe um token
3
Backend: POST /api/siteverify
Valida o token com a secretKey. Nunca exponha no frontend!

GET /api/challenge

ParâmetroTipoDescrição
sitekeystringSua site key pública (pk_...) obrigatório
Resposta:
{ "id": "abc123", "challenge": "deadbeef...", "difficulty": 4, "algorithm": "sha256", "expires_in": 300 }

POST /api/verify

ParâmetroTipoDescrição
idstringID do challenge obrigatório
noncenumberNonce encontrado no PoW obrigatório
sitekeystringSua site key (pk_...) obrigatório
fingerprintobjectDados de fingerprint (opcional, aumenta score)
Resposta:
{ "success": true, "token": "eyJ...", "score": 0.9, "expires_in": 120 }

POST /api/siteverify (backend only)

ParâmetroTipoDescrição
secretstringSua secret key (sk_...) obrigatório
tokenstringToken recebido do /api/verify obrigatório
remoteipstringIP do usuário (opcional)
Resposta:
{ "success": true, "score": 0.9, "flags": [], "challenge_ts": "2024-01-01T00:00:00.000Z", "hostname": "seusite.com" }
SDK & Exemplos
Copie e cole no seu projeto

Frontend — JavaScript (vanilla)

// Full SDK — cole no seu frontend
async function getPikaToken(siteKey) {
  // 1. Buscar challenge
  const r1 = await fetch(`/api/challenge?sitekey=${siteKey}`)
  const { id, challenge, difficulty, sig } = await r1.json()

  // 2. Resolver PoW (medir tempo para scoring)
  const t0 = performance.now()
  const nonce = await solvePoW(challenge, difficulty)
  const solveTimeMs = Math.round(performance.now() - t0)

  // 3. Coletar fingerprint
  const fingerprint = await collectFingerprint(solveTimeMs)

  // 4. Verificar e obter token
  const r2 = await fetch('/api/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ id, nonce, sitekey: siteKey, sig, fingerprint,
      honeypot: '' // sempre string vazia — bots preenchem
    })
  })
  const { token } = await r2.json()
  return token
}

// PoW usando Web Workers (não trava a UI)
function solvePoW(challenge, difficulty) {
  return new Promise(resolve => {
    const prefix = '0'.repeat(difficulty)
    let nonce = 0
    function tick() {
      for (let i = 0; i < 5000; i++) {
        if (sha256hex(challenge + nonce).startsWith(prefix))
          return resolve(nonce)
        nonce++
      }
      setTimeout(tick, 0) // yield para não travar UI
    }
    tick()
  })
}

// Coleta ~12 sinais para scoring anti-bot
async function collectFingerprint(solveTimeMs) {
  let canvasHash = '', webglRenderer = ''
  try {
    const c = document.createElement('canvas')
    c.getContext('2d').fillText('pika', 2, 15)
    canvasHash = c.toDataURL().slice(-32)
    const gl = c.getContext('webgl')
    webglRenderer = gl?.getParameter(gl.getExtension('WEBGL_debug_renderer_info')
      ?.UNMASKED_RENDERER_WEBGL) || ''
  } catch {}
  return {
    userAgent:   navigator.userAgent,
    language:    navigator.language,
    timezone:    Intl.DateTimeFormat().resolvedOptions().timeZone,
    screen:      `${screen.width}x${screen.height}`,
    colorDepth:  screen.colorDepth,
    pluginCount: navigator.plugins?.length ?? 0,
    canvasHash, webglRenderer, solveTimeMs,
    mouseEvents: window._pikaMouseCount || 0
  }
}

// Rastrear movimento de mouse (cole no <body> uma vez)
let _pikaMouseCount = 0
document.addEventListener('mousemove', () => _pikaMouseCount++, { passive: true })
window._pikaMouseCount = _pikaMouseCount

Backend — Node.js / Express

app.post('/submit', async (req, res) => {
  const { pikaToken, ...formData } = req.body

  const verify = await fetch('https://SEU_SITE.netlify.app/api/siteverify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      secret: process.env.PIKA_SECRET_KEY, // sk_xxx — nunca no frontend!
      token: pikaToken,
      remoteip: req.ip
    })
  })

  const result = await verify.json()

  if (!result.success || result.score < 0.5) {
    return res.status(403).json({ error: 'Captcha falhou' })
  }

  // Processar formulário normalmente...
})

Backend — Python / Flask

import requests

def verify_captcha(token):
    r = requests.post('https://SEU_SITE.netlify.app/api/siteverify', json={
        'secret': os.environ['PIKA_SECRET_KEY'],
        'token': token
    })
    data = r.json()
    return data.get('success') and data.get('score', 0) >= 0.5
Novo site
Um domínio por linha. Deixe vazio para aceitar qualquer origem.
Editar site
Um domínio por linha.
Remover site

Tem certeza? As keys serão invalidadas permanentemente.

Site: