Tellby Detect The Bet Docs
Getting started

How it works

The feed is a signed file you pull to a location you control, verify, and query inside your existing authorization flow. Three steps: verify, decide, stay current. It runs entirely in your environment, with no network call and no customer data leaving your walls.

What we deliver

You receive a small folder at a private delivery point you control (a repository or storage bucket): the signed feed, a pointer file that names the current release, a reference client, and a one-line verification script. That is the whole handoff. There is no API to call and no account to log into during authorization.

1

Verify

Check the signature before loading. This proves the feed is authentic and untampered, entirely on your side. If it does not verify, it does not load.

2

Decide

Make one in-process lookup per transaction. It returns block, review, or allow, plus the decision record. No network hop.

3

Stay current

Poll the delivery point on your own schedule. New releases are data, not code, so there is nothing to redeploy.

Step 1: Verify the release

Every release is cryptographically signed. Verify it against a public key you have pinned. The reference client does this automatically before loading, and a standalone script is included so you can check any release by hand.

shell
# verify authenticity + integrity before loading (fails closed)
sh verify/verify.sh feed-current.json
OK: signature valid, feed is authentic and untampered.

Step 2: One lookup per transaction

Inside the authorization step you already run, call decide() with the transaction descriptor. It returns an action and, on a match, the decision record you can log and act on.

python
from dtb_feed_client import FeedRefresher

refresher = FeedRefresher(".")          # loads + verifies the current release once

# in your auth path (cheap, no I/O per call):
feed = refresher.current()
action, record = feed.decide(descriptor=txn.descriptor)

if action == "block":    decline(txn)          # disguised-gambling merchant, high confidence
elif action == "review": route_to_review(txn)   # surface to your queue, do not decline
# else "allow":          not in the feed, do nothing

A match returns a record your compliance team can defend: the merchant, its category, how confident we are, the strength of the evidence, a plain-language reason, and the release version. You map each recommendation to your own policy.

example match
{
  "action":      "block",
  "category":    "sweepstakes casino",
  "confidence":  "observed",
  "reason":      "known disguised-gambling merchant",
  "feed_version": "current"
}

Step 3: Stay current

Wire the refresher once. On your schedule it checks the delivery point, verifies any new release, and hot-swaps it. If a release ever fails verification it is never loaded and the last good feed keeps serving, so a bad update can never enter your authorization path.

python
refresher.poll()   # verifies + hot-swaps if a new release landed. Returns True if updated.
Properties you can rely on. It runs in your environment with no outbound call during authorization. No customer data reaches us. Verification fails closed. New releases are data, so there is nothing to redeploy. Behavioral signals only ever surface an account for review, never an automatic decline.
Not on Python? The feed is plain, signed JSON; you can match against it in any language. The Python client is the reference implementation. Ask us for a port or a thin local sidecar.