Measure and protect
Tracking & Stats
How AdManta counts impressions, clicks and CTR internally, what counts as a valid view, and how consent and ad blockers affect the numbers.
Impression tracking
Every served ad counts as one impression and is stored in the HourlyStats model.
The model aggregates impressions and clicks hourly per ad.
| Field (HourlyStats) | Type | Description |
|---|---|---|
ad |
FK → Ad | Reference to the served ad. |
hour |
DateTime | Hour (rounded to the full hour) in which the events occurred. |
impressions |
Integer | Number of impressions in this hour. |
clicks |
Integer | Total clicks in this hour (all clicks, including repeat clicks). |
unique_clicks |
Integer | Unique clicks – only counted when the visitor has a valid consent cookie and has not clicked this ad before. |
Hourly granularity enables detailed intraday analysis with minimal database growth (max. 24 entries per ad per day).
Click tracking
Clicks are captured differently depending on the ad type:
Image Ad
The image is wrapped in an <a> tag.
The link points to the tracking endpoint /go/cl/{ad_id}/,
which logs the click and then redirects to the click URL.
HTML Ad
All href="https://…" links in the HTML content
are rewritten server-side to pass through the tracking endpoint before redirecting.
Additional clicks on the container (no link) also trigger the tracking endpoint.
Consent cookie (seco_)
The seco_ cookie is an opt-in only cookie
– it is only set when the visitor has explicitly accepted tracking via your consent banner.
Without this cookie, every click counts as a regular click (no unique tracking, no frequency caps, no deduplication).
| Cookie attribute | Value | Description |
|---|---|---|
| Name | seco_ |
Single cookie for all zones. Contains a UUID session identifier. |
| Lifetime | 6 months |
Persists until the visitor withdraws consent or the browser clears cookies. |
| Path | /go/ |
Scoped to the ad-serving path only. |
| SameSite | None (with Secure; Lax on plain http) |
Sent on browser navigations (clicks) even from other origins. Not sent on subresource requests. |
| HttpOnly | Yes |
Not accessible via JavaScript. Contains a UUID, no PII. |
For details on embedding the consent snippets in your cookie banner, see Cookie Consent Integration.
Deduplication
When a visitor has a valid seco_ cookie, the server checks Redis
to determine whether that session has already clicked the same ad. The Redis key pattern:
click:{session_id}:{ad_id} → TTL: 6 months (matches cookie lifetime)
The first click sets the key and increments unique_clicks. Subsequent clicks increment
only clicks. Without a cookie, only clicks is incremented (no deduplication).
Targeting statistics
The HourlyTargetingStats model
stores impressions split by targeting dimensions:
| Dimension | Possible values | Source |
|---|---|---|
device_type |
desktop, mobile, tablet, bot | Parsed from the User-Agent header |
country |
ISO 3166-1 Alpha-2 (e.g. DE, AT, CH) | Via GeoIP lookup (MaxMind) |
hour |
DateTime | Hourly aggregation like HourlyStats |
Targeting stats are visualised in the dashboard device chart and available via CSV export (targeting report).
CTR calculation
The Click-Through Rate (CTR) shows what fraction of impressions led to a click:
CTR (%) = (clicks ÷ impressions) × 100
Example: 150 clicks out of 10,000 impressions
(150 ÷ 10,000) × 100 = 1.50 %
When impressions = 0, CTR = 0 %. The system avoids division by zero.
JSON stats API
Campaign statistics can be queried as JSON (login required):
GET /panel/api/campaign/{id}/stats/?preset=7d
Parameters:
| Parameter | Values | Default |
|---|---|---|
preset |
7d, 30d, today, custom |
7d |
date_from |
YYYY-MM-DD | Only with preset=custom |
date_to |
YYYY-MM-DD | Only with preset=custom |