Measure and protect
Fraud Prevention
How AdManta handles bot detection, rate limits, IP blocking and GDPR compliance, and which settings protect your advertisers from invalid traffic.
5 protection layers
| # | Layer | Description | Response |
|---|---|---|---|
| 1 | Bot detection (UA) | User-Agent checked against known bot patterns (crawlers, spiders, headless browsers) | Empty ad response, no impression logged |
| 2 | IP blocklist | Known spam and bot IPs, as well as manually blocked IPs | HTTP 403, no ad served |
| 3 | Rate limiting | Maximum requests per IP within two time windows (Redis-based) | HTTP 429, empty response |
| 4 | Click deduplication | Repeat clicks from the same session on the same ad (requires consent cookie) | Redirect, counted as regular click only |
| 5 | Session cap | Zone-specific impression limit per visitor session (requires consent cookie) | Empty ad response (fallback HTML shown if configured) |
Bot detection
The AdServer analyses the User-Agent header of every request.
Detected bots receive an empty response – they are counted neither as an impression nor as a click.
Detected bot categories:
Search engine crawlers
Headless browsers
Web scrapers
Monitoring tools
SEO tools
Curl / Wget
Device type
botin theHourlyTargetingStatsmodel shows how many bot requests were received.
IP blocklist
Automatic
- IPs with > 10 clicks in 60 seconds are temporarily blocked
- Known spam networks (public blocklists)
Manual (via Admin)
- Permanently block individual IPs
- Block IP ranges (CIDR notation)
Rate limiting
Two independent time windows protect against excessive requests from a single IP:
| Window | Limit (default) | Redis key |
|---|---|---|
| 1 minute | 120 requests (ad delivery) · 30 requests (clicks) | rl:{serve |
| 1 hour | 1,000 requests (ad delivery) · 300 requests (clicks) | rl:{serve |
Limits can be adjusted in Django settings (
settings.py):ADSERVER_RATE_LIMIT_MINUTEandADSERVER_RATE_LIMIT_HOUR.
GDPR compliance
What we do NOT store
- Full IP addresses
- Personal data of visitors
- Browser fingerprints
- Cross-site tracking
What we store
- Aggregated impressions/clicks (hourly)
- IP address in short-lived rate-limit counters (Redis, expires within 1 hour); never stored with impressions or clicks
- Session UUID in
seco_cookie (opt-in only)- GeoIP country (aggregated, no link to person)
Basic ad serving (impressions + clicks) works without any cookies. The
seco_cookie is only set after explicit visitor consent and enables unique click tracking and frequency caps.
GeoIP setup
For country targeting stats, GeoIP is used. The system uses the MaxMind GeoLite2 database.
Step 1: Create a free account at maxmind.com and generate a license key.
Step 2:
Download GeoLite2-Country.mmdb and place it in the directory specified by GEOIP_PATH in settings.py.
Step 3: Restart the server. Country stats will appear from the next impression onwards.
Without the GeoIP database, country stats are stored as
XX(unknown). All other functions are unaffected.