Monitorização de crawlers de IA
Atualizado em 18 de outubro de 2026
Os crawlers de IA não executam JavaScript, pelo que o script do Statsdot nunca os deteta. Para saber quais deles leem o seu site, o seu servidor reporta os pedidos ao Statsdot. Poderá então ver, no relatório do site, cada crawler com o seu número de pedidos e as páginas que os crawlers mais leem.
Apenas são armazenados os pedidos cujo user agent corresponde a um crawler do diretório de crawlers de IA, juntamente com o crawler, o caminho sem query string e o código de estado. Os pedidos de pessoas são ignorados, mesmo que o seu servidor os envie, e não é armazenado qualquer endereço IP.
1. Ativar a funcionalidade
Nas definições do site, em AI crawler tracking, escolha Turn on and create a key. Copie a chave (começa por sdb_). A chave apenas pode reportar pedidos de crawlers; renove-a no mesmo local caso seja comprometida.
2. Ligar o seu site
WordPress
Em Settings > Statsdot do plugin, cole a chave em AI crawler tracking e guarde. É tudo.
Laravel
Adicione este middleware ao grupo web. O reporte é feito após o envio da resposta, pelo que os crawlers não sofrem atrasos:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Symfony\Component\HttpFoundation\Response;
class ReportAiCrawlers
{
private const TOKENS = ['gptbot', 'oai-searchbot', 'chatgpt-user', 'claudebot', 'claude-user', 'claude-searchbot', 'perplexitybot', 'perplexity-user', 'google-extended', 'googlebot', 'bingbot', 'applebot', 'meta-externalagent', 'bytespider', 'ccbot', 'amazonbot', 'duckassistbot', 'mistralai-user'];
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}
public function terminate(Request $request, Response $response): void
{
$agent = strtolower((string) $request->userAgent());
foreach (self::TOKENS as $token) {
if (str_contains($agent, $token)) {
Http::timeout(2)->withHeaders(['X-Statsdot-Bot-Key' => config('services.statsdot.bot_key')])
->post('https://statsdot.com/api/bots', [
'user_agent' => $request->userAgent(),
'url' => $request->fullUrl(),
'status' => $response->getStatusCode(),
]);
return;
}
}
}
}
Coloque a chave no .env como STATSDOT_BOT_KEY e em config/services.php como 'statsdot' => ['bot_key' => env('STATSDOT_BOT_KEY')]. O Statsdot reconhece mais crawlers do que a lista curta acima; estenda-a com os tokens do diretório que lhe interessam.
PHP simples
No final do seu front controller (por exemplo, index.php), após a página ter sido enviada:
$agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (preg_match('/gptbot|oai-searchbot|chatgpt-user|claudebot|claude-user|claude-searchbot|perplexitybot|perplexity-user|googlebot|bingbot|applebot|meta-externalagent|bytespider|ccbot|amazonbot/i', $agent)) {
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
$context = stream_context_create(['http' => [
'method' => 'POST',
'timeout' => 2,
'header' => "Content-Type: application/json\r\nX-Statsdot-Bot-Key: sdb_your_key\r\n",
'content' => json_encode([
'user_agent' => $agent,
'url' => 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'],
'status' => http_response_code(),
]),
]]);
@file_get_contents('https://statsdot.com/api/bots', false, $context);
}
Node.js e Express
const CRAWLERS = /gptbot|oai-searchbot|chatgpt-user|claudebot|claude-user|claude-searchbot|perplexitybot|perplexity-user|googlebot|bingbot|applebot|meta-externalagent|bytespider|ccbot|amazonbot/i;
app.use((req, res, next) => {
const agent = req.get('user-agent') || '';
if (CRAWLERS.test(agent)) {
res.on('finish', () => {
fetch('https://statsdot.com/api/bots', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Statsdot-Bot-Key': process.env.STATSDOT_BOT_KEY },
body: JSON.stringify({ user_agent: agent, url: `${req.protocol}://${req.get('host')}${req.originalUrl}`, status: res.statusCode }),
}).catch(() => {});
});
}
next();
});
Next.js
No middleware.ts, reporte sem atrasar a resposta:
import { NextResponse, type NextRequest, type NextFetchEvent } from 'next/server';
const CRAWLERS = /gptbot|oai-searchbot|chatgpt-user|claudebot|claude-user|claude-searchbot|perplexitybot|perplexity-user|googlebot|bingbot|applebot|meta-externalagent|bytespider|ccbot|amazonbot/i;
export function middleware(request: NextRequest, event: NextFetchEvent) {
const agent = request.headers.get('user-agent') ?? '';
if (CRAWLERS.test(agent)) {
event.waitUntil(fetch('https://statsdot.com/api/bots', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Statsdot-Bot-Key': process.env.STATSDOT_BOT_KEY! },
body: JSON.stringify({ user_agent: agent, url: request.url }),
}).catch(() => {}));
}
return NextResponse.next();
}
O endpoint
POST https://statsdot.com/api/bots com o cabeçalho X-Statsdot-Bot-Key e um corpo JSON {"user_agent": "...", "url": "...", "status": 200}, ou {"events": [...]} com até 100 pedidos. Responde com 202 e o número registado. Até 600 pedidos por minuto por chave.
Limites
Cada conta regista até 100.000 pedidos de crawlers por mês em todos os seus sites; para além disso, não são registados até ao mês seguinte. Os pedidos de crawlers não contam para os eventos do seu plano. São mantidos durante o mesmo período que as suas visitas (24 meses).