GateBehaviour — rules on the funding lifecycle
Deterministic, explainable rules on deposits, trading and withdrawals — the data only a broker has.
On this page
What it does
On-chain data cannot tell you that a client deposited, traded nothing, and asked to withdraw to a different wallet 20 hours later. Your ledger can. GateBehaviour takes deposits, withdrawal requests and trading summaries as events and runs deterministic rules on the lifecycle of each customer.
The rules: pass-through (withdrawal soon after deposits with little trading), withdrawal to a wallet never used for deposits, structuring (several sub-threshold deposits in 24 hours), wallet churn, large first deposit, withdrawal requested while a case on the customer is still open, an address previously rejected or revoked for another customer of yours reappearing under a new name, dormant account reactivated, a registered wallet shared between customers, and network links via device, IP or bank reference.
The fiat side joins the same timeline: card and bank PSP events (fiat_deposit, fiat_withdrawal, chargeback, card_declined, payment_method_added, name_mismatch) feed rules for crypto-in / fiat-out arbitrage and its mirror, chargeback history, card-decline bursts, payment-instrument churn, payer-name mismatches and a card or IBAN token shared between customers. KYTGate never receives card numbers or payer names — only hashed instrument tokens and a name-match boolean.
Thresholds are per tenant, and every fired rule states the numbers it saw, so a reviewer can disagree with it.
Why a broker needs it
Exchanges see a wallet once and can afford to think in terms of the wallet. A broker sees a customer over months — a KYC profile, a declared income, an expected trading pattern, a set of funding wallets, and eventually a withdrawal request. The risk is rarely in the first deposit; it is in the shape of the whole lifecycle: fund, barely trade, withdraw elsewhere.
Supervisors expect that shape to be watched. Most screening products stop at a wallet score and leave the lifecycle question to be answered by hand at examination time.
How it works
Send your ledger's funding events to /api/v1/events — deposit, withdrawal_request, withdrawal_paid, trade_summary — keyed by customerRef and idempotent on eventRef. Screenings that carry customerRef and amountUsd with trigger deposit or pre_withdrawal record their own event automatically.
Each rule emits a signal with a fixed severity (pass-through 65, foreign-wallet withdrawal 55, structuring 60, wallet churn 50, large first deposit 45, withdrawal with open case 70, returning rejected wallet 65, dormant reactivation 50, shared registered wallet 70, network link 50–60). Under the baseline policy a behaviour signal of 60 or more routes the decision to REVIEW. The coverage dimension customerBehaviour is COMPLETE only when a customerRef was given.
Five windowed rules compare the customer with their own history rather than with a fixed number. Velocity to new wallets (65): $10,000 or more withdrawn within 7 days to wallets that never appeared in the customer's history before. Deposit frequency spike (55): deposits in the last 7 days at 3× or more the customer's 90-day weekly rate, with a floor of 2 per week and at least 30 days of history. Amount spike (60): a deposit at 5× or more the customer's median deposit over the prior 90 days, once at least 5 deposits exist. Round-tripping (60): a deposit from address A and a withdrawal back to A within 72 hours for 80% or more of the amount, with trading below the minimum traded ratio in between. Third-party funding (55): deposits in 30 days from 4 or more distinct sender addresses that are not the customer's registered wallets. Every fired signal states the window, the baseline and the numbers it compared.
Fiat rules: crypto-in-fiat-out (65) — crypto deposits of $2,000 or more in 30 days followed by a fiat withdrawal with trading below the minimum traded ratio — and fiat-in-crypto-out (65) on a crypto withdrawal; chargeback-history (60, 1 or more in 180 days); card-decline-burst (55, 3 or more 3DS / AVS / CVV failures in 24 hours); payment-instrument-churn (55, 3 or more distinct tokens added in 30 days); name-mismatch-funding (60, any fiat deposit whose payer name did not match KYC in 90 days); shared-instrument (70, the same card or IBAN token behind another of your customers). A fiat event has no address to screen, so it is evaluated the moment it is recorded: the events response carries the signals and open cases on the customer are annotated; the same rules run again inside the next crypto screening.
What it does not do
Behaviour rules never block on their own — they route to a human. They see only the events you send: a customer whose deposits you do not report has no lifecycle to evaluate, and the coverage matrix says so. Nothing here is a model or a score; a rule either fired with its numbers or it did not.
API
POST /api/v1/events
{
"kind": "withdrawal_request", // deposit | withdrawal_request | withdrawal_paid | trade_summary
"customerRef": "cust-8812",
"eventRef": "wd-55031", // idempotent
"amountUsd": 24000,
"chain": "tron", "address": "T…",
"meta": { "ip": "…", "deviceId": "…" } // optional network-link attributes
}
POST /api/v1/events // fiat leg: evaluated at once, signals in the response
{
"kind": "fiat_withdrawal", // fiat_deposit | fiat_withdrawal | chargeback | card_declined | payment_method_added | name_mismatch
"customerRef": "cust-8812", "eventRef": "payout-7710", "amountUsd": 23500,
"meta": { "method": "bank", "instrumentRef": "sha256(iban)…", "nameMatch": true, "country": "GB" } // tokens and booleans only — never a PAN or a name
}Full reference: /docs#events · OpenAPI 3.1