Data & architecture

How the scam database is built.

A hybrid of trusted public feeds, commercial APIs, and first-party community reports — unified into a single searchable graph.

Ingestion pipeline

Data flows left to right: raw feeds get normalized, de-duplicated, enriched, then written to the live search index and served through the public API.

1 · Sources
PhishTank
URLhaus
OpenPhish
Google Safe Browsing
Chainabuse API
Cryptoscamdb
BBB Scam Tracker
FTC Sentinel (CSV)
Community reports1st-party
2 · Ingest workers
Scheduled fetcherscron
Webhook receiversapi
Normalizerschema
Deduperhash
Taxonomy mapper28 cats
Raw events queuekafka
3 · Enrichment
WHOIS + DNS lookup
Screenshot capture
Phone → carrier
Wallet → chain scan
Risk scoring (ML)
Moderation queue
4 · Serving
Postgres (source of truth)
OpenSearch index
Redis cache
Public REST API
Website search
Browser extension

Data sources, at a glance

Green = free with attribution. Amber = commercial / licensed. Red = requires scraping or ToS review.

Free

PhishTank

Community-verified phishing URLs, updated hourly. XML/JSON feed.

Free

URLhaus (abuse.ch)

Malicious URL database. Plain text + API. Updated continuously.

Free

OpenPhish (Community)

Live phishing feed. Free tier with 12-hour delay.

Free

Google Safe Browsing

Real-time URL reputation lookups. Free API key required.

Free

Cryptoscamdb

Open-source GitHub database of scam crypto addresses and domains.

Free

Chainabuse (TRM Labs)

Community crypto scam reports. Public API with registration.

Free

FTC Sentinel Data

Aggregated US complaint data, downloadable CSV. Great for stats.

Free

FBI IC3 Reports

Annual PDFs + category definitions. Seed data for the taxonomy.

ScamAdviser API

Domain trust scores. Commercial licensing per lookup volume.

Truecaller / Hiya

Phone reputation data. Commercial partnership needed.

Risk

Reddit r/Scams

Rich anecdotal data — requires Reddit API compliance + attribution.

Risk

Trustpilot 1-stars

Signal-rich but ToS-restricted. Manual-only recommended.

Core database schema

Everything revolves around three tables: entities (what was reported), reports (who said so), and evidence (screenshots, transcripts). A category table holds the 28-item taxonomy.

entities
id uuid
kind enum # url, phone, email, wallet
value text
normalized text
risk_score float
first_seen timestamptz
last_seen timestamptz
report_count int
reports
id uuid
entity_id uuid → entities
category_id text → categories
source enum # community, phishtank…
amount_lost numeric
narrative text
status enum # pending, verified, rejected
submitted_at timestamptz
categories
id text # investment_crypto
group text
name text
short text
examples text[]
loaded from
scam-taxonomy.json

Search flow

What happens when a user pastes something into the homepage search box.

1

Detect & normalize

Classify input as URL / phone / email / wallet. Normalize: lowercase domains, strip protocols, E.164 phone format, checksum wallet addresses.

2

Multi-source lookup (parallel)

Query OpenSearch (community), Redis (cached feeds), Google Safe Browsing, and Chainabuse — all at once. ~250ms budget.

3

Aggregate & score

Merge hits, weight by source confidence, compute a unified risk score 0–100.

4

Render result page

Show risk badge, category, linked community reports, related entities, and a "report this scam" CTA — even if clean, so users can contribute.

🚨 Report a Scam