Aggregations-API
GET /v1/codes/:id/scans — časové řady + top země/zařízení/OS pro jeden objekt kódu.
Každé naskenování dynamického QR kódu vytvoří v tvém workspace záznam o skenu (Scan-Record). Sběr dat probíhá kompletně na Cloudflare Edge — bez externích sledovacích služeb, bez cookies a bez toho, aby původní IP adresa vůbec kdy dorazila do tvé databáze.
Tři způsoby, jak konzumovat data o skenech:
Aggregations-API
GET /v1/codes/:id/scans — časové řady + top země/zařízení/OS pro jeden objekt kódu.
Webhooks (Echtzeit)
qr.scanned-event na sken, podepsaný pomocí HMAC-SHA256. Viz Webhooky.
Dashboard
Vizualizace v dashboardu qr3.app — není nutné žádné volání API.
Pro každý sken se vytvoří záznam v tabulce scans:
| Pole | Zdroj | Příklad |
|---|---|---|
id | UUID generované serverem | scn_d1f8… |
code_id | ID naskenovaného QR kódu | qr_a1b2c3d4 |
workspace_id | Workspace daného kódu | ws_xxx |
country | Cloudflare cf.country | AT |
region | Cloudflare cf.region | Vienna |
city | Cloudflare cf.city | Wien |
device_type | Parsování User-Agenta | mobile, tablet, desktop |
os | Parsování User-Agenta | iOS, Android, macOS, Windows |
browser | Parsování User-Agenta | Safari, Chrome, Firefox |
referer | HTTP hlavička Referer | https://example.com/landing |
language | Hlavička Accept-Language (první jazyk) | de |
redirected_to | Skutečný cíl přesměrování | https://example.com |
ip_hash | SHA-256(IP + denní salt) — nevratný | 8f3a… |
scanned_at | Časové razítko ISO-8601 | 2026-05-12T14:32:11.000Z |
Všechna geodata (country, region, city) pocházejí z objektu cf od Cloudflare a jsou založena na databázi Geo-IP od Cloudflare. Nedotazují se žádné externí Geo-IP služby — překlad probíhá ve stejném Workeru, který provádí i přesměrování.
To má tři důsledky:
city není vždy k dispozici (např. u VPN, mobilních operátorů nebo malých regionů). Počítej s hodnotami null a zohledni je ve svých dashboardech.GET /v1/codes/:id/scansVrací agregovanou analytiku pro jeden QR kód za zvolené časové období.
curl "https://qr3.app/v1/codes/qr_a1b2c3d4/scans?days=30" \ -H "Authorization: Bearer qr3_sk_..."const analytics = await qr3.scans.get('qr_a1b2c3d4', { days: 30 });console.log(analytics.period_scans, analytics.top_countries);qr3 scans qr_a1b2c3d4 --days 30Query parametry:
| Parametr | Typ | Výchozí | Popis |
|---|---|---|---|
days | integer | 30 | Časové období ve dnech (1–365) |
Odezva (HTTP 200):
{ "data": { "code_id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "total_scans": 1842, "period_days": 30, "period_scans": 367, "scans_by_day": [ { "date": "2026-04-13", "count": 12 }, { "date": "2026-04-14", "count": 18 } ], "top_countries": [ { "value": "AT", "count": 142 }, { "value": "DE", "count": 98 }, { "value": "CH", "count": 41 } ], "top_devices": [ { "value": "mobile", "count": 281 }, { "value": "desktop", "count": 72 }, { "value": "tablet", "count": 14 } ], "top_os": [ { "value": "iOS", "count": 158 }, { "value": "Android", "count": 123 }, { "value": "macOS", "count": 48 } ] }, "meta": { "request_id": "req_xyz123" }}Pole v odpovědi:
| Pole | Popis |
|---|---|
total_scans | Celkový počet skenů kódu za celou dobu (nezávisle na okně days) |
period_scans | Součet skenů ve zvoleném časovém okně |
scans_by_day | Denní buckety, vzestupně podle data, prázdné dny jsou vynechány |
top_countries | Top 8 zemí ve zvoleném časovém okně, sestupně |
top_devices | Top 5 typů zařízení (mobile, tablet, desktop) |
top_os | Top 5 operačních systémů |
Celkové součty za celý workspace (např. skeny za měsíc přes všechny kódy) jsou k dispozici přes GET /v1/workspaces/:id v poli scans_this_month. Pro analýzy napříč kódy doporučujeme použít dashboard nebo periodický export.
Pokud chceš zpracovávat události skenování ve chvíli, kdy nastanou — například pro živé dashboardy, sledování leadů nebo integraci s CRM — přihlas se k odběru události qr.scanned:
curl -X POST https://qr3.app/v1/webhooks \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/qr3", "events": ["qr.scanned"], "secret": "my-secret-key-min-16-chars" }'Payload:
{ "id": "evt_abc123xyz", "type": "qr.scanned", "created": "2026-05-12T14:32:11.000Z", "data": { "code_id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "scan_id": "scn_d1f8...", "country": "AT", "device_type": "mobile", "os": "iOS" }}Kompletní dokumentace k ověřování podpisů, logice opakování (retry) a doručovacím logům (delivery logs) v API → Webhooks.
Záznamy o skenech neobsahují žádné osobní údaje v podobě IP adres. Původní IP adresa je v Edge Workeru nahrazena kryptografickou hašovací funkcí (SHA-256) s denně rotujícím saltem. To znamená:
Uchovávání dat (Retention) závisí na tarifu:
| Tarif | Uchovávání |
|---|---|
| Free | 7 dní |
| Pro | 90 dní |
| Business / Agency | 1 rok |
| Enterprise | Custom (SLA) |
Denně spouštěná cron úloha (purgeOldScans) automaticky odstraňuje starší záznamy — hodnota total_scans u objektu kódu tím zůstává nedotčena.
days=365) může mít payload i několik KB. Na straně klienta cacheuj s krátkou TTL (např. 60 s).top_countries, top_devices a top_os jsou na straně serveru omezeny na 8, respektive 5 záznamů. Pro hlubší analýzy exportuj surová data.null: Pole country, region, city, referer a language mohou mít hodnotu null. Ve svém vyhodnocení s tím počítej a interpretuj to jako „Neznámé“.