GateCoverage: coverage matrix per decision
Nine coverage dimensions per decision, each with its own status instead of a single score.
Start free sandboxTalk to us50 screenings a month free, no card.
On this page
GateCoverage in simple terms
When a deposit is checked, GateCoverage writes down which checks ran and which could not. Instead of a single grade like "87 out of 100", you get a list: sanctions checked, issuer freeze checked, transaction checked, wallet ownership not proven yet.
Anything that could not be checked stays visible as a gap. It is never counted as "fine".
IN EVERYDAY TERMSThink of a car inspection sheet with one line per item: brakes checked, lights checked, engine could not be inspected. A single "passed" stamp would hide the engine.
What it does
GateCoverage records what each screening checked. Sanctions matching runs against OFAC, the UK Sanctions List and the EU consolidated list. The lists are re-synced at least every 6 hours and content-hashed, so each decision records which snapshot it saw. Stablecoin issuer freezes are read live from the Tether and Circle contracts on seven networks. The transaction integrity check confirms that the hash exists, succeeded, is confirmed and carries a canonical USDT/USDC transfer. It also resolves the real sender.
Each of those checks reports its own status on the response and in the receipt. So do the others: processor evidence, wallet ownership, customer behaviour, travel rule, actor attribution and source-of-funds exposure. "No known match" does not mean "clean". A dimension we cannot cover reports NOT_AVAILABLE or MISSING. Wallet ownership, for example, is COMPLETE only with a real proof: an EIP-191 signature, or a micro-transfer of an exact amount from the wallet. The transfer is checked on Blockscout where the chain has one, and by an eth_getLogs scan of the public RPC where it does not (Avalanche). A declaration alone gives PARTIAL.
Sanctions screening covers every network KYTGate recognises, because a list match is an address comparison and an EVM address is the same on every EVM chain. The node-dependent checks, transaction integrity and issuer-freeze reads, cover fewer networks. The list for each check is published at /networks. A headline number here would go out of date as soon as another chain was switched on.
Why a broker needs it
When a supervisor asks "did you screen this deposit?", a single score cannot answer the follow-up questions: against which lists, on which date, and what about the parts you could not check. A per-dimension matrix stored with the decision can.
The matrix also keeps reliance on third parties visible. Your processor's "approved" is recorded as a status. Only an evidence reference makes processorEvidence COMPLETE and raises the assurance tier. Without one, the gap shows in your own record instead of being covered by someone else's approval.
How it works
Every screening returns three separate things: assessment (what the data says: ADVERSE_SIGNAL, NO_ADVERSE_SIGNAL, INCONCLUSIVE or PROVIDER_ERROR), coverage (which checks ran, per dimension: COMPLETE, PARTIAL, MISSING, STALE or NOT_AVAILABLE) and decision (what your policy concluded from both). The matrix is embedded in the signed Decision Receipt and printed on every evidence pack.
The policy's mandatory-coverage rule reads the matrix: if a mandatory dimension is MISSING or STALE (for example, the RPC did not answer or the newest OFAC snapshot is older than your limit), the decision is TECHNICAL_HOLD, never a silent pass. The assurance tier (PUBLIC_BASELINE, PROCESSOR_ATTESTED, COMMERCIAL_ENRICHED, DUAL_SOURCE_ASSURED) is computed from the same matrix.
Try it without an account: Free wallet sanctions check · USDT blacklist check · USDC blacklist check.
What it does not do
GateCoverage does not rate risk and does not clear anyone. Sanctions lists cover a small fraction of illicit addresses, so NO_ADVERSE_SIGNAL means only that nothing adverse was found on the sources that ran. Commercial attribution (mixer exposure, cluster labels) is a dimension that stays MISSING until a provider fills it; we do not fabricate it from public data.
API
{
"assessment": "NO_ADVERSE_SIGNAL", // not "clean": nothing found on the sources that ran
"coverage": {
"sanctions": "COMPLETE", "issuerFreeze": "COMPLETE", "transactionIntegrity": "COMPLETE",
"processorEvidence": "MISSING", "walletOwnership": "MISSING", "customerBehaviour": "MISSING",
"travelRule": "MISSING", "actorAttribution": "NOT_AVAILABLE", "sourceOfFundsExposure": "NOT_AVAILABLE"
},
"assuranceTier": "PUBLIC_BASELINE",
"decision": "REVIEW"
}Full reference: /docs#semantics · OpenAPI 3.1