Skip to content

Legal

Privacy Policy

What is collected, why, who it is shared with, and — stated honestly — what does and does not have a retention limit.

Draft — not reviewed by a lawyer

This document was written by checking what the software actually does, not copied from a template. It is a starting point, not a finished legal instrument, and it has not been reviewed by a lawyer. Some sections contain bracketed placeholders (such as [ENTITY NAME] or [JURISDICTION]) that this deployment's operator has not yet filled in.

Draft prepared: 2026-08-24.

This document is published in English only. The text below is not yet available in a reviewed translation, so every language on this site shows the same English wording until a professional translation is commissioned.

Who controls your data

The Service is self-hostable: the entity actually responsible for a given deployment's data is whoever operates that deployment, not the authors of this document. For the deployment you are using, see its Imprint for who that is. Where this policy says “we”, it means the operator of the specific deployment you are using.

What we collect

Account data: your email address, password hash (if you use password login), and — if you sign in with Discord — your Discord id, username and avatar URL.

Terms acceptance: when you accepted the Terms of Service and Privacy Policy, and which version, stored on your account (and kept, without your email, if you delete it).

League membership: which leagues you belong to and your role in each.

Driver profile: display name, short name, nationality, car number and avatar, if a league admin has created or linked one to your account. A driver profile can also exist with no linked account at all, as a roster placeholder.

Recruiting applications: if you apply for a seat in a league, the answers you give to the league's own questions, your stated driving assists, your preferred car number and timezone, and — if the league connects Discord — whether and when you joined its server.

Tier placement from your lap times: unless you switch it off, the platform may use the lap times you set in the leagues you race in (when you race in more than one) to place those leagues' tiers relative to each other. Only the tiers' placement is shown. Nothing about you is published, and this is separate from your public profile and from showing your ratings.

Race telemetry: per-lap times, sectors, car and tyre status, session events, weather and speed-trap data, uploaded from a member's own game-session capture. Some fields (driver name, team, platform) are reported by the game itself for that session.

Activity log: an automatic audit trail of privileged actions in your league. The name recorded for you is resolved in priority order — your Discord handle, then your roster driver name, then only the part of your email before the @, then your account id — and never your full email address.

Security/audit events: login success or failure, password-reset requests, and similar account-security events also record your IP address and browser user-agent string.

Push notification subscription, if you opt in: your browser's push endpoint URL and its encryption key. These are never returned to any client by the API — only a subscription id, your device's user-agent string, and timestamps are.

Billing identifiers, once your league subscribes to a paid plan: a Stripe customer id and subscription id are stored against your league. Your payment details (card number, billing name) are collected and held by Stripe directly — we never see your card number.

First-party usage analytics: one row per page view or feature use, holding the route template (for example /api/races/{id}, never the filled-in URL), your user id, your role in the league and the league. No IP address or user agent is stored in it, and no third-party analytics service is used.

Feedback you submit in the app: your text, plus a “Reported by” line with your driver name or Discord username, becomes an issue in the operator's GitHub issue tracker.

A session token, mirrored into a non-HttpOnly browser-session cookie (no expiry set, so your browser drops it when it closes) so your session works across this deployment's subdomains; and separate cookies, each set for one year, for your language, timezone and (on public pages) season preference; plus, once you answer the embed banner, a one-year cookie remembering whether third-party embeds (Twitch) are allowed.

Browser local storage: your sign-in token; for a super admin viewing as another account, the impersonation token; and interface preferences kept only in your browser — theme, units, navigation mode, dashboard layout and density, remembered filters, onboarding / “what's new” / install-prompt state, and a hash of your push-subscription endpoint. None of it is sent to a third party.

Why we collect it

To operate the Service: authenticate you, resolve your league membership and permissions, run the features your league uses, secure accounts against abuse, keep an audit trail of privileged actions, send transactional email, enable push notifications where you opt in, understand which features are used (first-party usage analytics), triage the feedback you send, and process payment where your league subscribes to a paid plan. This policy does not claim any particular legal basis applies in your jurisdiction, with one stated exception below.

Tier placement from your lap times (the Tier Pace Index setting). This processing is on by default and you can switch it off, so it does not rest on your consent. The operator of this deployment is in Switzerland and also serves drivers in the EU. It relies on its legitimate interest in placing tiers fairly and comparably across leagues, so that drivers can find a seat at their level: under the GDPR, Article 6(1)(f); under the Swiss Federal Act on Data Protection (FADP), an overriding private interest (Article 31). That interest is weighed against yours as follows: only an aggregate tier placement is ever shown, no lap time or other data about you is published or shown to another league, the lap times used are ones you already set in leagues you race in, and you can object at any time, without giving a reason, by switching the setting off under Account → My pace, which takes effect from the next nightly update.

Who we share data with

Only the third parties actually contacted by the code. Some are involved for every user of a deployment (hosting, Cloudflare); the rest only when a feature is used or configured.

Cloudflare — sits in front of the deployment as its DNS and proxy. TLS is terminated at Cloudflare, so traffic to and from the app (including sign-in credentials and your IP address) passes through Cloudflare's network.

