Documentação da versão 5

API de CAPTCHA

Integração pública e sem autenticação. Seis endpoints, três passos de fluxo, e o restante fica por sua conta.

Introdução

Esta API disponibiliza um serviço de verificação humana que utiliza o Cloudflare Turnstile internamente. Você solicita um desafio, envia o endereço gerado para o seu usuário e depois consulta se ele foi aprovado. Não existe cadastro, chave de acesso nem cota mensal.

Uso responsável. A API é gratuita, mas possui limite de requisições por endereço de IP, sendo sessenta criações por minuto. Se você precisa de um volume maior, entre em contato com a Titanium ou com a M4niac pela página de créditos.

Endereço base

Endereço raiz da API
https://captcha.ggxdev.com

Fluxo de uso

Projetos e o campo team

Ao criar um desafio você pode enviar o campo opcional team com o nome do seu projeto. A partir daí acontecem três coisas:

O identificador é gerado convertendo o texto para minúsculas, removendo acentos e trocando espaços por hífens:

Você envia "Meu Projeto 4"
Identificador gerado meu-projeto-4
Sem duplicidade. Como o identificador é sempre gerado da mesma forma, escrever Meu Projeto 4, meu projeto 4 ou MEU PROJETO 4 leva todos ao mesmo registro meu-projeto-4, somando as estatísticas em um único lugar.

Criar desafio

POST /api/captcha/create
Gera um novo desafio e devolve o endereço da página em que o usuário deve concluir a verificação.

Corpo da requisição

CampoTipoObrigatórioDescrição
teamtextoOpcional Nome do seu projeto, com até quarenta e oito caracteres. Gera o identificador e alimenta o ranking público.
customDataobjetoOpcional Qualquer conteúdo em JSON. Você recebe exatamente o mesmo objeto ao consultar o status.
siteUrltextoOpcional Endereço de origem, guardado apenas como referência interna.

Resposta

200 OK
{
  "success": true,
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "captchaUrl": "https://captcha.ggxdev.com/captcha/550e8400-...",
  "expiresIn": 300,
  "team": {
    "id": "meu-projeto-4",
    "name": "Meu Projeto 4"
  },
  "customData": { "userId": 42 }
}

Quando o campo team não é enviado, o campo team da resposta volta como null.

Consultar status

GET /api/captcha/status/:id
Retorna a situação atual de um desafio. É o endpoint indicado para a consulta periódica do seu servidor.
200 OK
{
  "success": true,
  "status": "success",
  "id": "550e8400-...",
  "createdAt": 1735776000000,
  "expiresIn": 240,
  "completedAt": 1735776060000,
  "team": { "id": "meu-projeto-4", "name": "Meu Projeto 4" },
  "customData": { "userId": 42 }
}

Os valores possíveis do campo status são pending, success, failed e expired.

Ranking de projetos

GET /api/captcha/teams
Lista os projetos que mais geraram desafios, ordenados do maior para o menor. Aceita o parâmetro opcional limit, com o valor máximo de cinquenta.
200 OK
{
  "success": true,
  "total": 2,
  "teams": [
    {
      "id": "meu-projeto-4",
      "name": "Meu Projeto 4",
      "generated": 120,
      "solved": 108,
      "failed": 7,
      "successRate": 90
    }
  ]
}

Estatísticas gerais

GET /api/captcha/stats
Retorna os números globais do serviço, o ranking de projetos e os créditos do projeto.

Verificar (uso interno)

POST /api/captcha/verify/:id
Chamado automaticamente pela página do CAPTCHA quando o usuário conclui o desafio. Não utilize este endpoint direto do seu servidor, pois ele existe para o widget da Cloudflare.

Exemplo em Node.js

Criar o desafio e aguardar o resultado
const BASE = 'https://captcha.ggxdev.com';

async function criarDesafio(userId) {
  const resposta = await fetch(BASE + '/api/captcha/create', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      team: 'Meu Projeto 4',
      customData: { userId }
    })
  });
  return resposta.json();
}

async function aguardarResultado(id) {
  while (true) {
    await new Promise((r) => setTimeout(r, 2000));
    const resposta = await fetch(BASE + '/api/captcha/status/' + id);
    const dados = await resposta.json();

    if (dados.status === 'success') return true;
    if (dados.status === 'failed' || dados.status === 'expired') return false;
  }
}

Exemplo em Python

Utilizando a biblioteca requests
import requests, time

BASE = "https://captcha.ggxdev.com"

def criar_desafio(user_id):
    resposta = requests.post(f"{BASE}/api/captcha/create", json={
        "team": "Meu Projeto 4",
        "customData": {"userId": user_id}
    })
    return resposta.json()

def aguardar_resultado(desafio_id):
    while True:
        time.sleep(2)
        dados = requests.get(f"{BASE}/api/captcha/status/{desafio_id}").json()

        if dados["status"] == "success":
            return True
        if dados["status"] in ("failed", "expired"):
            return False

Exemplo com cURL

Linha de comando
curl -X POST https://captcha.ggxdev.com/api/captcha/create \
  -H "Content-Type: application/json" \
  -d '{"team":"Meu Projeto 4","customData":{"userId":42}}'

curl https://captcha.ggxdev.com/api/captcha/status/<id>

curl https://captcha.ggxdev.com/api/captcha/teams?limit=5
Atenção ao tempo limite. Todo desafio expira em cinco minutos. Se o seu fluxo precisar de mais tempo do que isso, gere um novo desafio no lugar de reutilizar o anterior.