‹ Pulso

Pulso

Privacy Policy

Version 1.0 · Effective: 30 August 2026

Data controller: grAppe, Colombia — grappestudio@gmail.com Contact: grappestudio@gmail.com

Pulso is a free app that displays public rainfall, river-level, air-quality, weather and mobility information for the Aburrá Valley (Medellín, Colombia). This policy explains what data the app handles, why, and what choices you have.

This is a translation. The Spanish (Colombia) version at https://grappe-studio.netlify.app/pulso/privacy.html governs in case of any discrepancy.

1. Summary

2. Information you give us

Pulso has no accounts and no sign-up. There is one feature through which you can send us information, and you always start it yourself.

2.1 Suggestions and bug reports

From Settings → Send a suggestion or report a bug (also available in the Information tab) you can write to us. Before sending, the app shows you exactly what will be sent, with the real values, in an expandable block called "What gets sent".

Sent:

Not sent, deliberately:

Because no identifier is sent, we cannot tell which reports are yours, nor link them to you or to each other. That is intentional, and it has a consequence worth stating plainly: we also cannot retrieve or delete a specific report on your request (see section 8).

To prevent abuse, our server momentarily processes the IP address a report arrives from, solely to limit how many messages one origin can send. That address is not stored with the report; it becomes a one-way hashed value that changes daily and is discarded within hours.

Reports are kept for at most 400 days (see section 7).

2.2 Email

If you voluntarily email grappestudio@gmail.com, we process your address and message solely to reply to you.

3. Information collected automatically

Pulso uses Firebase services from Google LLC, acting as our data processor.

3.1 Crash reports (Firebase Crashlytics)

When the app crashes or logs an error, a report is sent containing the stack trace, device model, OS version, app version, memory and disk state, and a Firebase-generated installation identifier.

We attach three of our own keys so a crash can be reproduced: the active map layer (layer), the app version (app_version) and the device language (locale).

Purpose: fixing bugs. Legal basis: legitimate interest in keeping the app working.

3.2 Performance (Firebase Performance Monitoring)

App start time, screen rendering time and network request durations, with technical device and network data — all collected automatically by the SDK.

Pulso adds two traces of its own, which measure only durations:

TraceWhat it times
layer_time_to_datahow long a map layer took to show its data, tagged with which layer and whether the data came from the network, the on-device cache, a bundled file, or was already loaded
siata_refreshhow long one full data refresh took

Neither carries anything you typed, and neither carries your location.

This is covered by the same switch as usage analytics — Settings → Privacy → "Compartir estadísticas de uso" turns off performance collection too, including the automatic part described above.

Purpose: detecting slowness and failing requests.

3.3 Usage analytics (Firebase Analytics)

Pulso logs 47 events of its own. None of them contains anything you typed, and none contains your location or anything derived from it.

What it measuresEvents
Which layer or screen you are looking at, and for how longlayer_switch, layer_dwell, slot5_swap, bar_expand, screen_view, settings_open, info_open, alerts_open, splash_complete
What you tap on the mapcallout_open, map_sample, radar_play, radar_scrub, radar_jump_live, radar_expand, forecast_slot_change, air_submetric_change, bike_intent_change, bus_route_select, metro_line_reveal, transit_list_toggle
Whether the data actually loaded, so we can tell "all clear" from "we had no data"refresh, data_outcome, overlay_empty, notice_shown, layer_hidden_remote, rc_unknown_layer_key
How long things tookrequest_timing, layer_time_to_data
Whether alerts reach you and are usefulalert_banner_shown, alert_navigate, alert_dismiss, alert_pref_change, push_open, push_suppressed, push_permission
Permissions and preferenceslocation_primer_shown, location_result, home_zone_set, setting_change
App health and the version gateinfo_link_tap, diagnostics_open, feedback_open, feedback_submit, update_required_shown, update_required_tap, review_prompt_requested

Two of these deserve to be spelled out, because they are the ones you would reasonably worry about:

We also attach a small number of user properties to this install so the numbers can be read by segment: your appearance, temperature and units preferences, whether notification and location permission are granted, whether a home municipality is set (a yes/no, never which one), and which map layer this install uses most.

You can turn all of this off. Settings → Privacy → "Compartir estadísticas de uso". It is on by default, and switching it off stops Firebase Analytics collecting anything at all from this install, including the automatic events described in the next paragraph. Crash reports (§3.1) are separate and stay on, so that a crash you hit can still be fixed.

You should also know that the Firebase Analytics SDK itself collects, on its own and as standard, automatic events (first open, sessions, app update), device characteristics, and an approximate country- or region-level location derived from the IP address — not from GPS. That inference is made by Google, not by Pulso, and it does not give Pulso your location.

Events are associated with a Firebase app instance identifier. It is not linked to your name, email or any account, and it is reset if you uninstall and reinstall the app.

Purpose: understanding which parts of the app are used, to decide what to improve.

3.4 Remote configuration (Firebase Remote Config)

The app periodically fetches server-side configuration (which layers to show, whether there is a maintenance notice, whether alerts are enabled). The request transmits the installation identifier and technical device data. Nothing about your usage is sent.

3.5 Notifications (Firebase Cloud Messaging and APNs)

Pulso's alerts are topic broadcasts: the device subscribes, and the server publishes one message to all subscribers.

This has a deliberate consequence in your favour: Pulso does not store, transmit or keep any record of your device identifier. There is no device database, because topic delivery does not need one.

The topic name depends on what you choose on the Alerts screen:

