---
title: "Scan Analytics"
description: "What only a resolver can know — anonymous scan statistics, demand insights, and a live privacy report that shows exactly what is and is not collected."
canonical_url: "https://openepcis.io/docs/digital-data-management/scan-analytics"
last_updated: "2026-08-26T20:11:06.872Z"
---

## What this is — and is not

Once your products resolve through the resolver, every scan passes through a system you operate — and that vantage point can answer questions nothing else can: *Is anyone scanning at all? Where? Which products? What are they looking for that we don't offer?*

The same vantage point could obviously be abused, which is why Scan Analytics is built on a firm refusal: it derives statistics from the **structure** of scans — which identifier, which level, which link type, which country, which day — and never from the **people** scanning. No IP addresses are stored, no user identifiers, no fingerprints; small groups are suppressed so that no combination of filters can single out a person. And rather than asking you to take that on faith, the page carries a [privacy report](#the-privacy-report) that proves it from the live configuration.

The page requires the realm `admin` role.

## Choosing what to look at

The time-window picker covers 24 hours to 90 days plus a custom range, and **auto-refresh** keeps the page live — useful on a wall screen during a campaign. By default the statistics are tenant-wide; to zoom into one product, paste a Digital Link (URL or AI path, e.g. `01/09521000551015`) into the inspector. A bare GTIN works too — the page interprets it and says so. **Open in catalog** jumps from a key to its record when a number needs a name.

## Overview

![The scan analytics overview | Figure 1: KPIs and the scans-over-time chart with previous-period comparison](/img/13.Digital-Data-Management/scans-overview.png)

Four KPI tiles summarize the window: **total scans**, **unique scanners**, **bot share** and **aggregator share** — the latter two because raw scan counts flatter: crawlers and data aggregators scan too, and knowing their share keeps the human number honest. Each tile carries the change against the previous period.

The **unique scanners** figure deserves its footnote, which the page always displays: it is an *estimate*. Counting true uniques would require remembering who scanned — exactly what this system refuses to do. Instead it uses a probabilistic sketch (HyperLogLog) whose daily salt is thrown away, and labels the result with its method and error margin. An estimate honestly labelled beats a precise number obtained by surveillance.

Below, **Scans over time** draws the window's series with the previous period dashed behind it — a campaign bump or a weekend rhythm is visible at a glance, and clicking a point zooms the window to that bucket. Then the breakdowns:

![The overview breakdowns | Figure 2: By granularity, country, device class, status, linkType — and the top keys with their catalog names](/img/13.Digital-Data-Management/scans-breakdowns.png)

**By granularity** splits scans into model, batch and item level — the difference between someone researching the product and someone holding one in their hand. **By country** and **by device class** locate the audience. **By HTTP status** is quiet quality control: a cluster of 404s means codes are in circulation that the resolver cannot answer. **By linkType** shows which destinations scanners actually request, and **Top keys** names the most-scanned products — resolved to their catalog names, so the list reads as products, not digits.

Where k-anonymity suppresses or truncates a breakdown, the page says so explicitly. A list that is quietly incomplete would be worse than no list.

## Insights

The **Insights** tab does the interpretation the overview leaves to you — each insight is a question turned into a list:

![The Insights tab | Figure 3: Unresolved keys and granularity misses — demand the catalog does not serve yet](/img/13.Digital-Data-Management/scans-insights.png)

*Which codes circulate that we never registered?* — **Unresolved keys**. *Are people scanning items where we only serve the model?* — **Granularity misses**, a direct pointer to missing serialized content. *What do scanners ask for that no link provides?* — **LinkType demand**, essentially a feature-request channel wired into the resolver. *Which languages do scanners speak that our content doesn't?* — **Language gaps**. *When does scanning happen?* — the **scan rhythm** heatmap by weekday and hour. *Is one serial number showing up in implausibly many places?* — **Clone suspects**, a counterfeit signal with adjustable thresholds. And **asset rotation** reads repeat scans of returnable assets as cycle data.

## The privacy report

The third tab is addressed to your data-protection officer as much as to you. It documents, **read live from the running configuration** rather than from a policy document, what the analytics pipeline collects and what it refuses to collect:

![The privacy report | Figure 4: Capture settings, schema guard, k-anonymity, uniques method, retention and access-log compliance — read live](/img/13.Digital-Data-Management/scans-privacy.png)

It walks through the capture settings (which Application Identifiers are stored, whether serials and countries are among them, and that service-relation numbers — GSRN, which can identify individuals — are never captured); the **schema guard**, which checks every stored field name against forbidden stems like `ip`, `user`, `session`, `cookie` and shows its verdict; the **k-anonymity** threshold and which breakdowns it gates; the uniques machinery described above, including the memory-only, daily-rotated salt that makes yesterday's scanner and today's unjoinable; and finally retention policies, operational limits and whether the web server's access-log pattern contains client IPs.

The tab exists so that the answer to *"what do you actually store?"* is a screenshot of the running system, not a promise in a PDF.
