‹ Pulso

Pulso

Privacy Policy

Version 1.4 · Effective: 19 October 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/es/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). For problems with alerts we also attach counts — how many alerts are shown, set aside or not yet sent, and how many zones you saved, never which ones — any setting the app could not recognise, and, when joining a notification topic failed, that topic without its zone (e.g. alerts_v2_river_zone).

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 59 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, 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
Whether sharing, the alerts reminder and the home-screen widget are usedshare_app, alerts_promo_shown, alerts_promo_action, widget_open
Which hazards the data put on screen, how the alert carousels and the warning button are used, and which notifications you choosealert_active, alert_carousel_shown, alert_carousel_swipe, alert_button_open, alert_panel_close, push_received, push_setting_change, push_scope_change, alert_place_change

Three 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), how it was set (by your location, from the list, by tapping the map, the Medellín Centro example, or none; never which one), whether a Pulso home-screen widget is installed (a yes/no), which map layer this install uses most, which kinds of alert you chose to be notified about (for example river rises and earthquakes), whether those notifications cover your zones or the whole valley, and how many zones you saved (a number, never which). On Android, Google Play tells Firebase how Pulso was installed: from the store itself, or the source, medium and campaign of the link that led there (for example a link on our website).

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's servers never receive, store or keep any record of your device identifier. There is no device database, because topic delivery does not need one.

The topics depend on what you choose in Settings → Notifications. Notifications are off until you switch a hazard on: until then alerts appear only inside the app, and the device is subscribed only to one general topic that every copy of Pulso shares, kept for exceptional announcements. Then:

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

To receive topic messages, the app obtains a notification token from your operating system (APNs, on iOS) and from Firebase Cloud Messaging (FCM, on both platforms). That token is sent to Google, because FCM needs it to deliver the messages of the topics the device is subscribed to; Pulso's servers never receive it. The app obtains it whether or not you have allowed notifications, so that alerts work as soon as you allow them. 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 (optional)

This section describes the only two ways Pulso can use your location: to find your zone, and to show where you are on the map.

When permission is asked for. On its own, the app asks only once: a few seconds after the forecast appears on screen, if it has never asked before, on Android and iOS. In addition, while it is not granted, Settings shows a location row: "Use my location" opens the system request and, if you already refused, "Turn on in phone settings" takes you to Pulso's page in the phone's settings. It can also be asked for, on both platforms, by tapping "Use my location" while adding or editing a zone (Settings → Notifications → My zones).

Your zone. With permission granted, the app takes one position fix each time it starts, and another right after you grant it. It compares that fix against the municipal boundaries bundled with the app, obtains the zone name (envigado, say) and discards the coordinate immediately.

Why it is repeated at start-up. 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 saved. The app does not keep one it inferred from an earlier reading. A few seconds after the forecast appears it shows Medellín Centro as an example, so the forecast strip describes a real place: that example is never saved, anything you choose replaces it, and neither the home-screen widget nor alerts use it. One you picked by hand is kept, because it is not a guess.

Your position on the map. With permission granted, every map shows where you are as a blue dot, with a lighter circle for how accurate the fix is and a cone for the direction the phone is facing. The direction comes from the phone's compass, which needs no permission of its own. To keep the dot current, the operating system updates the position while the app is open on screen; the updates stop when the app goes to the background. The position is only drawn: it is not stored, not sent anywhere, does not move the map, and is not used for the zone.

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

There is no tracking. The app uses no background location, no geofences, no region monitoring and no significant-change updates. For your zone it asks for one reading, turns it into a name, and stops; the map's dot lives only on screen, and nothing it shows is kept.

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. Without permission the maps simply show no dot.

In Apple's privacy declaration this is declared as Precise Location, not Coarse Location, even though the zone reading 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_FINE_LOCATION together with ACCESS_COARSE_LOCATION, so the system dialog lets you choose precise or approximate, and the Play Data Safety form declares Precise 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

13. This website

The pages under https://grappe-studio.netlify.app/pulso/ count visits with Google Analytics 4 (Google LLC, acting as our processor), and only if you accept the banner shown on your first visit. Nothing is set or sent before you choose, and nothing at all if you decline.

If you accept, Google Analytics sets its cookies (_ga and _ga_ followed by an identifier), limited to the /pulso/ pages and kept for about 13 months, and records the pages you view, how you arrived (a search engine, another website, a shared link), an approximate region derived from your IP address, your browser and device type, and clicks on links that leave the site, such as the App Store and Google Play buttons. Advertising features and Google signals are switched off. This data is kept for 14 months, and it is not linked to the app or to any app install.

Your choice is stored only in your browser. You can change it at any time from the Cookies link at the bottom of every Pulso page; withdrawing your consent deletes those cookies.