Microsoft Azure — production is moving to Azure, region Switzerland North; until the move completes it runs on a self-hosted server, also behind Cloudflare. On Azure the processors are Container Apps (the API and web containers), Database for PostgreSQL Flexible Server (all application data, with automated backups and 14-day point-in-time restore), Storage (uploaded files and, if enabled, database export copies), Key Vault (secrets), and Log Analytics with Application Insights (operational logs and telemetry of the service itself, 30-day retention).

Stripe — payment processing for paid plans. Stripe receives your league's billing name and, during their own checkout flow, whatever payment details you give them directly; the app never sees your card number.

Discord — for sign-in (your id, username, avatar, and email only if Discord has verified it), and, if a league admin configures it, results announcements, role assignments, direct messages to drivers (for example check-in reminders and post-race debriefs), protest discussion threads, recruiting posts and scheduled events for that league.

Cloudflare Turnstile — only where an operator turns it on: a security check on sign-up and league creation. When you complete it, Cloudflare receives your IP address and technical signals from your browser to tell people from automated scripts, and the server sends Cloudflare the resulting token and your IP address to verify it. The app stores neither the token nor anything else from the check.

GitHub — in-app feedback. When you submit feedback, the app creates an issue in the operator's GitHub issue tracker containing your text and a “Reported by” line with your driver name or Discord username. It does not include your email, user id, league name or IP address.

Twitch — a league can embed a Twitch stream or video. The player is an iframe from player.twitch.tv and it does not load until you allow third-party embeds: a banner asks, and until you agree you see a placeholder with a link to Twitch and a “Load player” button that loads it for that one view. Once the player loads, Twitch can receive your IP address and set cookies in your browser. You can change your choice at any time under Account → Privacy & data, or the “Privacy settings” link in the footer of the main site. “Allow embeds” is remembered in a cookie; “Not now” only hides the banner until your browser session ends. Separately, the server calls the Twitch API with channel names only — no personal data about you.

Open-Meteo — weather lookups for a race use track coordinates only. No personal data is sent.

Webhooks a league configures — a league admin can register URLs that receive signed JSON events (for example “results finalized”). What an event contains, and what the receiver does with it, is under that league's control.

The keyed read API (/api/v1) — a league admin can issue API keys that let a program read the league's published data. What that program does with it is the league's responsibility.

Your browser's own push service (for example Google, Mozilla or Apple, whichever your browser uses) — only if you opt into push notifications, and only the encrypted notification payload.

An email provider of the operator's own choosing — for invites, password resets, email verification and trial notices. This is not a fixed third party; it is whichever server the operator has configured. Where none is configured, these emails are not sent.

We do not sell personal data, and we do not share it with anyone other than those listed above and the recipients a league itself configures (webhooks, API keys, its own Discord server).

International transfers: Cloudflare, Discord, Stripe, GitHub and Twitch are US-based recipients, so the personal data described above for each of them is disclosed to recipients in the United States. Which push service receives a notification depends on your browser. [LAWYER TODO: state the transfer mechanism relied on for each (adequacy decision / Swiss-US and EU-US Data Privacy Framework certification / standard contractual clauses) — this draft does not assert one.]

How long we keep it

Activity log: kept 30–730 days (your league admin sets the window; 180 days if they haven't), pruned by a scheduled job, and your league admin can purge it for your league on demand.

Security/audit events: kept 90 days by default (730 days for cross-league administrative actions), for the whole deployment, not configurable per league. The rows keep your IP address and user agent for that window, including after you delete your account.

An unfinished sign-up (started but never completed): kept 7 days by default after it expires or is used.

Your in-app notification inbox: kept 7–730 days, 90 days by default. That is the configured retention window; this policy does not promise that a scheduled job enforces it.

A recruiting application: a declined, withdrawn or expired one, or an abandoned draft, is kept for 90 days after that outcome by default — the operator of this deployment can change that period to anywhere from 7 to 730 days, for every league at once rather than per league; once admitted, the application record itself is kept 90 days after you joined — the membership and the audit trail of the decision are kept as your league's ongoing record after that.

A push subscription has no fixed retention window — it is removed once your browser's own push service reports it permanently gone, not on a timer.

Race results, lap times, sessions and driver profiles: kept indefinitely as your league's historical record unless the league sets a window. Raw telemetry retention is a per-league setting (available to leagues whose plan includes data retention); when set, a scheduled purge job deletes that league's raw telemetry older than the window. Results, standings and driver profiles are not touched by it. Otherwise data is removed only when an operator permanently deletes the whole league. Whether the purge job is installed is an operator matter; the Azure deployment does not yet have one. [LAWYER/OWNER TODO: confirm the purge job before publishing a retention promise for the Azure deployment.]

First-party usage analytics: raw rows are kept 90 days, then reduced to aggregated rollups (counts per route, role and period) that carry no user id and no league identifier. The raw rows are not erased when you delete your account — they carry only a pseudonymous user id, a route template, a role and the league, and age out with the 90-day window.

Backups: data you delete, or that a retention job removes, persists in backups until those expire. On the self-hosted server, database dumps are kept 7 days, and if the operator enables off-site copies they are kept as 7 daily, 4 weekly and 6 monthly snapshots — up to about 6 months. On Azure the database's automated backups give 14-day point-in-time restore, and an optional scheduled export copy has its own retention. A restore from backup can bring back data deleted after the backup was taken. [LAWYER TODO: whether and how a deletion or erasure request must reach backups.]

Twitch: what Twitch's player stores in your browser, and for how long, is governed by Twitch, not this deployment.

Browser storage: the session cookie is a browser-session cookie — it has no expiry, your browser drops it when it closes, and it is cleared on sign-out. The language, timezone and season-preference cookies last one year. Local storage entries have no timer; they stay until you sign out where the app clears them, clear site data, or the app overwrites them. The Twitch embed is the only third-party item; it loads only after you allow third-party embeds, and your choice is kept in a one-year cookie (f1_embed_consent).

Your choices, and how to get data removed

You can download your own data yourself from Account → Privacy & data (“Download my data”). It is one JSON file with your account details (never your password, two-factor secrets, recovery codes or tokens), linked Discord identity, public-profile settings, your own sign-in and security events (with the IP address and user agent recorded for them), and, for each league you belong to, your membership, your driver profile, check-in answers, notifications and notification settings, push devices (the push service only, not the device keys), the protests, appeals, statements and messages you wrote, your votes, your saved setups and your own entries in the league's activity log. Your applications and seat watches are included as you see them yourself, never with a league's internal notes. Not included, and listed in the file itself: league records shared with other drivers (results, standings, lap times, penalties), other people's data, the first-party usage analytics rows (pseudonymous, kept 90 days), feedback you sent (it is held in the operator's GitHub issue tracker, not by the app), and leagues you have left or joined only as an event guest — ask the operator for those. A steward's ruling on a session that is not yet published appears in the file as it does in the app (still under review) until the session is published. You can download it a few times an hour, and each download is recorded in the security trail without its content. The separate export tools for league officials produce season results and standings; they are not a personal-data export.

