Platforms win on supply quality and lose on latency. This platform gives DSPs, SSPs and curation desks both sides: batch MFA and quality scoring to clean the supply path offline, and a 102M-domain classified database that enriches every bid request with IAB categories, quality tiers and audience segments as a local lookup — zero API calls inside the bid path.
An OpenRTB request carries a domain, maybe a page URL, and whatever the seller declared about itself. Everything that determines whether the impression is worth buying — what the page is about, whether the site is a real publisher or an arbitrage operation, who its audience is — is absent. Buyers feel this as waste; platforms feel it as churn when buyers' audits find the waste.
The ANA's 2023 transparency study put Made-for-Advertising inventory at roughly 15% of programmatic spend and about 21% of impressions. If your platform passes it through, your buyers are funding arbitrage — and their next audit will name your platform.
The same impression arrives through multiple resellers, and thin-content domains flood the pipe with billions of requests. Without a per-domain quality signal, QPS filtering is guesswork that throws away good supply along with bad.
Bid responses are due in tens of milliseconds. No external classification API can sit in that path — so most platforms bid with no idea what content they are bidding on, and contextual PMPs get built from stale, domain-level guesses.
Buyers now pay premiums for curated, SPO-friendly packages — "verified non-MFA automotive reaching affluent readers." Assembling that package requires category, quality and audience data per domain, at catalog scale.
The architecture is deliberately simple: heavy analysis (crawling, rendering, LLM judgment) happens offline through APIs and database builds; the bid path only ever touches a local key-value store built from those results.
MFA detection scores any URL 0–100 by
combining ad-stack forensics, DOM structure, LLM content-authenticity judgment and public MFA
research flags (Adalytics, NewsGuard). Run it across your sellers.json-derived domain list via
POST /api/mfa/score.php, exclude HIGH and VERY HIGH, and re-score monthly —
MFA domains churn faster than any static blocklist.
The offline database product ships 102M classified domains with IAB categories and quality signals as flat files you load into RocksDB, Aerospike or Redis. Bid-time enrichment becomes a sub-millisecond local lookup — no API call, no timeout risk, no per-QPS cost — and scheduled refreshes keep classifications current.
Content quality scores (clickbait, trust, design, deception) turn QPS filtering into policy: throttle request volume from the bottom tier, prioritize the top. Inspect individual domains with the Quality Score tool and the Ad Placement Analyzer, or review suitability at a glance in the suitability dashboard.
Audience segmentation attaches 1,667+ personas, demographics and purchase intent to domains and pages — the raw material for sellable curated packages. Browse pre-built audience, vertical and traffic cuts of the domain database to assemble deal IDs buyers can verify.
A nightly batch loop scores and refreshes supply; the bid path reads the result locally. Here is the skeleton of both sides.
import requests, csv
API = "https://www.websitecategorizationapi.com/api/mfa/score.php"
with open("scored_supply.csv", "w", newline="") as f:
out = csv.writer(f)
out.writerow(["domain", "mfa_score", "mfa_risk", "flag"])
for domain in open("new_sellers_domains.txt"):
r = requests.post(API, data={
"query": f"https://{domain.strip()}",
"api_key": API_KEY}, timeout=180)
row = r.json()
out.writerow([domain.strip(), row["mfa_score"],
row["mfa_risk"],
row["signals"].get("publicly_flagged_mfa")])
# load scored_supply.csv + the 102M-domain database
# into your local KV store, keyed by domain
# supply_db = RocksDB/Aerospike built from the offline # database + your MFA scores. No network I/O below. def enrich(bid_request): domain = bid_request["site"]["domain"] row = supply_db.get(domain) # sub-ms, in-process if row is None: return route_default(bid_request) if row["mfa_risk"] in ("HIGH", "VERY HIGH"): return None # drop pre-bid bid_request["site"]["cat"] = row["iab_codes"] bid_request["ext"]["quality_tier"] = row["quality_tier"] bid_request["ext"]["audience"] = row["personas"][:3] return bid_request
{
"url": "https://www.wealthydriver.com/cars/10-acuras-that-nailed-affordable-luxury...",
"mfa_score": 78,
"mfa_risk": "HIGH",
"signals": {
"ad_script_count": 4,
"header_bidding_detected": true,
"header_bidding_bidders": 2,
"mfa_skewed_networks": ["Taboola"],
"ad_to_content_ratio": 0.09,
"content_word_count": 1267,
"autoplay_video": true,
"internal_link_count": 74,
"clickbait_score": 0.2,
"trustworthiness_score": 0.7,
"mfa_llm_likelihood": 0.4,
"content_originality": "original",
"publicly_flagged_mfa": "adalytics_2024",
"domain_flag_applied": true,
"consent_management": ["Google Funding Choices"]
},
"ad_technologies_detected": [
"Google Ad Manager / DoubleClick",
"Amazon Publisher Services (TAM)",
"Prebid.js", "Taboola", "Facebook Pixel"
],
"status": 200
}
This is a real, trimmed API response. In a bid request this domain looks like a normal publisher — Prebid, Amazon TAM, a CMP, 1,200-word listicles. The composite score catches it anyway: autoplay video, an MFA-skewed native network, and a public Adalytics 2024 arbitrage flag, all cited in the response so your supply team can defend the exclusion to the seller.
Combining MFA risk and quality scores yields a simple, auditable tiering policy. The thresholds below are the starting point we recommend; every underlying signal is exposed in the API responses, so your policy is defensible in seller disputes and buyer audits alike.
| Tier | Criteria | Bid-path treatment | Commercial use |
|---|---|---|---|
| PREMIUM | MFA CLEAN (0–25), high quality scores | Full QPS, priority routing | Curated deals, contextual PMPs |
| STANDARD | MFA LOW (26–45), acceptable quality | Normal QPS | Open exchange |
| WATCH | MFA MODERATE (46–65) | Throttled QPS, monthly re-score | Open exchange with disclosure |
| EXCLUDED | MFA HIGH/VERY HIGH (66+) or public flag | Dropped pre-bid | None until re-scored clean |
Gate publisher onboarding with MFA and quality scores; re-score the long tail monthly so arbitrage domains never reach buyers under your name.
Enrich requests with IAB categories from the local database to power page-level contextual targeting products — see the contextual targeting use case for the buy-side view.
Use the Technology Detector to see every ad-tech vendor a suspicious seller loads, and technology cuts of the database for fleet-wide analysis.
You should not — and you never need to. Bid-path budgets are tens of milliseconds; that is why the offline database exists. All crawling, rendering and LLM analysis happens on our side ahead of time; you ship the results to a local store and read them in microseconds. The real-time APIs are for the offline loop: onboarding, re-scoring, investigating.
The database is refreshed on a recurring cycle, and delta files keep your local copy in sync without full reloads. For domains that matter most — new sellers, spiking domains, dispute cases — the real-time APIs give you an on-demand fresh classification of the live page, which you can write back into your store immediately.
Verification vendors return pass/fail verdicts; the Adalytics 2024 research documented MFA passing them at scale. Our responses expose every underlying signal — ad-stack composition, content authenticity, public research flags — so platforms can set their own thresholds, explain exclusions to sellers, and package "why this tier" evidence into curated deals.
Send us a sample of your sellers list and get back a scored CSV — MFA risk, quality tier and IAB coverage per domain — the same output the batch loop above produces.
Try the MFA Demo Request a Sample Read the API Docs