CashoutGuard

Dokumentation

Ein Script im Browser, ein API-Aufruf von deinem Server. Alles, was du für den Livegang brauchst, auf einer Seite.

Schnellstart

Du brauchst deinen Public Key (pk_...) für den Browser und deinen Secret Key (sk_...) für deinen Server. Beide findest du im Dashboard unter Sites und Keys.

1. Script einbinden

Setz diesen Tag auf die Seiten, auf denen Nutzer sich registrieren, einloggen, Angebote klicken oder einen Cashout anfordern. Er initialisiert sich selbst über data-key

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

2. request_id erfassen und an deinen Server senden

Ruf collect() im entscheidenden Moment mit dem Event-Namen auf. Das Ergebnis ist { request_id, visitor_id }

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

collect() wird nie rejected. Bei einem Fehler (blockiert, offline, Timeout) liefert es request_id: null und einen Fehlertext. Schick das Formular trotzdem ab und lass deinen Server entscheiden.

3. Entscheidung von deinem Server abfragen

Sende das Event per POST an /v1/evaluate, mit deinem Secret Key im Header Authorization: Bearer sk_live_...

Pack den Secret Key nie in Browser-Code oder eine mobile App. Nur dein Server darf /v1/evaluate aufrufen.

Evaluate-Request

POST https://cashoutguard.com/v1/evaluate bewertet ein Event für ein Konto, verknüpft es mit Gerät, Netzwerk und Auszahlungsadresse und liefert eine Entscheidung zurück. Sende JSON.

FeldTypPflichtBeschreibung
eventstringPflichtsignup, login, offer_click, conversion, cashout oder custom.
account_idstringPflichtDeine Nutzer-ID, max. 191 Zeichen. Nutze eine nichtssagende ID, keine E-Mail.
request_idstringOptionalAus collect() im Browser. 1 Stunde gültig. Ohne sie haben wir nur Netzwerkdaten.
ipstringOptionalDie IP des Nutzers. Nur nötig, wenn du keine request_id hast, zum Beispiel bei Postbacks.
emailstringOptionalWird als Hash gespeichert. Erkennt Wegwerf-Domains und E-Mails, die sich mehrere Konten teilen.
payout_addressstringOptionalPayPal-E-Mail, Wallet oder Konto, auf das das Geld geht. Wird als Hash gespeichert.
payout_methodstringOptionalFreitext wie paypal, usdt oder giftcard.
amountnumberOptionalBetrag des Cashouts oder der Conversion.
currencystringOptionalWährungscode, zum Beispiel USD. Standard bei Cashouts: USD.
offer_idstringOptionalAngebots-ID, für offer_click und conversion. Wird für das Angebotstempo genutzt.
offer_countrystringOptionalLand, für das das Angebot zahlt (ISO-Code, z. B. US), bei Conversions. Ein Nutzer in einem anderen Land wird markiert.
geo_countrystringOptionalDeine eigene Geolokalisierung der Nutzer-IP (ISO-Code). Weicht sie von unserer ab, ist die IP wahrscheinlich ein Proxy-Ausgang.
transaction_idstringOptionalTransaktions-ID des Netzwerks für eine Conversion. Dient zum Erkennen von Duplikaten.
offer_namestringOptionalAngebotstitel, wie deine Nutzer ihn sehen. Wird im Dashboard statt der rohen ID angezeigt.
click_idstringOptionalDeine Klick-ID. Sende denselben Wert bei offer_click und bei der Conversion, damit sie verknüpft werden.
sourcestringOptionalWoher das Ereignis kommt, zum Beispiel der Name der Offerwall oder des Netzwerks.
metaobjectOptionalBis zu 20 zusätzliche Textfelder, die mit dem Ereignis gespeichert werden (zum Beispiel Sub-IDs).

Response

Die Response hat immer dieselbe Struktur. Felder, die nicht zutreffen, sind null.

  • score liegt zwischen 0 und 100. Gründe werden kombiniert, sodass sich mehrere mittlere Signale summieren, ohne 100 zu überschreiten.
  • reasons listet jedes ausgelöste Signal auf, das stärkste zuerst, mit Gewicht, Details und einem verständlichen englischen Label, das du direkt anzeigen kannst.
  • device.confidence gibt an, wie eindeutig das Gerät wirkt. Fingerprints lassen sich fälschen, deshalb behaupten wir nie absolute Sicherheit.
  • linked_accounts listet andere Konten auf, die sich Gerät, Auszahlungsadresse oder E-Mail mit diesem Konto teilen.
  • cashout ist nur bei cashout-Events gesetzt und zeigt den Status in deiner Prüfliste.

