Privacy Policy
Version 2.0 • Last Updated: August 14, 2026
1. Introduction
GhostRail ("we," "our," or "the Service") provides real-time transit information for the Chicago area. This Privacy Policy explains what information we collect, why we collect it, how long we keep it, and who else handles it.
This policy covers both the ghostrail.app website and the GhostRail iOS application. Where a section refers to browsers, cookies or browser storage, it describes the website; where it refers to device permissions or push notifications, it applies to both. Anything that reaches our servers is handled the same way whichever one you used.
It is written to describe what the Service actually does. Where we state a retention period, name a company, or say we do not do something, it is because we have checked rather than because it sounded right.
2. The Short Version
- Most of GhostRail works without an account, and without you telling us anything.
- If you make an account we store your email address, a hashed password, and the stops and commutes you save.
- Every request to our servers is logged with an IP address. We use those addresses to apply rate limits and block abuse.
- If you use nearby-stop features, your coordinates are sent to us to answer that request. They are not saved to your account, and they are stripped out before our logs are written.
- Cloudflare carries all of our traffic and can see it. That is the one that matters most. We also use Cloudflare's analytics to count page views; it sets no cookies and does not identify you.
- We do not sell personal information, and we do not run advertising.
The rest of this document is the detail behind those points.
3. Where the Service Is Offered
GhostRail is operated from the United States and is intended for use by people located in the United States, specifically the Chicago metropolitan area. The Service is offered only in English, covers only Chicago-area transit agencies, and is not directed to or marketed toward people located in the European Union, the European Economic Area, the United Kingdom, or Switzerland. We do not offer goods or services to, or monitor the behavior of, people located in those jurisdictions.
4. Information You Provide
- Account information — your email address and a password. The password is stored only as a bcrypt hash and never in readable form. We cannot recover it, only reset it.
- Favorites — saved stops and stations, with an optional nickname you choose.
- Commute routes — origin, destination, and schedule for commutes you save.
- Notification preferences — which alerts you want, for which routes, and when.
- Error reports you trigger — if the site breaks while you are using it, see section 5.
- List signups — if you join a list (such as the iOS beta list), we store the email address you enter, the page you joined from, a timestamp, and a removal token created at that moment. We use this address solely to send you updates and access invitations related to that specific list. If you are signed in when you join, the entry is linked to your account; otherwise, it exists as an unlinked address. Because we do not send a confirmation email upon signup, anyone can enter any address. If you receive an email you did not request, every message includes a one-click removal link, or you can use either removal route in section 16.
There is no profile, no display name, no photo, and no way to post anything publicly.
5. Information Collected Automatically
- Server logs. Requests to our servers are logged with the originating IP address, the time, the path requested, the response status, the referring page, and your browser's user-agent string.
- Push notification tokens. If you enable notifications, a device token issued by Firebase Cloud Messaging. It identifies a device to the notification service; it does not identify you by name.
- Error reports. When the web application hits an error it sends us the error message, a stack trace, the page address, and a correlation identifier. The correlation identifier is a random value that lets us match your report to the matching request in our logs, so we can see what actually happened without needing to ask you.
- Location. When you use nearby-stop features, your device's coordinates are sent to our servers so we can find stops near you. They are used to answer that request and are not saved to your account. They are also stripped out of our logs before those logs are written — see section 9.
- Live updates. Arrival pages hold an open connection to our servers so times can update without reloading. That connection is logged the same way as any other request.
- Usage analytics. We use Cloudflare Web Analytics, which counts page views without cookies and without identifying you. See section 11.
6. What We Do Not Collect
Stated because "we collect the following" is easy to read as "and possibly more":
- No payment or card details. The Service is free and there is no billing system to hold them.
- No contacts, calendar, photos, microphone, or camera access.
- No continuous or background location. Coordinates are sent only when you use a nearby-stop feature, and only at that moment.
- No advertising identifiers, and no tracking of you across other websites.
- No selling, renting, or trading of personal information to anyone, for any purpose.
7. Cookies and Local Storage
We use a small number of cookies and browser storage entries. None of them are advertising cookies, and none of them are for analytics — they exist to sign you in, to keep that sign-in safe, or to remember a preference you set. Our analytics sets nothing in your browser at all; see section 11.
Everything below the first two rows stays in your browser. Those entries are never sent to our servers and we cannot read them.
| Name | What it is for |
|---|---|
gr_session |
Keeps you signed in. Marked HttpOnly, so scripts running in your browser cannot read it. |
gr_csrf |
Protects against another site submitting requests as you. Paired with, and verified against, the session cookie. |
gr_authed |
Stored in your browser rather than as a cookie. A simple marker that tells the app to show the signed-in interface. It holds no personal information and grants no access on its own. |
gr_recent_searches |
Browser storage. The last few things you typed into the search box, so the box can offer them again. It stays on your device. |
ghostrail_map_center, ghostrail_map_zoom |
Browser storage. Where you last had the map positioned, so it opens where you left it. This is a map position you chose, not a record of where you have been. |
ghostrail_favorite_routes, ghostrail_favorite_stations |
Browser storage. Routes and stations pinned on this device. Favourites saved to an account are held on our servers instead — see section 4. |
gr_disruption_dismissed, gr_storm_dismissed_episode, stateLakeBannerDismissed |
Browser storage. Records that you closed a particular banner, so it does not reappear on every page. Each holds an identifier for the notice you dismissed and nothing about you. |
gr_account_prompt_dismissed_until |
Browser storage. When you close the prompt that explains what a free account does, this holds the date until which it stays closed (14 days). It holds nothing about you. |
gr_account_prompt_shown |
Browser storage for this tab only, cleared when you close it. Records that the account prompt has already appeared, so it appears at most once per visit. |
gr_last_visit_day |
Browser storage. The date of your last visit, in Chicago time. GhostRail uses it to count returning visits by broad range (for example "1 day" or "2 to 7 days"). The date itself is never sent to GhostRail. |
Clearing your browser storage signs you out and removes all of these.
8. How We Use Information
- To provide arrival predictions, alerts, and the features you have enabled
- To send notifications you have asked for
- To keep your Favorites and preferences available across sessions and devices
- To protect the Service. We use IP addresses to apply rate limits and to detect and block abuse. This is the main security purpose for which we process IP addresses, and it applies to every request, signed in or not.
- To diagnose faults and improve reliability
- To understand which parts of the site are used, in aggregate
- To send you an invitation to something you joined a list for. Every message to a list is written and sent by a person; nothing is sent to a list automatically
- To record your agreement to these documents — see section 10
We do not use your information to build a profile of you, to make decisions about you, or to target advertising.
9. Retention
| Data | Retained for |
|---|---|
| Account information | Until the account is deleted |
| Favorites, commute routes, preferences | Until the account is deleted |
| List signups | Until you remove yourself, or until the list is closed and archived. Nothing on a list expires on a timer, because a list exists for a date that has not happened yet |
| Web server request logs | 14 days |
| Application logs | Rotated by size rather than by age; older entries are overwritten as newer ones arrive |
| Location coordinates | Not retained — removed before logs are written |
| Error reports | 14 days |
| Sign-in sessions | Until they expire or you sign out |
| Email verification and password reset links | Short-lived, and consumed when used |
| Push notification tokens | Until you disable notifications or the account is deleted |
| Agreement records | Until the account is deleted — see section 10 |
| Notification history (which alerts we sent you) | 30 days |
| Analytics | Held by Cloudflare as counts and totals, not as records about you. There is no per-person analytics record to attach a period to. |
| Backups | Up to 35 days — deleting your account removes it from the live service straight away, but a copy can remain in an encrypted backup until that backup ages out |
On location and logs. Some features send coordinates to the server as part of the address of the request, and logs record the addresses requested. We strip coordinates and email addresses out of that text before it is written to disk, so they do not accumulate. Our web server logs record the path you requested without the parameters attached to it. Error reports are scrubbed the same way before being stored.
Error reports are kept for 14 days deliberately. A report is only useful while the correlation identifier in it can still be matched to a request in the server logs, and those are kept for 14 days. Holding reports longer would mean keeping data we could no longer do anything with.
10. Records of Your Agreement
When you accept these Terms or this Privacy Policy, we record which version you accepted, when you accepted it, and the IP address the acceptance came from. We keep this for as long as the account exists, because it is the record that you agreed. Each document is recorded separately, so it is always clear which version of which document you accepted.
This is a different purpose and a different retention period from the server logs in section 5, even though both involve an IP address. Server-log addresses age out after 14 days. An agreement record persists for the life of the account, and is removed when the account is deleted.
11. Who Else Processes Your Data
These companies handle data on our behalf, or receive it because of how the Service is built:
- Cloudflare — routes and secures all traffic to our servers. Cloudflare terminates the encrypted connection, which means it processes every request you make to us, including your IP address and the content of the request. Cloudflare also stores our database archives and handles email sent to our published addresses. Those archives include account information as well as transit and weather measurements. They are encrypted before they leave our server, and Cloudflare cannot read them.
- Cloudflare Web Analytics — measures how the site is used, and is the only analytics on the Service. It is part of the same Cloudflare that already carries every request, so it introduces no additional company. It works differently from conventional analytics in ways that are worth stating plainly: it sets no cookies and stores nothing in your browser, it does not build a profile of you or follow you to other websites, and Cloudflare states that it does not use your IP address or user-agent string to fingerprint individual visitors. What we see is aggregate: how many times each page was viewed, roughly where visits came from, and how quickly pages loaded. We cannot single you out in it, and there is no per-person analytics record to request or delete. No analytics data goes to Google.
- Google (Firebase Cloud Messaging) — delivers push notifications to your device. This is the only Google service the Service uses, and it is used only if you turn notifications on.
- Resend — sends transactional email such as address verification and password resets.
- RackNerd — provides the server the Service runs on.
- Apple — distributes the iOS application. If you install it through TestFlight, Apple provides us with crash reports and basic usage figures for the beta, and passes on any feedback you choose to send through TestFlight. That data comes from Apple rather than from us, and Apple's own privacy terms govern how Apple collects it. We do not receive your Apple ID.
Transit and weather data comes from the CTA, Metra, and the National Weather Service. We send no personal information to any transit agency or weather service. Those are sources we read from, not parties we share with.
We may also disclose information if we are legally required to, or where we believe it is necessary to protect the Service or someone's safety. We do not sell personal information.
12. What Your Browser Contacts Directly
Some parts of the site load from other companies' servers. When that happens your browser connects to them directly, and they will see your IP address and which page requested the file. We do not send them anything else about you, and we have no control over their logs.
- OpenStreetMap — map tiles, when you view a map
- unpkg and cdnjs — the mapping library the maps are built on
- GitHub — the colored marker icons shown on maps
- Cloudflare — the analytics script described in section 11
The list above is complete. Any company not named there is not contacted by your browser while you use the website.
13. Where Your Data Is Handled
Our server is in the United States. Cloudflare operates a global network, so a request may be handled by whichever of its locations is nearest to you before reaching us; this is how the Service is delivered quickly and is not a transfer for any separate purpose. Google and Resend operate internationally and handle data in line with their own policies; Google is involved only in delivering push notifications, if you have turned them on.
14. Using GhostRail Without an Account
Most of GhostRail works without signing in: the live train, bus and Metra maps, service alerts, the history and reliability pages, the About page, the status page, stop pages, the departure board, and the embedded widget. If you use the Service that way we hold no account information about you at all — only the server logs described in section 5, kept for 14 days.
An account is for the parts that are about you rather than about the transit system: saved favourites, My Commute, notification preferences, and your account settings. Signing up buys those, not access to the information above.
One thing you can do signed out does leave us an email address: joining a list, described in sections 4 and 16. Apart from that, and the logs above, we hold nothing about a signed-out visitor.
15. The Embedded Widget and Public Displays
GhostRail offers a widget that other websites can embed to show arrival times, and a display mode intended for screens in lobbies and similar places. If you encounter GhostRail embedded in someone else's site, your browser is requesting the widget from us, so our server logs record that request as they would any other. The site doing the embedding is responsible for its own privacy practices, and we have no visibility into them.
16. Email and Notifications
We send email only when it is needed to operate your account: address verification, password resets, a welcome message, and a notice if someone attempts to register with an address that already exists. We do not send marketing email.
You can also join a list deliberately. The iOS beta list is the one that exists today. Email addresses reach a list only through the form on the site: there is no way for us to add one, and joining a list signs you up for nothing else. Every message sent to a list carries a one-click link to come off it. Until the first message goes out there is no such link to click, so to be removed before then, email removal@ghostrail.app.
Push notifications are sent only for the alerts you have turned on. They may include the route or stop the alert concerns. You can turn them off in the app or at the device level, and turning them off at the device level works regardless of what our settings say.
17. Security
- Passwords are stored as bcrypt hashes.
- Traffic is encrypted in transit.
- Session cookies are HttpOnly, so scripts running in your browser cannot read them, and are paired with a separate anti-forgery token.
- Our origin server accepts traffic only from Cloudflare, over a mutually authenticated connection, and its application ports are not reachable from the internet.
- Rate limits apply to sign-in and account endpoints to slow down guessing attacks.
- Access to production systems is limited to the operator.
No system is perfectly secure, and we do not claim otherwise.
18. If Something Goes Wrong
If we become aware of a breach affecting your personal information, we will tell affected users by email at the address on the account, and describe what happened, what was affected, and what we are doing about it. If you believe you have found a security problem in GhostRail, please email support@ghostrail.app rather than posting it publicly, and we will work with you on it.
19. Your Choices and Requests
- Access and correction — you can see and change your saved stops, commutes and preferences in the app. You can also download a copy of everything linked to your account from the Account page while signed in: your account details, agreement records, Favorites, commute routes and preferences, Metra and notification preferences, and your sign-in sessions. Server logs are not included, because they are not indexed by user and identifiers are scrubbed from them. If something is wrong and you cannot correct it yourself, contact us.
- Deletion — email privacy@ghostrail.app from the address on the account and we will delete it. Deleting the account removes your account information, Favorites, commute routes, notification preferences and settings, sessions, push tokens, and agreement records. Deleting the account also removes a list entry you made while signed in. You can also do this yourself from the Account page while signed in, which deletes everything listed above immediately. If you would rather we did it, the email route above still works and we will confirm when it is complete.
- Sessions — the Account page lists where your account is currently signed in, and lets you sign out any session individually. Use it if you have signed in on a device you no longer have.
- Notifications — turn them off in the app or on your device.
- Location — decline the browser permission. The Service works without it; you lose only the nearby-stop features.
- Analytics — a content blocker or a browser setting that blocks scripts will stop the Cloudflare analytics script from loading, and nothing else on the site depends on it. There is no opt-out link to offer you, because there is no profile or identifier to opt out of: the measurement is aggregate and sets nothing in your browser. We would rather say that than point you at a switch that does nothing.
- List signups — to come off a list, use the one-click link in any message it has sent you. If no message has reached you yet, email removal@ghostrail.app and we will take you off it. Deleting your account removes a list entry only if you were signed in when you joined; if you joined signed out, the entry is not connected to any account, so use one of the two routes above.
- Using the Service signed out — always available, as described in section 14.
We aim to respond to requests within 30 days. We may need to confirm you control the account's email address before acting on a request, so that someone else cannot make it for you.
20. Do Not Track and Global Privacy Control
We do not track you across other websites, so there is nothing for a Do Not Track or Global Privacy Control signal to switch off on our side. We do not respond to those signals separately, and we do not sell or share personal information in the sense those signals are meant to address.
21. Automated Decisions
GhostRail makes automated judgments about vehicles — whether a train appears to have vanished, whether buses are bunching, how reliable a route has been. It makes no automated decisions about people. Nothing about your account is decided by an algorithm, and there is no profiling or scoring of users.
22. California Residents
We do not believe GhostRail meets the thresholds that make the California Consumer Privacy Act apply to us. We offer the following voluntarily: the right to know what we collect, the right to ask us to delete it, and the right not to be treated differently for exercising either. We do not sell or share personal information as that Act defines those terms, and we have not done so in the preceding twelve months.
23. Children
GhostRail is not intended for children under 13 and we do not knowingly collect their personal information. If you believe a child has given us information, contact us and we will delete it.
24. Changes to This Policy
When we make a material change, you will be asked to review and accept the updated document the next time you sign in. You will see a short plain-language summary of what changed, with links to the full documents, and your acceptance is recorded against that specific version. Minor corrections that do not affect your rights or our obligations may be made without asking you to accept again; the version number and date at the top of this page will still change.
If you would rather not accept an update, you can continue to use the parts of the Service that do not need an account, or ask us to delete the account.
25. Contact Us
Privacy: privacy@ghostrail.app
General support: support@ghostrail.app
If you are unhappy with how we have handled a privacy question, say so in a reply and it will be looked at again rather than closed.
26. Governing Law
This Privacy Policy is governed by the laws of the State of Illinois, United States.