CashoutGuard

Documentação

Um script no navegador, uma chamada de API do seu servidor. Tudo o que você precisa para entrar no ar, em uma única página.

Início rápido

Você precisa da sua chave pública (pk_...) para o navegador e da sua chave secreta (sk_...) para o servidor. As duas ficam no painel, em Sites e chaves.

1. Adicione o script

Coloque esta tag nas páginas onde os usuários se cadastram, entram, clicam em ofertas ou pedem um saque. Ele se inicializa sozinho a partir de data-key

<script src="https://cashoutguard.com/v1/agent.js" data-key="pk_live_YOUR_PUBLIC_KEY" async></script>

2. Colete e envie o request_id ao seu servidor

Chame collect() no momento que importa, com o nome do evento. Ele resolve para { request_id, visitor_id }

const { request_id } = await CashoutGuard.collect({ event: 'cashout' });

collect() nunca rejeita. Em caso de falha (bloqueio, offline, timeout) ele resolve com request_id: null e uma string de erro. Envie o formulário mesmo assim e deixe o seu servidor decidir.

3. Peça uma decisão a partir do seu servidor

Faça POST do evento para /v1/evaluate com a sua chave secreta no header Authorization: Bearer sk_live_...

Nunca coloque a chave secreta em código de navegador ou em um app mobile. Só o seu servidor deve chamar /v1/evaluate.

Requisição evaluate

POST https://cashoutguard.com/v1/evaluate pontua um evento de uma conta, vincula esse evento ao dispositivo, à rede e ao endereço de pagamento, e retorna uma decisão. Envie JSON.

CampoTipoObrigatórioDescrição
eventstringObrigatóriosignup, login, offer_click, conversion, cashout ou custom.
account_idstringObrigatórioO ID do seu usuário, até 191 caracteres. Use um ID opaco, não um e-mail.
request_idstringOpcionalVem do collect() no navegador. Válido por 1 hora. Sem ele, só temos os dados de rede.
ipstringOpcionalO IP do usuário. Só é necessário quando você não tem um request_id, por exemplo em postbacks.
emailstringOpcionalArmazenado como hash. Detecta domínios descartáveis e e-mails compartilhados entre contas.
payout_addressstringOpcionalE-mail do PayPal, carteira ou conta que recebe o dinheiro. Armazenado como hash.
payout_methodstringOpcionalTexto livre, como paypal, usdt ou giftcard.
amountnumberOpcionalValor do saque ou da conversão.
currencystringOpcionalCódigo da moeda, por exemplo USD. Padrão USD para saques.
offer_idstringOpcionalID da oferta, para offer_click e conversion. Usado na velocidade de ofertas.
offer_countrystringOpcionalPaís pelo qual a oferta paga (código ISO, ex. US), em conversões. Um usuário em outro país é marcado.
geo_countrystringOpcionalSua própria geolocalização do IP do usuário (código ISO). Se divergir da nossa, o IP provavelmente é uma saída de proxy.
transaction_idstringOpcionalID de transação da rede para uma conversão. Usado para pegar duplicatas.
offer_namestringOpcionalTítulo da oferta como seus usuários o veem. Aparece em todo o painel no lugar do id.
click_idstringOpcionalSeu id de clique. Envie o mesmo valor no offer_click e na conversão para vinculá-los.
sourcestringOpcionalDe onde veio o evento, por exemplo o nome da offerwall ou da rede.
metaobjectOpcionalAté 20 campos de texto extras salvos com o evento (por exemplo sub ids).

Resposta

A resposta tem sempre o mesmo formato. Campos que não se aplicam vêm como null.

  • score vai de 0 a 100. Os motivos são combinados para que vários sinais médios somem sem passar de 100.
  • reasons lista cada sinal disparado, do mais forte para o mais fraco, com seu peso, detalhes e um rótulo em inglês simples que você pode mostrar como está.
  • device.confidence indica o quão único o dispositivo parece. Fingerprints podem ser falsificados, então nunca afirmamos certeza.
  • linked_accounts lista outras contas que compartilham dispositivo, endereço de pagamento ou e-mail com esta.
  • cashout só vem preenchido em eventos de cashout e informa o status na sua fila de revisão.

Decisões e ações

Aja com base no campo action, não em decision. Os limites abaixo são os padrões e podem ser alterados por site no painel.

DecisãoPontuação (padrão)action no modo sombraaction no modo ativoO que fazer
allow0-49allowallowSiga normalmente.
review50-79allowreviewRetenha o saque ou peça uma verificação extra. Ele aparece na sua fila de revisão.
block80-100allowblockInterrompa a ação. Congele o saldo ou recuse o cadastro.

No modo sombra o action é sempre allow, então o mesmo código pode ir para produção com segurança antes de você começar a bloquear. Quando mudar para o modo ativo, nada no seu código muda.

Tipos de evento

Envie os eventos que você tiver. Cadastro e saque são os mais importantes; as conversões alimentam as checagens de velocidade de ofertas.