Entscheidungen und Aktionen

Reagiere auf das Feld action, nicht auf decision. Die Schwellenwerte unten sind Standardwerte und lassen sich im Dashboard pro Site ändern.

EntscheidungScore (Standard)action in Shadowaction in EnforceWas tun
allow0-49allowallowNormal weitermachen.
review50-79allowreviewCashout zurückhalten oder zusätzliche Verifizierung verlangen. Erscheint in deiner Prüfliste.
block80-100allowblockAktion stoppen. Guthaben einfrieren oder Anmeldung ablehnen.

Im Shadow-Modus ist action immer allow, du kannst denselben Code also gefahrlos ausliefern, bevor du Enforce aktivierst. Beim Umschalten auf Enforce ändert sich nichts an deinem Code.

Event-Typen

Sende die Events, die du hast. Signup und Cashout sind am wichtigsten; Conversions liefern die Daten für die Prüfung des Angebotstempos.

EventWann sendenWas es erkennt
signupKonto erstelltMulti-Accounts, Bots, VPN-Anmeldungen, Wegwerf-E-Mails
loginErfolgreicher LoginAccount-Sharing, Länderwechsel, neue Geräte
offer_clickNutzer öffnet ein AngebotStartet die Uhr fürs Angebotstempo
conversionPostback von Offerwall oder NetzwerkZu schnell abgeschlossene Angebote, doppelte Transaktionen, Conversion-Spitzen
cashoutNutzer fordert eine Auszahlung anGeteilte Auszahlungsadressen, Cashout-Velocity, Cashouts neuer Konten
customAlles andere, was du bewerten willstGeräte- und Netzwerksignale

Offerwalls und Postbacks

Offerwall-Conversions kommen per Postback, Server zu Server, ohne Browser. CashoutGuard verknüpft jede Conversion mit dem Klick, der sie ausgelöst hat, und bewertet sie mit Gerät und Netzwerk dieses Klicks.

1. Wenn der Nutzer ein Angebot öffnet

Sammle im Browser und sende ein offer_click mit dem Angebot und deiner Klick-ID.

2. Wenn der Postback eintrifft

Sende aus deinem Postback-Handler eine conversion mit derselben account_id und click_id. Eine request_id ist nicht nötig. Gib die IP des Nutzers mit, falls die Offerwall sie liefert.

Conversions werden geprüft auf: zu schnell für das Angebot, Conversion ohne Klick, Klick und Conversion aus verschiedenen Ländern, Einnahmen weit über dem üblichen Tag des Kontos und doppelte Transaktions-IDs.

Offerwall-Netzwerke

Betreibst du ein Netzwerk mit vielen Publishern, sende Konto-IDs mit dem Publisher und aktiviere den "Offerwall-Netzwerk-Modus" unter Websites. Dann werden Konten nur innerhalb desselben Publishers verknüpft, weil es normal ist, dass eine Person mehrere Seiten deiner Publisher nutzt. Format: publisher_id:user_id

Angebotskatalog

POST /v1/offers sendet deine Angebotsnamen (bis zu 1.000 pro Aufruf). Vergangene und künftige Ereignisse zeigen dann den echten Namen, auch wenn sie nur die ID enthalten.

Reason-Codes

Diese Codes erscheinen in reasons[].code. Zeig deinen Moderatoren den Text; nutze den Code in deiner Logik.