Removing you from a league revokes your access to it. It does not erase historical race results, lap times, or a linked driver profile already recorded — those remain as the league's historical record.

You can delete your own account from Account → Delete account. Deletion anonymizes rather than erases: your sign-in, Discord link, public profile, notification and push settings, calendar feeds and league memberships are removed, and your driver in each league is renamed “Former driver #N” with its nationality, avatar and public profile cleared. League results and standings are not altered — they are the other drivers’ record too. Your name and nationality are also cleared where a league copied them onto a kept record (Hall of Fame, award results, stewarding decisions, telemetry slots), including a guest driver created by an event sign-up in a league you never joined. Rows that record who did something keep an anonymous account id. A few carry a name snapshot written at the time (for example the activity-log actor label, “uploaded by” labels or a free-text reason that mentions you); those are not rewritten by this flow — the activity-log label ages out under the activity-log window, while the others have no retention window of their own and stay until an operator rewrites them by hand on request. A Discord id used only as a bot-synced guild-member cache entry is refreshed from Discord, not by this flow. Deletion is blocked while you are the only owner or the only member who can manage members of a league, or started a league with an active paid plan.

Two records survive account deletion by design: the security trail keeps its IP-address and user-agent rows, with your anonymous account id, for their retention window, and the first-party usage analytics rows keep their pseudonymous user id until their 90-day window ends. Copies in backups persist until the backups expire.

A request the self-service flow cannot handle (a platform account, or a record you want erased rather than anonymized) is an operator action: contact your league admin or the deployment operator.

Tier placement from your lap times is on by default, for every account. You can switch it off at any time from Account → My pace (“Help place tiers with my lap times”); it takes effect from the next nightly update. When this default changed, the setting was switched on for every existing account too, including any that had switched it off before, so check it if you want it off.

Third-party embeds: you can change your choice at any time from Account → Privacy & data, or the “Privacy settings” link in the footer of the main site. “Allow embeds” is remembered in a one-year cookie; “Not now” only hides the banner until your browser session ends and stores nothing. Declining only means the Twitch player is not loaded automatically.

Security

Each league's data is technically isolated from every other league at the database level, enforced so that no tenant context means no data is returned rather than an error. This describes a technical control, not a claim that any particular security standard or certification has been met.

Children's data

The Service does not verify the age of anyone who registers, and there is no dedicated handling for children's data. If a deployment is used by minors, its operator is responsible for whatever additional safeguards their jurisdiction requires — none are built into the product today.

International data transfers

The software is self-hostable, so where a given deployment stores and processes data is whatever its operator chose. Production is moving to Microsoft Azure, region Switzerland North; until that move completes it runs on a self-hosted server. Both sit behind Cloudflare, which terminates TLS and so handles traffic outside Switzerland. Disclosures to Cloudflare, Discord, Stripe, GitHub and Twitch (US-based recipients) are described under “Who we share data with”. [LAWYER TODO: the transfer mechanism for each of those recipients, and for Cloudflare's global edge.]

Changes to this policy

We may update this policy as the Service changes. Continued use after a change means you accept the updated policy.

Contact

Questions about this policy, or a request concerning your data: [CONTACT EMAIL].

More legal documents

The other documents covering this deployment.