Trilho

Privacy policy

Revision dated 25 October 2026 · Contact: [email protected]

No account is required. Saved journeys and transport-card history stay on your phone and, if you use it, in your phone’s own backup (Google or iCloud), which Trilho cannot access. Searches and coordinates may be sent to provide routes, nearby stops and maps. Optional usage statistics are off until you enable them.

1. Who is responsible

The controller of your personal data is Trilho’s independent developer (a natural person in Portugal, identified in the App Store and Google Play listings), who publishes Trilho on the App Store and Google Play and runs its server and this website. Trilho is independent: it is not operated by any transport operator or public authority and has no official link with them.

Contact for this policy and for any request about your data: [email protected].

2. Journeys, location and searches

When you request a route or nearby stops, Trilho sends the necessary stop identifiers or coordinates to its server. Location permission is optional, requested when needed, and limited to use of the app. You can enter stops manually. Trilho does not track your location in the background. If you place a Trilho widget on your home screen or Lock Screen, your phone periodically asks the server, without any action from you, for the next departures of the saved trip or pinned stop, sending only the operator, stop and line codes (never coordinates), and the server only counts how many widget requests it receives per day, platform, widget type and reason, without IP addresses or identifiers.

Stop searches are sent to Trilho’s server as you type. When the text has at least three characters and you pause typing, or when you press the keyboard Search action, Trilho also sends it to its server to look up places and addresses: first in Trilho’s own address index (built from public Portuguese address data published by INE) and, if that is not enough, on to OpenStreetMap’s Nominatim geocoder. Your device location is not forwarded to Nominatim; it is only used to order the results. Addresses or map links you choose to share with Trilho are also sent to the server to resolve a destination; the server follows a supported map link through its provider and may send the shared coordinates to Nominatim. Successful geocoding results are cached in memory for reuse; the cache treats results as fresh for 24 hours and replaces older entries as it fills. This is more than processing a request in real time.

The “Buy ticket” button opens CP’s website through Trilho’s server. The server receives the CP page address (with the chosen stations and date), forwards it immediately and only counts how often the button is used per day, train type (for example Alfa Pendular or Urbano), how far ahead the trip is and which screen it came from. It keeps neither the address, the stations, the date nor any installation identifier. Trilho does not sell tickets or receive commissions from CP.

The tourist Home screen can show a Lisboa Card offer. Its prices and link are fetched from Trilho’s server like any other request, and the button opens the seller’s website in your browser (today the official Lisboa Card shop). If Trilho uses a partner link, a “We may earn a commission” notice appears next to the button. The link carries a Trilho partner identifier and nothing about you; the seller handles your purchase and its own cookies under its own policy, and Trilho receives no information about you from the seller.

Light and dark maps load from Trilho’s own map server (tiles.trilhoapp.com, hosted on Cloudflare); if it is unavailable, the app falls back to OpenFreeMap. Whichever serves the map receives your IP address and map-resource requests, which can reveal the area viewed, and its own privacy policy applies. Tapping a walking section opens Google Maps (or Apple Maps on iPhone) with the start and end points of that section; that app handles them under its own policy. Tapping “Search ‘…’ in Google Maps” or “Open Google Maps” opens Google Maps (the app or, if it is not installed, your browser) with the text you typed in the search, or just the map; from then on Google’s privacy policy applies. To protect the server from abuse, it counts requests per IP address in memory only; the counters are never written to disk and reset when the server restarts. Network services may keep technical records for operation and security. We do not use route searches to build an advertising profile.

This website. trilhoapp.com sets no cookies and loads no analytics, advertising or third-party scripts or fonts, so it shows no cookie banner. It is served by Cloudflare, which processes visitors’ IP addresses in technical logs to deliver and protect the site.

3. Data kept on your phone

Favourites, saved places, recent searches, preferences and card-reading history (which includes the card number and, when the card carries it, the holder’s name) are stored locally. NFC reading is optional and read-only: Trilho does not top up, validate or modify a card, and does not upload the card's contents — except, if you choose to name an unknown stop, the few codes described below. Supported information depends on the card and phone. You can clear stored lists in Settings or remove the app and its local data.

Naming an unknown stop. For some trips the card keeps only an operator’s internal stop code — on Carris buses, for example. If you choose to say which stop it was, Trilho shows your answer on your phone at once and sends our server an anonymous hint: the operator, route and stop codes written on the card for that tap, whether it was an entry or an exit, and the stop you picked from Trilho’s list. It never includes the card number, trip times, balance, or any identifier of your phone or installation. The server keeps only running totals of how many hints named each stop — no individual hint, no time and no IP address — so a hint cannot be linked back to you, and once sent it cannot be deleted because we cannot tell whose it was. Your IP address is used only in memory to limit abuse: a rate limit, and a salted fingerprint that ignores repeat hints for the same stop on the same day; both are kept only in the server’s memory, never written by Trilho to a file or database, and reset daily. When enough riders agree, or after a manual check, the stop name is shown to everyone. You can always choose «I don’t know» or close the sheet; nothing is sent then.