CodeBedeutungGruppeGewicht
ip_torTor-Exit-NodeNetzwerk60
ip_vpnVPN-VerbindungNetzwerk45
ip_datacenterRechenzentrums- / Hosting-IPNetzwerk40
timezone_mismatchBrowser-Zeitzone passt nicht zum IP-StandortNetzwerk20
webrtc_ip_leakEchte IP in einem anderen Land geleaktNetzwerk30
ip_multi_timezoneGleiche IP mit vielen verschiedenen Zeitzonen (Proxy-Ausgang)Netzwerk50
proxy_farm_ipMehrere Konten auf einer IP, alle mit derselben ausländischen Uhrzeit (geteilter Proxy)Netzwerk60
provider_rotationViele Internetanbieter in wenigen Tagen, mit ausländischer Uhrzeit (rotierender Residential-Proxy)Netzwerk45
privacy_relayiCloud Private Relay (Datenschutzfunktion)Netzwerk5
proxy_headersAnfrage kam über einen ProxyNetzwerk20
geo_sources_disagreeGeolokalisierungsquellen widersprechen sichNetzwerk45
ip_shared_with_accountsGleiche IP heute von anderen Konten genutztNetzwerk25
country_changedLand gewechseltNetzwerk15
impossible_travelUnmögliche Reise: IPs aus zwei weit entfernten Ländern innerhalb weniger StundenNetzwerk50
locale_country_mismatchBrowsersprache aus einem anderen LandNetzwerk30
phone_country_mismatchTelefon aus einem anderen Land als die IPNetzwerk20
ip_flagged_on_networkIP auf anderen Websites blockiertNetzwerk25
device_shared_with_accountsGerät mit anderen Konten geteiltGerät55
automation_detectedBot oder AutomatisierungstoolGerät70
auto_clickerAuto-Clicker auf dem HandyGerät55
scripted_behaviorSeite per Skript bedientGerät45
emulator_or_vmEmulator oder virtuelle MaschineGerät45
browser_tamperingManipulierter / gefälschter BrowserGerät35
device_rootedGerootetes SmartphoneGerät25
incognitoPrivates SurfenGerät10
device_spoofedGefälschtes HandymodellGerät55
emulator_profileEmulator-StandardprofilGerät60
cloud_phoneCloud-HandyGerät60
phone_farm_displayDisplay einer HandyfarmGerät45
device_market_mismatchChina-Handy im AuslandGerät25
storage_cleared_reappearedCookies gelöscht und wiedergekommenGerät15
no_device_dataKeine Gerätedaten gesendetGerät15
request_reusedGeräte-Token von anderem Konto wiederverwendetGerät40
device_farm_proxyHandy-Farm über Residential-ProxysGerät85
device_clonesGeräteklone: ein Telefon, das seine Identität zurücksetzt, um als viele neue Konten in einem Netz aufzutretenGerät55
payout_address_sharedAuszahlungsadresse von anderen Konten genutztKonto70
email_disposableWegwerf-E-MailKonto25
email_invalidE-Mail-Adresse, die keine Mails empfangen kann (keine Mail-Domain)Konto35
email_sharedGleiche E-Mail wie ein anderes KontoKonto50
phone_sharedTelefonnummer mit anderen Konten geteiltKonto50
phone_voipVoIP- oder virtuelle NummerKonto40
phone_invalidUngültige TelefonnummerKonto30
many_devices_per_accountZu viele Geräte an einem KontoKonto20
flagged_on_networkAuf anderen von CashoutGuard geschützten Websites markiertKonto45
face_same_personGleiches Gesicht wie andere KontenKonto0
offer_completed_too_fastAngebot unmöglich schnell abgeschlossenVerhalten40
slow_after_clickLange nach dem Klick konvertiertVerhalten0
conversion_velocityZu viele Conversions pro StundeVerhalten30
conversion_without_clickConversion ohne Klick aus deiner OfferwallVerhalten35
click_conversion_country_mismatchIn einem Land geklickt, in einem anderen konvertiertVerhalten30
offer_country_mismatchAngebotsland passt nicht zum NutzerVerhalten45
click_velocityZu viele Angebotsklicks in wenigen MinutenVerhalten35
earnings_spikeEinnahmen weit über normalem NutzerVerhalten30
source_high_reversalsQuelle mit vielen RückbuchungenVerhalten45
offer_high_reversalsAngebot mit vielen RückbuchungenVerhalten35
duplicate_transactionDoppelte Transaktions-IDVerhalten60
offer_repeated_other_publisherDasselbe Angebot schon über einen anderen Publisher erledigtVerhalten85
offer_repeated_other_accountGleiches Angebot schon von einem anderen Konto auf diesem GerätVerhalten85
offer_farm_burstFarm-Welle: viele neue Konten mit Farm-Geräten bei diesem Angebot binnen StundenVerhalten30
signup_burstRegistrierungswelle: mehrere Konten binnen Sekunden von verschiedenen IPs registriertVerhalten25
face_check_requiredGesichtsprüfung erforderlich, noch nicht erfolgtVerhalten0
face_check_failedGesichtsprüfung nicht bestandenVerhalten0
publisher_farm_waveFarm-Welle seines Publishers: die meisten neuen Konten, die er zu diesem Angebot schickte, kamen von Cloud-Handys oder EmulatorenVerhalten55
cashout_velocityZu viele Cashouts pro TagVerhalten30
new_account_cashoutCashout von brandneuem KontoVerhalten20
blocklistedAuf deiner BlocklistDeine Listen100