⚠️ You should know what that implies. Pulso does not receive this, but the subscription is made with Firebase Cloud Messaging (Google), so Google can tell that this device listens for river alerts in a particular municipality. That is the price of your phone not ringing for alerts from the far end of the valley. If you would rather avoid it, save no places: with none saved the device subscribes only to the valley-wide topic, which says nothing about where you are.

Your operating system generates a notification token (FCM on Android, APNs on iOS) that stays on the device. It appears only in internal development builds, on the Information screen, so that a test notification can be sent by hand; copying it is an action you take, never an automatic one. Released builds do not show it on any screen.

3.6 App verification (Firebase App Check — iOS only)

In released builds, iOS uses Apple's App Attest to certify to our server that a request comes from a genuine copy of Pulso rather than a script. It is a cryptographic device check; it does not identify a person.

3.7 Location (a single reading, optional)

This section describes the only way Pulso can use your location.

What happens. The app may ask permission to take one position fix. On iOS this happens when you tap "Use my location" on the Alerts screen, and when you open the app on the forecast if permission was already granted. On Android it happens the first time you open the forecast, if you allow it. If you grant it, the app requests one position fix, compares it against the municipal boundaries bundled with the app, obtains the zone name — envigado, say — and discards the coordinate immediately.

Why iOS repeats it on open. Because a saved municipality goes stale: someone who moved, or who once tapped another municipality on the map out of curiosity, kept seeing that forecast forever even with location permission granted. Each reading replaces the last — they do not accumulate, none is stored, and none leaves the phone. What you choose by hand, in the picker or by tapping the map, wins for the rest of that session: your location does not argue with you.

If you do not grant permission, no municipality is selected. The app does not guess one, and it does not keep one it inferred from an earlier reading: the forecast opens with no municipality and the line "Selecciona un municipio primero" until you choose. One you picked by hand is kept, because it is not a guess.

What is kept: the zone name, on the device. What is never stored or transmitted: the coordinate, the altitude, the accuracy, the speed, the time of the fix, or any history. It is not attached to an analytics event, a crash report or a suggestion.

There is no continuous tracking. The app uses no background location, no geofences, no region monitoring and no significant-change updates. It asks for one reading, turns it into a name, and stops.

You can avoid it entirely. The same screen lets you pick places from a list of thirteen zones with no permission granted, and it works exactly as well on both platforms.

In Apple's privacy declaration this is declared as Precise Location, not Coarse Location, even though the app requests hundred-metre accuracy: that figure is a hint to the system, not a cap, and Apple requires declaring the most granular data the code could receive. On Android the app requests ACCESS_COARSE_LOCATION (approximate only), so the Play Data Safety form declares Approximate location.

4. Data stored only on your device

Never transmitted anywhere, and removed when you uninstall the app:

On Android, backups are disabled (allowBackup="false"), so none of the above is uploaded to Google Drive.

5. Third parties your device contacts directly

Pulso fetches data straight from the public sources. When it does, those servers receive — as in any internet request — your device's IP address and technical connection information. Pulso sends them nothing else.

ServerWhat forOperated by
siata.gov.co, geoportal.siata.gov.corain, radar, river levels, air quality, weatherSIATA / Área Metropolitana del Valle de Aburrá
www.metrodemedellin.gov.coMetro stations and linesMetro de Medellín
www.datos.gov.coopen datasetsGovernment of Colombia
api.citybik.esEnCicla stations and bike availabilityCityBikes (private provider)
Google/Firebase servicesanalytics, crashes, config, notificationsGoogle LLC
Google Maps SDK (Android only)the base mapGoogle LLC
MapKit (iOS only)the base mapApple Inc.

These third parties handle that data under their own policies, which we do not control:

Pulso has no official relationship with SIATA, the Área Metropolitana del Valle de Aburrá, Metro de Medellín or EnCicla. It uses their public data with attribution.

6. International transfers

Firebase processes and stores the data described in section 3 on Google servers outside Colombia, primarily in the United States. Google relies on standard contractual clauses and the applicable transfer frameworks. By using Pulso you accept this transfer, which is necessary for the crash-reporting and analytics services to function.

7. Retention

8. Your rights

Under Colombia's Law 1581 of 2012 and Decree 1377 of 2013, you have the right to know, update, rectify and delete your personal data, to request proof of the authorisation given, to be informed about how it has been used, to complain to the Superintendencia de Industria y Comercio, and to revoke your authorisation.

If you are in the European Economic Area or the United Kingdom, you also have the GDPR rights of access, rectification, erasure, restriction, portability and objection.

An honest caveat about exercising them: Pulso holds no data that identifies you, so in practice we cannot locate "your" data within analytics or crash reports, even if you ask. By design, it is anonymous with respect to you. What you can do, with immediate effect:

For any request or question: grappestudio@gmail.com. We reply within fifteen (15) business days, as required by Law 1581.

9. Children

Pulso is not directed at children under 13 and does not knowingly collect their data. There is no user-generated content, no messaging and no in-app purchases.

10. Security

All app connections use HTTPS. The app stores no credentials. Administrative access to the Firebase project is restricted and protected with two-factor authentication; the database rules permit only public read access to a single service-status document and deny all writes from clients.

No system is perfect: we cannot guarantee absolute security of any internet transmission.

11. Changes to this policy

If this policy changes materially, we will publish the new version at https://grappe-studio.netlify.app/pulso/privacy.html with an updated effective date and — where the change warrants it — announce it inside the app. Continued use after the effective date constitutes acceptance of the revised version.

12. Contact

grAppe Colombia grappestudio@gmail.com