EventoQuando enviarO que detecta
signupConta criadaMulticontas, bots, cadastros com VPN, e-mails descartáveis
loginLogin bem-sucedidoCompartilhamento de conta, mudanças de país, dispositivos novos
offer_clickUsuário abre uma ofertaInicia o cronômetro da velocidade de ofertas
conversionPostback do offerwall ou da redeOfertas concluídas rápido demais, transações duplicadas, picos de conversão
cashoutUsuário pede um saqueEndereços de pagamento compartilhados, velocidade de saques, saques de contas novas
customQualquer outra coisa que você queira pontuarSinais de dispositivo e de rede

Offerwalls e postbacks

As conversões de offerwall chegam por postback, de servidor para servidor, sem navegador. O CashoutGuard vincula cada conversão ao clique que a iniciou, então ela é avaliada com o dispositivo e a rede desse clique.

1. Quando o usuário abre uma oferta

Colete no navegador e envie um offer_click com a oferta e seu id de clique.

2. Quando o postback chega

Envie uma conversion do seu handler de postback com o mesmo account_id e click_id. Não precisa de request_id. Envie o IP do usuário se a offerwall fornecer.

As conversões são verificadas para: concluída rápido demais para a oferta, conversão sem clique, clique e conversão de países diferentes, ganhos muito acima do dia normal da conta e ids de transação duplicados.

Redes de offerwall

Se você opera uma rede com muitos publishers, envie ids de conta que incluam o publisher e ative o "Modo rede de offerwall" em Sites. Assim as contas só são vinculadas dentro do mesmo publisher, porque é normal uma pessoa usar vários sites dos seus publishers. Formato: publisher_id:user_id

Catálogo de ofertas

POST /v1/offers envia os nomes das suas ofertas (até 1.000 por chamada). Eventos passados e futuros mostram o nome real mesmo quando trazem só o id.

Códigos de motivo

Estes códigos aparecem em reasons[].code. Mostre o texto aos seus moderadores; use o código na sua lógica.

CódigoSignificadoGrupoPeso
ip_torNó de saída TorRede60
ip_vpnConexão VPNRede45
ip_datacenterIP de datacenter / hospedagemRede40
timezone_mismatchFuso horário do navegador não bate com a localização do IPRede20
webrtc_ip_leakIP real vazou em outro paísRede30
ip_multi_timezoneMesmo IP com muitos fusos horários diferentes (saída de proxy)Rede50
proxy_farm_ipVárias contas num IP, todas com o mesmo relógio estrangeiro (proxy partilhado)Rede60
provider_rotationMuitos fornecedores de internet em poucos dias, com relógio estrangeiro (proxy residencial rotativo)Rede45
privacy_relayiCloud Private Relay (recurso de privacidade)Rede5
proxy_headersA requisição veio por um proxyRede20
geo_sources_disagreeAs fontes de geolocalização divergemRede45
ip_shared_with_accountsMesmo IP usado por outras contas hojeRede25
country_changedPaís mudouRede15
impossible_travelViagem impossível: IPs de dois países distantes em poucas horasRede50
locale_country_mismatchIdioma do navegador de outro paísRede30
phone_country_mismatchTelefone de outro país que o IPRede20
ip_flagged_on_networkIP bloqueado em outros sitesRede25
device_shared_with_accountsDispositivo compartilhado com outras contasDispositivo55
automation_detectedBot ou ferramenta de automaçãoDispositivo70
auto_clickerAuto-clicker no celularDispositivo55
scripted_behaviorUso da página por scriptDispositivo45
emulator_or_vmEmulador ou máquina virtualDispositivo45
browser_tamperingNavegador adulterado / falsificadoDispositivo35
device_rootedCelular com rootDispositivo25
incognitoNavegação anônimaDispositivo10
device_spoofedModelo de celular falsoDispositivo55
emulator_profilePerfil padrão de emuladorDispositivo60
cloud_phoneCelular na nuvemDispositivo60
phone_farm_displayTela de fazenda de celularesDispositivo45
device_market_mismatchCelular só da China no exteriorDispositivo25
storage_cleared_reappearedLimpou os cookies e voltouDispositivo15
no_device_dataNenhum dado do dispositivo enviadoDispositivo15
request_reusedToken do dispositivo reutilizado por outra contaDispositivo40
device_farm_proxyFazenda de celulares com proxies residenciaisDispositivo85
device_clonesClones de dispositivo: um telefone que reinicia sua identidade para se passar por muitas contas novas numa redeDispositivo55
payout_address_sharedEndereço de pagamento usado por outras contasConta70
email_disposableE-mail descartávelConta25
email_invalidE-mail que não pode receber mensagens (domínio de e-mail inexistente)Conta35
email_sharedMesmo e-mail de outra contaConta50
phone_sharedTelefone compartilhado com outras contasConta50
phone_voipTelefone VoIP ou virtualConta40
phone_invalidTelefone inválidoConta30
many_devices_per_accountDispositivos demais em uma só contaConta20
flagged_on_networkMarcado em outros sites protegidos pelo CashoutGuardConta45
face_same_personMesmo rosto que outras contasConta0
offer_completed_too_fastOferta concluída rápido demais para ser realComportamento40
slow_after_clickConverteu muito depois do cliqueComportamento0
conversion_velocityConversões demais por horaComportamento30
conversion_without_clickConversão sem clique na sua offerwallComportamento35
click_conversion_country_mismatchClique em um país, conversão em outroComportamento30
offer_country_mismatchO país da oferta difere do usuárioComportamento45
click_velocityCliques demais em ofertas em poucos minutosComportamento35
earnings_spikeGanhos muito acima de um usuário normalComportamento30
source_high_reversalsFonte com muitos estornosComportamento45
offer_high_reversalsOferta com muitos estornosComportamento35
duplicate_transactionID de transação duplicadoComportamento60
offer_repeated_other_publisherMesma oferta já feita por outro publisherComportamento85
offer_repeated_other_accountMesma oferta já feita por outra conta neste aparelhoComportamento85
offer_farm_burstVaga de quinta: muitas contas novas com dispositivos de quinta nesta oferta em poucas horasComportamento30
signup_burstRajada de cadastros: várias contas cadastradas com segundos de diferença a partir de IPs diferentesComportamento25
face_check_requiredFalta a verificação facialComportamento0
face_check_failedVerificação facial reprovadaComportamento0
publisher_farm_waveVaga de quinta do seu publisher: a maioria das contas novas que enviou para esta oferta vinha de telemóveis na nuvem ou emuladoresComportamento55
cashout_velocitySaques demais por diaComportamento30
new_account_cashoutSaque de uma conta recém-criadaComportamento20
blocklistedNa sua lista de bloqueioSuas listas100

