Aggregerings-API
GET /v1/codes/:id/scans — tidsserier + toppländer/-enheter/-OS för ett enskilt kodobjekt.
Varje skanning av en dynamisk QR-kod skapar en scan-record i din workspace. Datainsamlingen sker helt på Cloudflare Edge — utan externa spårningstjänster, utan cookies och utan att den ursprungliga IP-adressen någonsin når din databas.
Tre sätt att konsumera skanningsdata:
Aggregerings-API
GET /v1/codes/:id/scans — tidsserier + toppländer/-enheter/-OS för ett enskilt kodobjekt.
Webhooks (realtid)
qr.scanned-event per skanning, HMAC-SHA256-signerat. Se Webhooks.
Dashboard
Visualisering i qr3.app-dashboarden — inget API-anrop krävs.
För varje skanning skapas en post i tabellen scans:
| Fält | Källa | Exempel |
|---|---|---|
id | Servergenererad UUID | scn_d1f8… |
code_id | Kod-ID för den skannade QR-koden | qr_a1b2c3d4 |
workspace_id | Kodens workspace | ws_xxx |
country | Cloudflare cf.country | AT |
region | Cloudflare cf.region | Vienna |
city | Cloudflare cf.city | Wien |
device_type | User-Agent-parsning | mobile, tablet, desktop |
os | User-Agent-parsning | iOS, Android, macOS, Windows |
browser | User-Agent-parsning | Safari, Chrome, Firefox |
referer | HTTP Referer-header | https://example.com/landing |
language | Accept-Language-header (första språket) | de |
redirected_to | Faktiskt omdirigeringsmål | https://example.com |
ip_hash | SHA-256(IP + dagligt salt) — inte reversibelt | 8f3a… |
scanned_at | ISO-8601-tidsstämpel | 2026-05-12T14:32:11.000Z |
Alla geodata (country, region, city) kommer från cf-objektet i Cloudflare och baseras på Cloudflare Geo-IP-databasen. Inga externa Geo-IP-tjänster anropas — upplösningen sker i samma worker som utför omdirigeringen.
Detta får tre konsekvenser:
city är inte alltid tillgänglig (t.ex. vid VPN, mobiloperatörer eller små regioner). Räkna med null-värden och kalkylera med dem i dina dashboards.GET /v1/codes/:id/scansReturnerar aggregerad analysdata för en enskild QR-kod under en valbar tidsperiod.
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-parametrar:
| Parameter | Typ | Standard | Beskrivning |
|---|---|---|---|
days | integer | 30 | Tidsperiod i dagar (1–365) |
Svar (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" }}Svarsfält:
| Fält | Beskrivning |
|---|---|
total_scans | Totalt antal skanningar under kodens livstid (oberoende av fönstret för days) |
period_scans | Totalt antal skanningar under det valda tidsfönstret |
scans_by_day | Dags-buckets, stigande efter datum, tomma dagar utelämnas |
top_countries | Topp 8 länder under tidsfönstret, fallande |
top_devices | Topp 5 enhetstyper (mobile, tablet, desktop) |
top_os | Topp 5 operativsystem |
Workspace-övergripande summor (t.ex. skanningar per månad för alla koder) finns tillgängliga via GET /v1/workspaces/:id i fältet scans_this_month. För analyser över flera koder rekommenderar vi dashboarden eller en periodisk export.
Om du vill bearbeta skanningsevents så fort de inträffar — till exempel för live-dashboards, lead-tracking oder CRM-integrationer — prenumerera på qr.scanned-eventet:
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" }}Fullständig dokumentation om signaturverifiering, retry-logik och leveransloggar finns i API → Webhooks.
Scan-records innehåller inga personuppgifter i form av IP-adresser. Den ursprungliga IP-adressen ersätts i Edge-workern med en kryptografisk hashfunktion (SHA-256) med ett dagligt roterande salt. Detta innebär:
Retention (lagringstid) beror på ditt abonnemang:
| Abonnemang | Lagringstid |
|---|---|
| Free | 7 dagar |
| Pro | 90 dagar |
| Business / Agency | 1 år |
| Enterprise | Custom (SLA) |
Ett dagligt cron-jobb (purgeOldScans) tar automatiskt bort äldre poster — total_scans på kodobjektet påverkas inte av detta.
days=365) kan payloaden bli flera KB stor. Cachelagra på klientsidan med en kort TTL (t.ex. 60 s).top_countries, top_devices och top_os är begränsade på serversidan till 8 respektive 5 poster. För djupare analyser bör du exportera rådata.null-värden: country, region, city, referer och language kan vara null. Hantera detta som “Okänd” i dina analyser.