This data is part of your phone’s own system backup, if you have it on: on Android only when the backup is end-to-end encrypted with your screen lock, or when moving directly to a new phone; on iPhone according to your iCloud settings (Apple holds the keys unless Advanced Data Protection is on; an unencrypted computer backup keeps it readable on that computer). Trilho has no access to these copies. After you clear data in Settings, the backup copy is replaced the next time your phone backs up.

Notification after sharing (iPhone). If you turn this option on (the iPhone asks for permission only at that moment), when you share a place with Trilho from another app Trilho shows a local notification with that place’s name that opens your trip when tapped; the notification is created and delivered by your phone itself and sends nothing to Trilho’s server or any other service, and you can turn it off in Trilho’s or the iPhone’s Settings.

4. Optional usage statistics

Status: Optional usage sharing is part of the app since version 1.1.0 (September 2026). Both destinations described below are configured in the published app: Trilho’s own server collector and Google Analytics for Firebase. Nothing is sent to either of them until you enable sharing.

GA4 event and user retention is set to 2 months, with reset on new activity off. This setting does not cover standard aggregated reports or prove physical deletion. Google Signals, user-provided data, granular location/device collection and ad personalisation are disabled.

If you enable sharing, Trilho sends limited usage categories to two destinations. Our server receives a random installation identifier, a stable event identifier to prevent duplicates, day-level dates, platform, app version and environment. Google Analytics for Firebase receives individual usage events directly from the app. These are pseudonymous records, not anonymous totals. Neither stream includes GPS coordinates, addresses, search text, stop identifiers, card contents or journey histories supplied by Trilho.

These categories include the passes you declare in Settings: your city pass (Navegante Metropolitano, Municipal, +65, Urbano 3ª Idade or youth up to 23; Cartão Porto, Andante Metropolitano or Andante youth; bank card, no pass or not set) and whether you hold CP’s Passe Ferroviário Verde. The +65, Urbano 3ª Idade and youth options reveal an age group; Urbano 3ª Idade also reveals a tax address in Lisbon, and Cartão Porto that you live or study in Porto. The municipality you choose for a Municipal pass stays on your phone, and route searches do not include your passes.

They also include how a transport-card reading ended (which kind of card was recognised, or the kind of failure), whether you chose to save a card’s history, whether the card screen was opened from Home or by holding the card to the phone, and the steps of naming an unknown stop (asked, opened, answered, «I don’t know», closed or undone, and whether the stop was picked from the line or by search). Never the card number, balance, trips, lines or stops.

When you tap “Buy ticket”, they include the train type, how far ahead the trip is, the screen it came from and, on the trains screen, the line you picked (for example Lisbon–Porto) — never the stations or the date.

They also include whether Trilho asked the system for the store’s rating window (and after which kind of answer: a route, departures, a card reading or the metro), and taps on “Rate Trilho” and “Send feedback” in Settings — never the rating, which only Apple and Google see. They also include when you open “Where to top up” (from the card screen or the Home reminder, and which reminder it was), a tap on “Open the navegante® app” and a request to share Trilho (from the top-up sheet or Settings) — never the card number, the balance, the passes or the app you share with. And they include opening “How to pay for this trip” from a trip, with the answer it showed (the bank card is enough, except on one leg, may not be enough, or a ticket is needed) — never the trip, the operators or the places. Trilho never asks for or stores bank card details.

Since version 1.5.0, they also include how receiving a place shared from Google Maps ended (route found, choice between places, search or failure), whether it was the first time, which tip preceded it, and the sharing tips shown and tapped — never the address, name, coordinates or shared link, nor the searched text.

On iPhone, with the notification after sharing, they also include whether the trip was opened from the notification or by opening Trilho, how long after sharing (in ranges), whether the notification was shown (or why not) and your answer to the notification permission request — never the place.

Google’s SDK uses its own app-instance identifier and records event times, sessions, app lifecycle events and technical device/app details. It can derive approximate location from the network IP address. In Analytics we disable advertising identifiers, ad personalisation and screen reporting, and do not set a user ID. This does not remove the SDK’s own installation identifier or make the events anonymous. See Google’s SDK data disclosure.

For our own metrics, the app keeps session counters and flags for displayed answers, interactions and returns on days 7 and 30 locally. Observation starts when you enable sharing, not at first installation. A new session is counted after an absence of at least 30 minutes. Unknown outcomes remain unknown; these statistics do not establish that you made a journey. Google’s session and return reports use separate definitions.

Whatever your sharing choice, to decide when to ask for a store rating the app keeps on your phone how many useful answers you saw and on which days (last 30), and when it asked (last 365 days). These counters never leave your phone. The rating window and the rating are handled by Apple or Google under their own terms; Trilho never learns whether the window appeared or what you rated.

Our server stores data persistently: records that prevent duplicates, including fingerprints of the installation identifier and payload, have an 8-day event-day window; counts by installation, category and day have a 45-day window. The fingerprint remains pseudonymous. Cleanup runs at server startup and hourly, with the boundary day included. This is not a guarantee of physical deletion at an exact moment or while the server is stopped. Internal reports suppress positive groups below 25 self-reported installation identifiers. This threshold does not apply to individual events sent to Google or Sentry.