Os pesos são combinados com um noisy-OR: score = 100 x (1 - produto de (1 - weight/100)). Dois sinais de 40 dão 64, não 80. Uma ocorrência na lista de bloqueio sempre dá 100.

Webhooks

Defina um URL de webhook no painel. Enviamos um POST por cada evento classificado como block (event.blocked), quando uma conta passa a block (account.blocked) e quando a sua equipa decide um levantamento (cashout.decided). Ignore os tipos que não usa.

Cada requisição é assinada com o seu segredo de webhook. O HMAC-SHA256 em hex do corpo bruto vem no header X-CashoutGuard-Signature

Responda com qualquer status 2xx. Entregas com falha são tentadas de novo até 5 vezes: após 10 segundos, 1 minuto, 5 minutos e 15 minutos.

Status da conta

GET /v1/accounts/{account_id} retorna a visão de risco atual de uma conta sem criar um evento.

POST /v1/accounts/{account_id}/status permite que as suas próprias ferramentas de moderação mudem o status de uma conta.

  • active: Pontuação normal.
  • allowlisted: As pontuações ficam limitadas abaixo do limite de revisão. Para usuários de confiança e para a equipe.
  • blocked: Todo evento retorna block com pontuação 100.

Estornos e precisão

POST /v1/outcomes informa o que aconteceu com as conversões depois de pontuadas: estornadas pelo offerwall ou anunciante (chargeback) ou confirmadas como válidas. Cruzamos seus ids com as conversões e medimos o motor no seu próprio tráfego na página Precisão.

Sem código: envie na página Precisão o export mensal de estornos dos seus offerwalls (CSV ou Excel). Encontramos a coluna de ids automaticamente.

PHP, Node.js, Python, Android

Não precisa de SDK. Uma chamada HTTP simples com timeout curto basta. Exemplo completo de saque:

Erros e limites

HTTPCorpoSignificado
401missing_or_invalid_secret_keyChave secreta ausente, errada ou revogada. A resposta diz o motivo em "reason" (missing, public_key, unknown_secret, placeholder, malformed) e como corrigir em "hint".
404not_foundConta não encontrada (endpoints de conta).
422{ "message", "errors" }Corpo inválido. errors lista cada campo.
429Too Many RequestsLimite de requisições atingido. A API do servidor permite 3.000 requisições por minuto por site.
401 · agent.jsunknown_public_keyO data-key não é a chave pública de nenhum site. Copie de novo o pk_live_... em Instalação.
403 · agent.jsorigin_not_allowedO domínio da página não está nas origens permitidas do site. Adicione em Sites ou deixe a lista vazia. localhost sempre funciona. O agent.js também explica isso no console do navegador. WebViews de apps enviam a origem "null": adicione null à lista para aceitá-los. O SDK nativo de Android não precisa de nada.
403account_suspendedA conta está suspensa, normalmente por fatura não paga. Veja Faturamento.
503temporarily_unavailableFalha breve do nosso lado. Deixe a ação passar e tente de novo depois.

Fail open: se a chamada der timeout ou erro, permita a ação e registre. Nunca deixe uma queda nossa travar os seus usuários.