Data Retention & Compliance
Data Retention & Lifecycle Management
QRForge applies enterprise‑grade data retention policies to ensure security, compliance, and predictable lifecycle behavior for all API‑generated and dashboard‑managed data. This document outlines how long different categories of data are stored, how deletions are processed, and what can be expected from the platform’s archival and purge cycles.
Applies to: API v1 and QRForge Dashboard
Status: Stable retention policy (subject to future Enterprise‑tier extensions)
QR Code Metadata
Retention: Indefinite, until user deletion.
Includes:
labelproject_idslugredirect_urlanalytics_enabledcreated_at,updated_atcreated_via(dashboard, API, import)
Deletion behavior:
- The public API has no delete endpoint for QR codes. A QR code is archived, not deleted, via
PATCHwithstatus: "archived". - An archived QR code stops resolving for scans (effectively removed from public traffic), but its metadata and slug are retained, and the slug is not released for reuse while the code is archived.
- Archived QR codes can be reactivated via the same endpoint (
status: "active"). - Hard deletion of QR metadata only happens as part of full account deletion (see User‑Initiated Deletion below) — a separate, dashboard‑initiated flow, not something triggered per‑QR via the API.
Raw Scan Logs
Retention: 90 days
Raw scan logs contain:
- Timestamp
- Device + platform metadata
- Country/region (IP‑derived)
- Browser + referrer
- URL parameters (e.g., UTM fields)
Purpose:
- Anti‑fraud intelligence
- Trend‑level analytics
- Real‑time scan monitoring
- Debugging integrations
Deletion behavior:
- Automatically purged after 90 days on a rolling basis, enforced by a Firestore TTL policy on an
expire_atfield set at write time. - After deletion, only aggregated analytics remain.
Trail Visitor Events
Retention: 90 days
QRForge Trails record one event per trail entry and per stop view, so the funnel report can be built. Each raw event contains:
- A visitor identifier (
visitor_id) stored in a first‑party cookie, used only to distinguish repeat visits within a trail - The trail and stop being viewed
- A truncated user‑agent string
- Timestamp
Deletion behavior:
- Automatically purged after 90 days on a rolling basis, enforced by a Firestore TTL policy on an
expire_atfield set at write time — the same window and mechanism as raw scan logs, since the data category is the same. - Raw events are rolled up nightly into daily per‑trail aggregates, which are retained under the Aggregated Analytics policy below. The funnel report is served from those aggregates, so purging the raw events does not remove historical reporting.
- Full account deletion removes a user's trails, their raw events and their aggregates immediately, as part of the cascade described under User‑Initiated Deletion.
Aggregated Analytics
Retention: 24 months
Stored in daily_scan_stats, daily_trail_funnel_stats and other aggregate collections, including:
- Total scans per day
- Country/device breakdowns
- Time‑of‑day distributions
- Bounce vs. multi‑scan ratios
Purpose:
- Long‑term trend analysis
- Reporting
- Enterprise planning
Deletion behavior:
- Automatically purged after 24 months (rolling window), enforced by a Firestore TTL policy on an
expire_atfield set at write time.
Project Metadata
Retention: Indefinite
Project definitions persist until manually deleted by the user.
Stored fields include:
namedescriptionis_defaulthas_custom_domain- Timestamps (
created_at,updated_at) - Ownership (
owner_uid) - Creation source (
created_via)
Deletion behavior:
- Hard deletion removes all project metadata.
- Associated QR codes are not auto‑deleted; they must be deleted separately.
API Logs & Audit Records
API request logs: 30 days
Admin audit log (admin_audit_log): 12 months
Tracks:
- API key usage
- Rate limit evaluations
- Internal error traces
- Authentication and ownership checks
- Admin actions (who did what, when, and from which IP)
Used for:
- Security investigations
- Abuse prevention
- System‑level diagnostics
Deletion behavior:
- Admin audit log entries are automatically purged 12 months after creation, enforced by a Firestore TTL policy on an
expire_atfield set at write time. - The
ipfield on an audit log entry is the administrator's IP address and is stored in full — it is not masked. This is intentional: full IPs on the audit trail are a legitimate security‑logging use case, distinct from customer‑facing analytics data (see Compliance Notes below).
Billing & Payment Provider Events
Retention: 30 days for raw payment‑provider webhook payloads
QRForge's payment provider sends webhook events for subscription and order lifecycle changes. Events that cannot yet be matched to an account, and event types QRForge does not act on, are retained in raw form purely so a billing discrepancy can be reconciled after the fact. A raw payload may contain the customer name, email and billing address held by the payment provider.
Deletion behavior:
- Raw payloads are automatically purged after 30 days, enforced by a Firestore TTL policy on an
expire_atfield set at write time. - Webhook delivery records (used to guarantee each event is processed exactly once — no payload, no personal data) are retained for 90 days.
- Confirmed subscription and invoice records are not covered by this policy; they are billing records retained with the account.
User‑Initiated Deletion
Individual QR codes cannot be hard‑deleted through the public API — see QR Code Metadata above; the only per‑QR write available is archiving.
Full account deletion is a separate, dashboard‑initiated, email‑confirmed self‑service flow that satisfies GDPR's “right to be forgotten.” It cascades and permanently removes:
- All QR codes and their metadata
- All projects
- Personal/account data, billing history, and custom domains
Upon account deletion:
- Metadata → Hard deleted immediately (cascade)
- Raw logs → Removed on next purge cycle
- Aggregates → Removed according to retention windows
Export Windows
CSV/JSON exports will include:
- Up to 90 days of raw scan events
- Up to 24 months of aggregated analytics
Future Enterprise plans may allow extended or custom retention windows.
Compliance Notes
QRForge’s retention model supports:
- GDPR (right to erasure, data minimization)
- Long‑term analytics preservation without storing personal identifiers
- Automatic purging of raw, potentially sensitive metadata
QRForge does not store:
- Full IP addresses for scan/visitor traffic. IP addresses are masked before a scan record is written: IPv4 addresses have their last octet zeroed (e.g.
203.0.113.45→203.0.113.0), and IPv6 addresses are truncated to their/64network prefix. Geo fields (country, city, latitude/longitude) are resolved from the request and stored as their own separate fields, so masking the IP does not reduce analytics functionality. - Personal identity data
- Cross‑site or cross‑customer visitor tracking, advertising identifiers, or any visitor profile built beyond the event metadata described above. The one visitor identifier QRForge does set — the first‑party Trails cookie described under Trail Visitor Events — is scoped to a single trail's funnel measurement and expires with those events after 90 days.
This masking applies to scan/visitor data only. The admin audit log intentionally retains the full, unmasked IP address of the administrator performing each action — a standard security‑audit‑trail practice, and a distinct category from customer‑facing analytics data (see API Logs & Audit Records above).
Self‑Hosted Geolocation Lookup
To resolve the country/city geo fields described above, QRForge looks up the scanning visitor's IP address against a self‑hosted MaxMind GeoLite2 database that QRForge downloads and refreshes on its own infrastructure. This lookup happens entirely in‑process — no visitor IP address is ever transmitted to any third party for geolocation purposes. Only the masked IP and the resolved geo fields are persisted, per the retention rules above.
Summary Table
| Data Category | Retention | Deletion Type | Notes |
|---|---|---|---|
| QR metadata | Indefinite | Archive only via API; hard delete via account deletion | No API delete endpoint — status: "archived" via PATCH |
| Scan logs (raw events) | 90 days | Automatic purge (Firestore TTL) | Rolling window; IP addresses masked at write time |
| Trail visitor events | 90 days | Automatic purge (Firestore TTL) | Raw per‑visit events; rolled up nightly into aggregates |
| Aggregated analytics | 24 months | Automatic purge (Firestore TTL) | Daily aggregates (daily_scan_stats, daily_trail_funnel_stats) |
| Raw billing webhooks | 30 days | Automatic purge (Firestore TTL) | Unmatched/unhandled payment‑provider payloads only |
| Project metadata | Indefinite | Hard delete | QR codes not auto‑deleted |
| API logs | 30 days | Automatic purge | Platform logs |
| Admin audit log | 12 months | Automatic purge (Firestore TTL) | admin_audit_log; admin IP stored unmasked |
If you require custom data retention policies, extended archival windows, or enterprise‑tier data residency options, please contact support.