The first-party queue holds at most 2000 events and discards events older than 7 days. Delivery is attempted periodically in the foreground, at startup, when sharing is enabled and when connectivity returns; background delivery is not guaranteed. Google’s SDK handles its own delivery and does not use this queue. Retention at Sentry and in backups needs separate verification: we do not promise that the own-store 45-day window applies to them.

Version 1.1.0 asked everyone for a new choice before optional sharing could be enabled: a previous acceptance was reset to undecided and a previous refusal was kept. Our local queue/session/return state was cleared and the random identifier replaced. You can keep using Trilho without enabling sharing, or enable it in Settings or onboarding. Withdrawing consent stops new optional collection, clears our local queue and observation state, and resets Google’s local analytics data and app-instance identifier. It does not automatically delete data already received by our server or providers.

5. Diagnostics and translation

On Android and iOS, when crash reporting is configured, the same opt-in enables Sentry crash and error reports. These can include device and app details, stack traces, diagnostic breadcrumbs and the pseudonymous installation identifier. Disabling usage sharing closes this reporting in the same session. The same consent controls Sentry reporting on iOS.

Android uses Google ML Kit for optional translation of operator notices. The notice text is translated on the device, but ML Kit can send installation identifiers, device and app details, performance measurements and feature events to Google. This SDK activity is separate from Trilho's optional usage-statistics switch. Language models may need to be downloaded. On supported iOS versions, translation uses Apple's on-device Translation framework.

Technical server logs support diagnosis and security. The application’s request log records only the response status and method, without addresses, coordinates, search text or IP addresses; the web proxy is configured without an access log, though its operational log can record technical connection events that may include an IP address. Container logs rotate by size (about 100 MB for the application) and have no fixed deletion period. An external logging service, if configured, follows its own retention. The privacy assessment explains the remaining verification work.

6. Services and legal bases

Necessary requests provide the service you ask for (GDPR Article 6(1)(b)); limited operational and security diagnostics protect that service (Article 6(1)(f)); Trilho's optional analytics and Android and iOS Sentry reporting use consent (Article 6(1)(a)). A stop hint you choose to send is processed to carry out that request (Article 6(1)(b)), with in-memory abuse limits under legitimate interest (Article 6(1)(f)); the stored totals are anonymous.

ServicePurpose
HetznerTrilho backend hosting in Germany
CloudflareWebsite, DNS, email forwarding and Trilho’s own map server
OpenStreetMap Foundation / NominatimPlace search and reverse geocoding
OpenFreeMapBackup map styles, tiles and fonts, used only if Trilho’s own map server fails
Google ML Kit (Android)On-device translation, model downloads and SDK diagnostics
Sentry, when configuredOptional Android and iOS crash reports and backend error diagnostics
Google Analytics for FirebaseOptional individual usage events and SDK metadata on Android and iOS
Axiom, when configuredBackend technical logs

Some providers operate internationally. Where Google, Sentry or Cloudflare process data outside the EEA, they rely on safeguards such as the EU–US Data Privacy Framework or standard contractual clauses in their data-processing terms; those terms and the configured regions govern that processing. No individual journey or card data is sold by Trilho. External operator, source and support links open their respective services; those services handle any information you give them.

7. Your choices and rights

You may decline location access, leave usage sharing off, clear local data, or contact us to request access, correction, erasure, restriction or objection where applicable. A random identifier can still be personal data; having no account does not remove your rights. We may need information sufficient to identify a relevant record, without asking you to provide unnecessary personal data. Removing the app does not automatically delete server logs or third-party records.

Optional-statistics records on our server and at Google are tied only to random identifiers that the app does not display, so we usually cannot tell which records are yours (GDPR Article 11). Withdrawing consent stops new records and replaces the identifier, so earlier records can no longer be linked to your phone going forward; the records on our own server expire on the schedule in section 4.

Write to [email protected]. You may complain to the Portuguese supervisory authority, CNPD. We handle requests within applicable GDPR time limits.

8. Children and updates

Trilho is a general transport service and is not directed at children. In Portugal a child aged 13 or over can consent to online services alone (Lei 58/2019, Article 16); for younger children optional sharing should stay off. Changes to data use will be reflected here. Read the technical privacy assessment or the Portuguese policy.

Changes on 25 October 2026: the bank card in passes and the “How to pay for this trip” sheet (section 4).

Changes on 8 October 2026: the home screen and Lock Screen widgets (section 2).

Changes on 7 October 2026: the notification after sharing on iPhone (sections 3 and 4).

Changes on 6 October 2026: what happens when you tap “Search ‘…’ in Google Maps” or “Open Google Maps” (section 2) and the optional statistics about sharing from Google Maps, in version 1.5.0 (section 4).

Changes on 3 October 2026: the controller is now named; the status of optional sharing was updated (in the app since version 1.1.0); website cookies and the age of consent were clarified; section 7 explains requests that concern random identifiers.