Gewichte werden per Noisy-OR kombiniert: score = 100 x (1 - Produkt von (1 - weight/100)). Zwei Signale mit 40 ergeben 64, nicht 80. Ein Treffer auf der Blocklist ergibt immer 100.

Webhooks

Legen Sie im Dashboard eine Webhook-URL fest. Wir senden einen POST für jedes mit block bewertete Ereignis (event.blocked), wenn ein Konto auf block wechselt (account.blocked) und wenn Ihr Team über eine Auszahlung entscheidet (cashout.decided). Ignorieren Sie Typen, die Sie nicht nutzen.

Jeder Request wird mit deinem Webhook-Secret signiert. Der Hex-HMAC-SHA256 des Raw-Bodys steht im Header X-CashoutGuard-Signature

Antworte mit einem beliebigen 2xx-Status. Fehlgeschlagene Zustellungen werden bis zu 5 Mal wiederholt: nach 10 Sekunden, 1 Minute, 5 Minuten und 15 Minuten.

Kontostatus

GET /v1/accounts/{account_id} liefert die aktuelle Risikoeinschätzung eines Kontos, ohne ein Event anzulegen.

POST /v1/accounts/{account_id}/status erlaubt deinen eigenen Moderationstools, den Status eines Kontos zu ändern.

  • active: Normales Scoring.
  • allowlisted: Scores bleiben unter der Prüfschwelle. Für vertrauenswürdige Nutzer und Mitarbeiter.
  • blocked: Jedes Event liefert block mit Score 100.

Rückbuchungen & Genauigkeit

POST /v1/outcomes meldet, was mit Conversions nach unserer Bewertung passiert ist: vom Offerwall oder Werbetreibenden zurückgebucht (Chargeback) oder als gültig bestätigt. Wir ordnen Ihre IDs zu und messen die Engine auf Ihrem eigenen Traffic auf der Seite Genauigkeit.

Ohne Code: Laden Sie den monatlichen Rückbuchungs-Export Ihrer Offerwalls (CSV oder Excel) auf der Seite Genauigkeit hoch. Die ID-Spalte finden wir automatisch.

PHP, Node.js, Python, Android

Kein SDK nötig. Ein einfacher HTTP-Aufruf mit kurzem Timeout reicht. Komplettes Cashout-Beispiel:

Fehler und Limits

HTTPBodyBedeutung
401missing_or_invalid_secret_keySecret Key fehlt, ist falsch oder widerrufen. Die Antwort nennt den Grund in "reason" (missing, public_key, unknown_secret, placeholder, malformed) und die Lösung in "hint".
404not_foundKonto nicht gefunden (Konto-Endpoints).
422{ "message", "errors" }Ungültiger Body. errors listet jedes Feld auf.
429Too Many RequestsRate-Limit erreicht. Die Server-API erlaubt 3.000 Requests pro Minute und Site.
401 · agent.jsunknown_public_keyDer data-key ist kein öffentlicher Schlüssel einer Seite. Kopieren Sie pk_live_... erneut unter Installation.
403 · agent.jsorigin_not_allowedDie Domain der Seite steht nicht in den erlaubten Origins der Seite. Fügen Sie sie unter Seiten hinzu oder lassen Sie die Liste leer. localhost funktioniert immer. agent.js erklärt das auch in der Browserkonsole. App-WebViews senden die Origin "null": Füge null zur Liste hinzu, um sie zu erlauben. Das native Android-SDK braucht nichts davon.
403account_suspendedDas Konto ist gesperrt, meist wegen einer offenen Rechnung. Prüfen Sie die Abrechnung.
503temporarily_unavailableKurzer Ausfall bei uns. Aktion zulassen und später erneut versuchen.

Fail open: Wenn der Aufruf in einen Timeout läuft oder fehlschlägt, lass die Aktion zu und protokolliere sie. Unser Ausfall darf nie deine Nutzer aufhalten.