Getno Assist API
Valide quando uma navegação web foi iniciada pela Getno Assist e aplique regras específicas de acesso, CAPTCHA ou monitoramento.
Em automações web com stealth desabilitado, a Getno envia headers de identidade apenas na navegação principal do site cadastrado.
X-Getno-Client: web-agent/1.0
X-Getno-Automation-Token: <JWT assinado pela Getno>A assinatura do JWT é validada com a chave pública publicada pela Getno. A URL do JWKS é estável e pode ser cacheada por bibliotecas JWT.
curl https://api.getno.com.br/.well-known/jwks.jsonO campo aud sempre representa a origem do site acessado. O cliente deve validar esse valor contra a origem esperada da própria aplicação.
{
"iss": "https://getno.com.br",
"aud": "https://app.cliente.com",
"sub": "getno-assist-web-agent",
"client": "web-agent/1.0",
"iat": 1776780000,
"nbf": 1776780000,
"exp": 1776781800,
"jti": "9af62fb1-0e32-45cc-96d2-9b1dfc7ab513",
"orgId": "org_123",
"siteId": "site_123",
"automationId": "automation_123",
"runId": "run_123",
"environmentId": "env_123",
"runType": "ai_automation"
}Valide o token na camada que recebe o request HTTP inicial: middleware, edge, backend, gateway ou load balancer programável. JavaScript rodando no navegador não consegue ler os headers da navegação principal.
import { createRemoteJWKSet, jwtVerify } from 'jose';
const getnoJwks = createRemoteJWKSet(
new URL('https://api.getno.com.br/.well-known/jwks.json')
);
export async function verifyGetnoAutomation(req) {
const token = req.headers['x-getno-automation-token'];
const client = req.headers['x-getno-client'];
if (client !== 'web-agent/1.0' || !token) {
return { verified: false };
}
const audience = 'https://app.cliente.com';
const { payload } = await jwtVerify(token, getnoJwks, {
issuer: 'https://getno.com.br',
audience,
});
if (payload.client !== 'web-agent/1.0') {
return { verified: false };
}
return {
verified: true,
orgId: payload.orgId,
siteId: payload.siteId,
automationId: payload.automationId,
runId: payload.runId,
};
}Uma forma comum é validar o token no middleware e gravar um sinal temporário para o frontend decidir se deve mostrar CAPTCHA.
import { NextResponse } from 'next/server';
import { createRemoteJWKSet, jwtVerify } from 'jose';
const getnoJwks = createRemoteJWKSet(
new URL('https://api.getno.com.br/.well-known/jwks.json')
);
export async function middleware(request) {
const token = request.headers.get('x-getno-automation-token');
const client = request.headers.get('x-getno-client');
if (client !== 'web-agent/1.0' || !token) {
return NextResponse.next();
}
try {
await jwtVerify(token, getnoJwks, {
issuer: 'https://getno.com.br',
audience: request.nextUrl.origin,
});
const response = NextResponse.next();
response.cookies.set('getno_automation_verified', '1', {
httpOnly: false,
secure: true,
sameSite: 'lax',
maxAge: 300,
path: '/',
});
return response;
} catch {
return NextResponse.next();
}
}O frontend pode então ler getno_automation_verified=1 e pular o CAPTCHA apenas naquela sessão curta.
Se a validação falhar, mantenha o comportamento padrão do site. A ausência do header nunca deve bloquear usuários reais.
iss, aud, assinatura, expiração e client.kid.