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.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
event | string | Pflicht | signup, login, offer_click, conversion, cashout oder custom. |
account_id | string | Pflicht | Deine Nutzer-ID, max. 191 Zeichen. Nutze eine nichtssagende ID, keine E-Mail. |
request_id | string | Optional | Aus collect() im Browser. 1 Stunde gültig. Ohne sie haben wir nur Netzwerkdaten. |
ip | string | Optional | Die IP des Nutzers. Nur nötig, wenn du keine request_id hast, zum Beispiel bei Postbacks. |
email | string | Optional | Wird als Hash gespeichert. Erkennt Wegwerf-Domains und E-Mails, die sich mehrere Konten teilen. |
payout_address | string | Optional | PayPal-E-Mail, Wallet oder Konto, auf das das Geld geht. Wird als Hash gespeichert. |
payout_method | string | Optional | Freitext wie paypal, usdt oder giftcard. |
amount | number | Optional | Betrag des Cashouts oder der Conversion. |
currency | string | Optional | Währungscode, zum Beispiel USD. Standard bei Cashouts: USD. |
offer_id | string | Optional | Angebots-ID, für offer_click und conversion. Wird für das Angebotstempo genutzt. |
offer_country | string | Optional | Land, für das das Angebot zahlt (ISO-Code, z. B. US), bei Conversions. Ein Nutzer in einem anderen Land wird markiert. |
geo_country | string | Optional | Deine eigene Geolokalisierung der Nutzer-IP (ISO-Code). Weicht sie von unserer ab, ist die IP wahrscheinlich ein Proxy-Ausgang. |
transaction_id | string | Optional | Transaktions-ID des Netzwerks für eine Conversion. Dient zum Erkennen von Duplikaten. |
offer_name | string | Optional | Angebotstitel, wie deine Nutzer ihn sehen. Wird im Dashboard statt der rohen ID angezeigt. |
click_id | string | Optional | Deine Klick-ID. Sende denselben Wert bei offer_click und bei der Conversion, damit sie verknüpft werden. |
source | string | Optional | Woher das Ereignis kommt, zum Beispiel der Name der Offerwall oder des Netzwerks. |
meta | object | Optional | Bis 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.
scoreliegt zwischen 0 und 100. Gründe werden kombiniert, sodass sich mehrere mittlere Signale summieren, ohne 100 zu überschreiten.reasonslistet jedes ausgelöste Signal auf, das stärkste zuerst, mit Gewicht, Details und einem verständlichen englischen Label, das du direkt anzeigen kannst.device.confidencegibt an, wie eindeutig das Gerät wirkt. Fingerprints lassen sich fälschen, deshalb behaupten wir nie absolute Sicherheit.linked_accountslistet andere Konten auf, die sich Gerät, Auszahlungsadresse oder E-Mail mit diesem Konto teilen.cashoutist 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.
| Entscheidung | Score (Standard) | action in Shadow | action in Enforce | Was tun |
|---|---|---|---|---|
allow | 0-49 | allow | allow | Normal weitermachen. |
review | 50-79 | allow | review | Cashout zurückhalten oder zusätzliche Verifizierung verlangen. Erscheint in deiner Prüfliste. |
block | 80-100 | allow | block | Aktion 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.
| Event | Wann senden | Was es erkennt |
|---|---|---|
signup | Konto erstellt | Multi-Accounts, Bots, VPN-Anmeldungen, Wegwerf-E-Mails |
login | Erfolgreicher Login | Account-Sharing, Länderwechsel, neue Geräte |
offer_click | Nutzer öffnet ein Angebot | Startet die Uhr fürs Angebotstempo |
conversion | Postback von Offerwall oder Netzwerk | Zu schnell abgeschlossene Angebote, doppelte Transaktionen, Conversion-Spitzen |
cashout | Nutzer fordert eine Auszahlung an | Geteilte Auszahlungsadressen, Cashout-Velocity, Cashouts neuer Konten |
custom | Alles andere, was du bewerten willst | Gerä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.
| Code | Bedeutung | Gruppe | Gewicht |
|---|---|---|---|
ip_tor | Tor-Exit-Node | Netzwerk | 60 |
ip_vpn | VPN-Verbindung | Netzwerk | 45 |
ip_datacenter | Rechenzentrums- / Hosting-IP | Netzwerk | 40 |
timezone_mismatch | Browser-Zeitzone passt nicht zum IP-Standort | Netzwerk | 20 |
webrtc_ip_leak | Echte IP in einem anderen Land geleakt | Netzwerk | 30 |
ip_multi_timezone | Gleiche IP mit vielen verschiedenen Zeitzonen (Proxy-Ausgang) | Netzwerk | 50 |
proxy_farm_ip | Mehrere Konten auf einer IP, alle mit derselben ausländischen Uhrzeit (geteilter Proxy) | Netzwerk | 60 |
provider_rotation | Viele Internetanbieter in wenigen Tagen, mit ausländischer Uhrzeit (rotierender Residential-Proxy) | Netzwerk | 45 |
privacy_relay | iCloud Private Relay (Datenschutzfunktion) | Netzwerk | 5 |
proxy_headers | Anfrage kam über einen Proxy | Netzwerk | 20 |
geo_sources_disagree | Geolokalisierungsquellen widersprechen sich | Netzwerk | 45 |
ip_shared_with_accounts | Gleiche IP heute von anderen Konten genutzt | Netzwerk | 25 |
country_changed | Land gewechselt | Netzwerk | 15 |
impossible_travel | Unmögliche Reise: IPs aus zwei weit entfernten Ländern innerhalb weniger Stunden | Netzwerk | 50 |
locale_country_mismatch | Browsersprache aus einem anderen Land | Netzwerk | 30 |
phone_country_mismatch | Telefon aus einem anderen Land als die IP | Netzwerk | 20 |
ip_flagged_on_network | IP auf anderen Websites blockiert | Netzwerk | 25 |
device_shared_with_accounts | Gerät mit anderen Konten geteilt | Gerät | 55 |
automation_detected | Bot oder Automatisierungstool | Gerät | 70 |
auto_clicker | Auto-Clicker auf dem Handy | Gerät | 55 |
scripted_behavior | Seite per Skript bedient | Gerät | 45 |
emulator_or_vm | Emulator oder virtuelle Maschine | Gerät | 45 |
browser_tampering | Manipulierter / gefälschter Browser | Gerät | 35 |
device_rooted | Gerootetes Smartphone | Gerät | 25 |
incognito | Privates Surfen | Gerät | 10 |
device_spoofed | Gefälschtes Handymodell | Gerät | 55 |
emulator_profile | Emulator-Standardprofil | Gerät | 60 |
cloud_phone | Cloud-Handy | Gerät | 60 |
phone_farm_display | Display einer Handyfarm | Gerät | 45 |
device_market_mismatch | China-Handy im Ausland | Gerät | 25 |
storage_cleared_reappeared | Cookies gelöscht und wiedergekommen | Gerät | 15 |
no_device_data | Keine Gerätedaten gesendet | Gerät | 15 |
request_reused | Geräte-Token von anderem Konto wiederverwendet | Gerät | 40 |
device_farm_proxy | Handy-Farm über Residential-Proxys | Gerät | 85 |
device_clones | Geräteklone: ein Telefon, das seine Identität zurücksetzt, um als viele neue Konten in einem Netz aufzutreten | Gerät | 55 |
payout_address_shared | Auszahlungsadresse von anderen Konten genutzt | Konto | 70 |
email_disposable | Wegwerf-E-Mail | Konto | 25 |
email_invalid | E-Mail-Adresse, die keine Mails empfangen kann (keine Mail-Domain) | Konto | 35 |
email_shared | Gleiche E-Mail wie ein anderes Konto | Konto | 50 |
phone_shared | Telefonnummer mit anderen Konten geteilt | Konto | 50 |
phone_voip | VoIP- oder virtuelle Nummer | Konto | 40 |
phone_invalid | Ungültige Telefonnummer | Konto | 30 |
many_devices_per_account | Zu viele Geräte an einem Konto | Konto | 20 |
flagged_on_network | Auf anderen von CashoutGuard geschützten Websites markiert | Konto | 45 |
face_same_person | Gleiches Gesicht wie andere Konten | Konto | 0 |
offer_completed_too_fast | Angebot unmöglich schnell abgeschlossen | Verhalten | 40 |
slow_after_click | Lange nach dem Klick konvertiert | Verhalten | 0 |
conversion_velocity | Zu viele Conversions pro Stunde | Verhalten | 30 |
conversion_without_click | Conversion ohne Klick aus deiner Offerwall | Verhalten | 35 |
click_conversion_country_mismatch | In einem Land geklickt, in einem anderen konvertiert | Verhalten | 30 |
offer_country_mismatch | Angebotsland passt nicht zum Nutzer | Verhalten | 45 |
click_velocity | Zu viele Angebotsklicks in wenigen Minuten | Verhalten | 35 |
earnings_spike | Einnahmen weit über normalem Nutzer | Verhalten | 30 |
source_high_reversals | Quelle mit vielen Rückbuchungen | Verhalten | 45 |
offer_high_reversals | Angebot mit vielen Rückbuchungen | Verhalten | 35 |
duplicate_transaction | Doppelte Transaktions-ID | Verhalten | 60 |
offer_repeated_other_publisher | Dasselbe Angebot schon über einen anderen Publisher erledigt | Verhalten | 85 |
offer_repeated_other_account | Gleiches Angebot schon von einem anderen Konto auf diesem Gerät | Verhalten | 85 |
offer_farm_burst | Farm-Welle: viele neue Konten mit Farm-Geräten bei diesem Angebot binnen Stunden | Verhalten | 30 |
signup_burst | Registrierungswelle: mehrere Konten binnen Sekunden von verschiedenen IPs registriert | Verhalten | 25 |
face_check_required | Gesichtsprüfung erforderlich, noch nicht erfolgt | Verhalten | 0 |
face_check_failed | Gesichtsprüfung nicht bestanden | Verhalten | 0 |
publisher_farm_wave | Farm-Welle seines Publishers: die meisten neuen Konten, die er zu diesem Angebot schickte, kamen von Cloud-Handys oder Emulatoren | Verhalten | 55 |
cashout_velocity | Zu viele Cashouts pro Tag | Verhalten | 30 |
new_account_cashout | Cashout von brandneuem Konto | Verhalten | 20 |
blocklisted | Auf deiner Blocklist | Deine Listen | 100 |
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:
- cashoutguard.php: PHP 7.4+, eine Datei, ohne Composer. Einbinden und fertig.
- composer require cashoutguard/cashoutguard-php: derselbe PHP-Client mit README für Ihren vendor-Ordner.
- npm install @cashoutguard/node: Node 18+, mit TypeScript-Typen.
- cashoutguard-wordpress.zip: WordPress-Plugin: das Browser-Skript auf jeder Seite, bewertete Registrierungen und Logins sowie Hooks für Auszahlungen, Offerwall-Conversions und Stornos.
Fehler und Limits
| HTTP | Body | Bedeutung |
|---|---|---|
| 401 | missing_or_invalid_secret_key | Secret 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". |
| 404 | not_found | Konto nicht gefunden (Konto-Endpoints). |
| 422 | { "message", "errors" } | Ungültiger Body. errors listet jedes Feld auf. |
| 429 | Too Many Requests | Rate-Limit erreicht. Die Server-API erlaubt 3.000 Requests pro Minute und Site. |
| 401 · agent.js | unknown_public_key | Der data-key ist kein öffentlicher Schlüssel einer Seite. Kopieren Sie pk_live_... erneut unter Installation. |
| 403 · agent.js | origin_not_allowed | Die 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. |
| 403 | account_suspended | Das Konto ist gesperrt, meist wegen einer offenen Rechnung. Prüfen Sie die Abrechnung. |
| 503 | temporarily_unavailable | Kurzer 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.