← psybertechno:geo

Privacy

This page was machine-translated from the Japanese original. If there is any discrepancy, the Japanese version takes precedence.

What gets sent, what stays on your device, and who it goes to. This isn't a general statement — it only describes what's actually in the code.

Applies to: v0.1.3 / Last updated: 2026-07-30

Summary

Device ID

The first time you open the app, a random UUID (v4) is generated and stored in your device's localStorage under the key ptg:device-id. This isn't authentication — it's an anonymous ID used only to attribute published content and for server-side rate limiting and abuse prevention. It isn't linked to a name, email, advertising ID, or anything similar.

Clearing your browser storage, or using a different browser or device, gives you a different ID (in environments where storage isn't available, such as private browsing, you get a disposable ID every time you open the page). Exporting/importing a backup carries this ID along with it.

What gets sent to the server

Sending only ever happens in the situations below. For each one, here's exactly what's sent and what's stored.

1. Publishing (PUBLISH)

Sent only when you explicitly PUBLISH from the EDIT MENU. What's sent:

  • The layer (AREA / SPOT) and the cell's ID and coordinates
  • The edited pattern (the actual content — steps, pitches, resolution, and so on)
  • Your tribe (RED / GREEN / BLUE)
  • The generator version
  • A key to prevent duplicate resends (an idempotency key)
  • The device ID
  • A Cloudflare Turnstile token (for bot detection)
  • If a position is available, that fix (latitude, longitude, accuracy, and time acquired)

Stored on the server (Cloudflare D1): the full revision described above (layer, cell ID, coordinates, sequence number, device ID, pattern, generator version, idempotency key, creation time, tribe), the position fix (latitude, longitude, accuracy), a flag for whether that fix could be verified as inside the cell, and the country code Cloudflare derives from the connecting IP. The country code is only recorded — it's never used as a reason to reject a request.

The position fix is used to confirm you're inside the cell, and the latitude/longitude are stored after that check. If no position is available, no fix is sent and it's recorded as "unverified".

2. Listen beacon

Staying in the same cell for a certain amount of time while playing sends a small signal reporting that "this cell was actually listened to." It resets the decay clock and builds the footfall heatmap.

What's sent: the layer and ID of the cell you listened to, and the device ID.

What's stored: only a per-cell aggregate (layer, cell ID, coordinates, running count, last time). The device ID is never written to the database — it's only used in memory for rate limiting while the request is processed, and disappears once the request finishes. There's no record of who listened where.

What's shown on the map: the footfall heatmap is never drawn finer than AREA (~250m across). SPOT-level footfall (~70m across) only ever reaches the map summed into the AREA that contains it, and the API refuses to serve it at SPOT granularity at all (zooming in changes nothing). SPOT aggregates keep being recorded for the decay clock, but they are not shown at a granularity that would read as "somebody was standing at that address."

The same thinking applies to time: the "last listened at" time that leaves the server is coarsened to the day (that day's 00:00 UTC). At millisecond precision it would be a record that "somebody was in this cell at 14:32." Decay is computed per day anyway, so rounding it changes nothing about what you hear. (PUBLISH times are not rounded — publishing is a deliberate, attributed act.)

3. Report endpoint

There is no report button in the app (a published cell holds no free text, image, or audio, so there is little real harm for a report to protect against, and the button was removed). The endpoint itself remains for operator/contact-driven reports and for future journey reports. If it's ever used, what's sent: the target layer and cell ID, the device ID, and an optional reason. What's stored: the same, plus the time received and its handling status. See Help for details.

4. Sharing a journey

A journey contains your entire GPS track. Whoever receives your shared link can replay exactly the route you walked. That can reveal your home, workplace, or commute.

Sharing always requires an explicit action from you, and a privacy confirmation dialog always appears first. Simply recording or saving a journey sends nothing.

What's sent: a gzip-compressed stream of the journey's events (your GPS and listening path, a snapshot of the pattern and timbre for each cell, jumps made by tapping the map, edits made during recording, PLAY / STOP), plus the title, start time, duration, event count, device ID, and a Turnstile token.

What's stored: the journey itself in Cloudflare R2, with metadata (ID, title, start time, duration, event count, size, device ID, creation time, takedown status) in D1. The device ID here is deliberately kept so misuse can be moderated.

The share ID is a random 12 characters. Anyone with the link can play it back.

5. Loading the world

These are requests to load the reference time for playback sync, and published data for whatever range is currently shown. The device ID is never sent. All that's sent is the coordinates of the region needed. That said, since this is still a network request, Cloudflare does see your connecting IP address and the request time.

Retention and deletion

What stays on your device (never sent unless shared)

Clearing your browser's site data erases all of this (anything already published, or any journey already shared, remains on the server).

About location

Third parties reached just by opening the page

These connections happen just from loading the page, without you doing anything. Each of them receives your IP address and basic browser information (such as the User-Agent).

Cloudflare (hosting, API, and data storage)
Handles delivering the site, the API, and storage in D1 and R2. It receives your IP address, connecting country, and a record of the request.
Cloudflare privacy policy
Cloudflare Turnstile (bot detection)
Bot protection used only for PUBLISH and journey sharing. The script only loads the first time you enter EDIT mode — it never loads if you're just listening.
Cloudflare privacy policy
CARTO (map tiles) / OpenStreetMap (map data)
The map's background imagery loads from CARTO's delivery servers. Which area of the map you're viewing (tile coordinates and zoom) is sent along with your IP address. The map data itself comes from OpenStreetMap.
CARTO privacy policy / OSM Foundation privacy policy
Google Fonts
The app itself loads a pixel font for the UI. The explanation pages — Help, Privacy, and Donation links (including this page) — also load a body typeface (LINE Seed JP). Both are loaded from fonts.googleapis.com / fonts.gstatic.com, which sends Google your IP address and browser information.
Google privacy policy
unpkg (CDN)
Loads the stylesheet for the Leaflet map library from unpkg.com. It receives your IP address and browser information.
Cloudflare Zaraz / Google Analytics (analytics)
Loaded to measure usage, only once consent has been given. Details, and exactly where the line is drawn on never sending location and similar data, are in the Analytics section.

Nothing else reaches out externally. There are no ad networks, no social-media tracking pixels, and no A/B testing tools.

Analytics (Google Analytics)

We use Google Analytics 4 (GA4) to understand usage across the whole site. It's delivered through Cloudflare Zaraz, rather than an analytics tag embedded directly in the app's code.

Your location (GPS), the music you edit, and the contents of your journeys are never sent to analytics.

Analytics only ever sees the granularity of "a page was viewed." Cell IDs, latitude/longitude, journey contents, and the device ID (ptg:device-id) above are never sent as analytics event parameters or custom dimensions. They only ever reach our own APIs listed above.

What analytics collects

All that rides along with these events is a fixed choice and a small number, like the ones in parentheses above. It's implemented so that free-text input or identifiers simply can't be passed through.

How URLs are handled — differs between info pages and the app itself

We record the URL to know which page was read, but this site has two kinds of pages with very different characters, so they're handled differently.

Information pages (this Privacy page, Help, Donation links)

The URL is recorded as-is (/help/, /privacy/, /support/). This is so we can tell which explanation page was read. These URLs contain no location — they only reveal which page was opened.

The app itself

The app's URL contains your current cell (/{zone}/{area}/{spot}) — the URL itself is a coordinate. So before an app page view is sent to analytics, it's replaced with a constant value, / (the site's root), with the cell part stripped out. All that's recorded is "the app was opened" — this coordinate never reaches analytics.

The address bar's URL is rewritten every time you walk into a new cell, but that rewrite is never sent to analytics either.

In short, all that's recorded is which of the information pages was read — where you were in the app can never be reconstructed from any page-view record. This handling is what keeps the promise made at the top: your location, the music you edit, and your journey contents are never sent to analytics.

About consent

Consent for analytics is managed by Cloudflare Zaraz's consent tool. Visitors from applicable regions are asked to confirm consent before analytics starts running. You can change or withdraw your consent at any time from the same consent banner (reopen it from the settings link shown on screen). Withdrawing stops all further analytics.

Cookies / identifiers used by analytics

Google Analytics uses a cookie (such as _ga) or an equivalent local identifier, to count visits from the same browser together. These are entirely separate from this app's own device ID (ptg:device-id), and the two are never linked. The device ID never reaches analytics, and no analytics identifier is ever tied to this app's world data.

Reference links: Google privacy policy / How Google Analytics uses data / Cloudflare privacy policy (Zaraz)

Cookies

The app's own state (drafts, settings, journeys, and so on) is stored in localStorage / sessionStorage / IndexedDB, not cookies. Cookies are used only for the analytics above and its consent management. Other third parties may also set their own cookies.

Use by children

There are no accounts or payments, and we never collect names or contact details. That said, since the app handles location data, a parent or guardian should be involved in deciding whether a child uses it. Sharing a journey in particular hands over the exact route walked.

Requesting removal or correction

Changes

If we change the content, we'll update the "Last updated" date on this page.