Bloqueie os bots.
Sem que seus
usuários percebam.
Um checkbox. Zero chaves API. Zero tracking. Seus usuários marcam e seguem. Os bots batem em um muro criptográfico que seu servidor valida em uma única linha de código.
Invisível para humanos.
Impossível para bots.
Três passos. Nem um a mais. Sem bibliotecas pré-carregadas, sem scripts de terceiros, sem chaves para rotacionar.
O usuário marca um checkbox
Até esse clique, o mCaptcha dorme. Nenhum fetch, ciclo de CPU ou requisição DNS. Seu Lighthouse nem sabe que ele existe.
Desafio criptográfico em ~50 ms
O navegador resolve um Proof-of-Work SHA-256. Se o IP disparou >30 desafios em uma hora, passamos a um puzzle deslizante que nenhum bot atravessa sem tempo humano real.
Seu backend recebe um token
Um GET para /api/captcha/verify com o token. Se ok=true, é humano e você processa o form. Uso único, validade 2 min. Uma linha em qualquer linguagem.
Mesmo objetivo.
Melhores consequências.
Tudo o que o reCAPTCHA faz por você, o mCaptcha também faz. O que o reCAPTCHA faz aos seus usuários, não.
Duas linhas. Pronto.
Sem npm install. Sem dashboard para se cadastrar. Sem chaves para copiar. Cole o snippet, faça deploy, feche o ticket.
<form action="/contact" method="POST">
<input name="email" required>
<textarea name="message" required></textarea>
<div class="mcaptcha"></div>
<button type="submit">Enviar</button>
</form>
<script src="https://medel.es/captcha.js" async defer></script>
Antes de processar o formulário,
valide o token.
Seu backend recebe mcaptcha_token. Faz um GET, verifica se ok=true e segue. Cinco linguagens, mesmo fluxo, zero bibliotecas para instalar.
<?php
function mcaptcha($token) {
$url = 'https://medel.es/api/captcha/verify?token=' . urlencode($token);
$response = json_decode(file_get_contents($url));
return $response->ok ?? false;
}
// Uso:
$token = $_POST['mcaptcha_token'] ?? '';
if (!mcaptcha($token)) {
http_response_code(400);
exit('Captcha falhou');
}
// ✅ Captcha verificado. Processe o formulário.
// Validação no cliente — útil em SPAs antes de enviar ao backend.
// Para proteção real, verifique SEMPRE também no servidor.
async function mcaptcha(token) {
const url = 'https://medel.es/api/captcha/verify?token=' + encodeURIComponent(token);
const data = await fetch(url).then(r => r.json());
return data.ok === true;
}
// Uso em um formulário:
document.querySelector('form').addEventListener('submit', async (e) => {
e.preventDefault();
const fd = new FormData(e.target);
const token = fd.get('mcaptcha_token');
if (!(await mcaptcha(token))) {
alert('Captcha falhou');
return;
}
// ✅ Captcha verificado. Envie ao backend.
await fetch('/api/contact', { method: 'POST', body: fd });
});
async function mcaptcha(token) {
const url = 'https://medel.es/api/captcha/verify?token=' + encodeURIComponent(token);
const data = await fetch(url).then(r => r.json());
return data.ok === true;
}
// Uso (Express):
const token = req.body.mcaptcha_token;
if (!(await mcaptcha(token))) {
return res.status(400).send('Captcha falhou');
}
// ✅ Captcha verificado. Processe o formulário.
import urllib.request, urllib.parse, json
def mcaptcha(token):
url = 'https://medel.es/api/captcha/verify?' + urllib.parse.urlencode({'token': token})
with urllib.request.urlopen(url, timeout=5) as r:
return json.loads(r.read()).get('ok') is True
# Uso (Flask):
token = request.form.get('mcaptcha_token', '')
if not mcaptcha(token):
abort(400, 'Captcha falhou')
# ✅ Captcha verificado. Processe o formulário.
# Você só precisa de um GET com o token como query param:
curl 'https://medel.es/api/captcha/verify?token=YOUR_TOKEN'
# OK: {"ok":true,"verified_at":"2026-06-22 12:24:56"}
# FALHA: {"ok":false,"error":"already_used"}
Migrando do Google reCAPTCHA?
O widget também preenche g-recaptcha-response e aceita class="g-recaptcha". Se seu backend já lê, mude apenas a URL de verify:
// Antes: $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . $token; // Depois (sem secret): $url = 'https://medel.es/api/captcha/verify?response=' . $token;
Endpoints
Quatro endpoints REST. Sem SDK. Sem auth. Sem versionamento. Apenas o que você precisa — o widget chama os demais.
GET
https://medel.es/api/captcha/verify?token=…
Você chama
Verifica o token. Uso único: invalidado após o primeiro verify bem-sucedido, impossível replay.
200 OK:{"ok": true, "verified_at": "2026-06-22 12:24:56"}
400 KO:
{"ok": false, "error": "already_used"}
Códigos: missing_token · unknown_token · already_used · expired · origin_mismatch
GET
https://medel.es/api/captcha/challenge
Chamado pelo widget
Emite um desafio (PoW por padrão, slider puzzle se o IP for suspeito). O widget chama sozinho.
POST
https://medel.es/api/captcha/solve
Chamado pelo widget
O widget envia a solução (nonce do PoW ou posição X do slider) e recebe o token verificável.
GET
https://medel.es/api/captcha/stats
Público
Estatísticas agregadas do dia. Zero dados pessoais, zero IPs, zero tracking.
Funciona em 98%
sem configurar nada.
Funciona automaticamente em
- Sites HTTPS
- Chrome / Edge / Firefox / Safari (2017+)
- localhost em desenvolvimento
- SPA (React / Vue / Svelte)
- Formulários server-rendered
Se você tem CSP estrita
Adicione o domínio a 3 diretivas:
script-src 'self' https://medel.es; connect-src 'self' https://medel.es; style-src 'self' https://medel.es;
Perguntas honestas, respostas honestas
Quando aparece o slider puzzle?
É grátis para sempre?
Funciona sem JavaScript?
Faz tracking dos meus usuários?
Por que slider em vez de "selecione os semáforos"?
E se o Medel Captcha cair?
É compatível com reCAPTCHA?
Como faço self-host?
Cole o snippet.
Esqueça os bots.
Integre em 30 segundos. Sem cartão. Sem chaves. Sem contratos. Sem letras miúdas. Quando um bot tentar entrar, vira problema dele, não seu.