OTRI · Open Trail Running Index

Privacy policy

Last changed 2026-09-28.

What we collect

Organizer accounts (POST /auth/register):

Race/result submissions: race metadata and result files organizers choose to submit (see Data policy for how athlete data within those files is handled). From a results file OTRI keeps each finisher's names, gender, finish time and rank, and, when supplied, the bib number, the year of birth and a country code, never the full date of birth. The bib number is shown on the public leaderboard and in the scored CSV.

Publishing: when an organizer publishes a race, the moment and their confirmation that they organize it are recorded with the race, together with what the automatic check noted (api/screening.py: signs that a results file is invented or copied, in plain words) and any decision an admin took, with the admin's address and note. The organizer sees all of this on the race's review page; the public sees only whether the race is pending, verified, or not public. The OTRI admins receive an email for every publish naming the race, the organizer's address and the finisher count.

Runner profiles: results from races an organizer has published are grouped into a runner profile (name, gender, country, age category, published results and the runner index described in docs/methodology/runner-index/RUNNER-INDEX-v1.md). Profiles show nothing that is not already on a published leaderboard. A runner can ask for a profile to be removed or corrected with the "Report a problem" form on every profile, leaderboard and shared course (or at hello@otri.run); reports go only to the OTRI admins, who can delete the data from the admin dashboard. Unpublishing a race removes its results from every profile at once, and also takes back any year of birth or country that race had contributed to the profile. Public pages are cached for up to about a minute and a half at the front door, so a page someone has just loaded can take that long to catch up.

Score my race (POST /score): the course file and the results file you upload are checked, scored and deleted before the answer is sent. No race, result or runner is recorded, the names in the file are never written to the database, and nothing is linked to an account or published. The scored list exists only in the answer your browser or program receives.

If you then press Publish this race, the two files are kept in your own browser (its IndexedDB, under otri-publish) so the organizer app can create the race page without a second upload. They are not sent anywhere by that step; they reach OTRI only through your signed-in uploads, and they are deleted from the browser as soon as the race page exists, when you press "Throw it away", or the next time you open any OTRI page after they are a day old.

Score calculator uploads (POST /gpx/analyze): a GPX file you upload is measured and then discarded; it is not linked to any account. If you click Share this score, the file is stored (POST /gpx/share) under an id derived from its contents so the link can reopen it, together with the course name you saw on screen. Anyone with the link can view that course. Before any course file is stored (a shared course, or a race's course uploaded by its organizer) it is reduced to its track: positions and elevations only. Timestamps, the author's and device's names, heart rate and other sensor data, waypoints and notes are not kept in the stored file and are never served. Nothing about the file's origin is kept for a shared course, and neither is the name of the file you uploaded. (For a course an organizer attaches to a race, the origin details are kept privately so a licence question can be answered; see Data policy.) The target time travels in the link, not on the server. Shared courses are stored compressed under a total size budget; when it is full the oldest ones are deleted, so old links can stop working. Email hello@otri.run to have a shared course removed sooner.

Server logs: standard web server access logs (IP address, request path, timestamp) for operational/security purposes. They record the path only and never the query string, so the one-time links OTRI emails do not end up in a log. The application log shortens email addresses (ab***@example.com) rather than writing them out. The rate limiter in api/rate_limit.py throttles abuse per address, and stores a digest of the address rather than the address itself. Not used for tracking or analytics.

OTRI sets cookies only where one is needed to make something work, never for analytics or advertising. All three are HttpOnly, so page scripts cannot read them, and all three are set by the API:

We do not use third-party analytics or advertising trackers.

Counting visits: OTRI counts how many people use the site, with its own code (api/analytics.py), and hands nothing to anybody else. Opening a page tells the API the path you are on, the site you came from if any (its address only, never a search you typed), your browser's time zone setting, and what the browser says it is. Nothing is written to your browser: no cookie, no stored identifier, nothing that is still there when you come back.

So that the same person is not counted twice in a day, the API makes a number out of the date, a secret, your network address and your browser's description, keeps only that number, and throws the rest away. The date is inside it, so the number is different tomorrow and today's visit cannot be joined to any other day's. Those numbers are deleted after three days; what is left is the count itself, which is nobody's. If your browser sends "Do Not Track" or Global Privacy Control, nothing is sent at all.

Alongside the counts the API keeps a tally of what was done: how many courses were measured, results files scored, races published and accounts made, per day. Those are totals with nothing attached to them.

Why we collect it

Who else sees it

How long we keep it

Your rights

You can ask us to:

Organizers can do the last two themselves on the account page, and both ask for the password first:

For anything else, or as a runner, contact hello@otri.run.

We keep a log of every email sent (recipient, subject, provider message id, outcome) so delivery problems can be traced; it is visible to admins only.

Security

Passwords are hashed with bcrypt, never stored or logged in plain text. Sessions use signed JWTs (OTRI_API_JWT_SECRET). See SECURITY.md for how to report a vulnerability.

Changes to this policy

Material changes to this policy are recorded in CHANGELOG.md.

Signing in with Google

Organizers may sign in with a Google account instead of, or as well as, a password. When they do, OTRI receives from Google a stable account identifier, the account's email address and the display name on it, and keeps only the first two, so the same Google account opens the same OTRI account next time. The display name is discarded: it is never stored, shown or used. Nothing else from the Google account is read or kept: no contacts, no calendar, no files, and no access token or refresh token, because OTRI never calls Google's services after the sign-in itself. Google is told only that a sign-in to OTRI happened. Google's own script is never loaded on OTRI's pages.

An OTRI account created this way has no password until its owner chooses to set one from the account page. Setting one matters for more than convenience: signing out everywhere, turning on two-factor sign-in, downloading your data and deleting the account all ask for a password, and the account page offers to email a link to choose one.