Your Pokémon GO journey, visualized.
Niantic keeps years of your trainer life — every catch, raid, friendship, step and purchase. You have the right to a free copy of all of it. POGO Metrics turns that raw export into a digestible summary & dashboard of your whole adventure.
Every file is parsed locally in your browser. There is no backend, no upload, no account. Your data never leaves your device.
→ Try it · → See a live example first
Getting your Pokémon GO data is easy. Understanding it is not.
What Niantic sends back is a zip of .tsv, .csv, .txt and .json files with names like
Sfida_capture1.csv and column headers like Fort_Latitude. Somewhere in there is the story
of every place you've played, every friend you've made, and every year you've put into the game
— but you'd need a spreadsheet and a free afternoon to see any of it.
POGO Metrics reads those files the way they actually are and gives you the story instead.
It also solves a smaller problem: requesting your export takes 3–5 days. Rather than leaving you staring at a "come back later" page, the site spends that gap teaching you exactly what Niantic holds on you, file by file, and how revealing each one is — so when the zip arrives you already know what you're looking at and can upload only what you're comfortable with.
That catalog is searchable down to Niantic's own column names: type latitude and it shows you
the two files that carry your coordinates, quoting the real Player_Latitude header back at you.
Filter by sensitivity, or by the files this site deliberately never reads.
Each file you drop in lights up its own chapter. Upload one file or the whole export:
| Chapter | Built from |
|---|---|
| Trainer card — level, XP, distance, collection by region, medal cabinet | Gameplay.txt |
| Your bag — what you're carrying, by kind, plus the eggs on your bench | Gameplay.txt |
| Adventure log — monthly timeline, hour-of-week rhythm, activity breakdown | Player_Journey/*.csv |
| Your rhythm — play sessions rebuilt from timestamps, and the stops and gyms you keep going back to | Player_Journey/*.csv |
| Your last day on the map — a minute-by-minute close-up of your most recent session, with the CP of the ones that got away | Gameplay.txt |
| Year over year — every year compared, plus a shareable recap card per year (downloadable PNG; single-year journeys get their card too) | Player_Journey/*.csv |
| Your world — a 3D globe of everywhere you've played, GPS trail, and remote-raid arcs | location files |
| Social — friendships over time, how you connect, who reaches out first | FriendList.tsv and friends |
| Spending — coin flow, top items, which storefront, free boxes and support gifts | InAppPurchases.tsv |
| Fitness — Adventure Sync steps and real-world equivalents | FitnessData.tsv |
| Photo album — every GO Snapshot you've taken, by month | ImageData.txt |
| Record book — your personal bests: biggest day, best month, longest streak, farthest raid | Player_Journey/*.csv |
| Behind the screen — sessions, devices, cities, countries, support tickets | app sessions, installs, support |
| Live events and Wayfarer contributions | tickets, wayfarer_player_data.json |
Nothing is required. Upload only FriendList.tsv and you'll get exactly the social chapter and
nothing else.
Once a dashboard is built, the toolbar above it offers:
- ▶ Play my story — a full-screen, tappable recap of your whole journey, one number at a time. Tap right for next, left to go back, Esc to close. It's also the demo page's main CTA.
- ⬇ Journey card — your entire journey as one shareable PNG: headline totals, a month-by-month chart with a legend, and auto-awarded badges. The Year-over-year chapter offers the same thing per year.
- 🧾 My numbers — a JSON dump of every figure the app computed, for anyone who'd rather have the data than the pictures. Location data is deliberately excluded — no GPS trail, no stop or activity coordinates, no cities, no countries. Those stay in the browser. Everything else, including your trainer profile, is in the file, so treat it like you would any personal export.
- + Add more files — drop in the rest of your export later and the new chapters appear alongside the ones you already have.
This is the whole point, so it should be checkable rather than promised:
- 100% client-side. Files are read with
FileReader/.text()and parsed in the browser. There is no server to upload to. Close the tab and it's gone. - No account, no tracking, no analytics, no cookies.
- No external requests at all. Chart.js, Leaflet, globe.gl, the fonts,
the globe textures and the country borders are all vendored into
vendor/. - Your locations are mapped, and nothing else sensitive is. The globe and the map are the
point, so they do plot where you played — on your device, published nowhere. Your email, IP
addresses and advertising IDs are never shown, charted, or written to any export. To be exact
about it: the browser hands the app whole files, so those columns pass through memory like every
other column — no parser extracts them, nothing renders them, and the
connect-src 'self'policy below means nothing could send them anywhere. The catalog on the landing page rates how sensitive each file is before you open it. - The browser enforces it. The deployed site ships a
Content-Security-Policywithconnect-src 'self'(seenetlify.toml), so no script — ours or otherwise — can fetch, XHR, WebSocket or beacon your data off-origin. (Precisely that:connect-srcgoverns those APIs, not navigation. Nothing here navigates with parsed data, but this section invites you to check it, so it should survive the check.) - It works in airplane mode. A service worker caches the pages, both stylesheets, every app script, the chart library and the Trainer Model's cohort data, so once you've visited, the app loads and parses an export — and the research layer draws — with no network at all. The 3D globe's assets are large and cache on first use instead, so the globe chapter needs one online build before it too works offline.
- You can audit all of it — it's ~6,000 lines of vanilla JavaScript in this repo, no build step.
In Pokémon GO: Poké Ball → Settings → Help → Chat with us → New Conversation → My account → Request my data → Continue. You'll get a download link and a password by email, usually within 3–5 days (Niantic allows up to 7). Unzip it, then drop the files in.
This is a free right under privacy laws like GDPR and CCPA — not a hack or a third-party service.
Static HTML/CSS/JS. No build step, no dependencies to install.
node pogo-metrics/static-server.mjs pogo-metrics 8770Then open http://127.0.0.1:8770/. A real HTTP server is needed because the globe textures and
map data load over fetch(), which file:// blocks.
pogo-metrics/ the deployed site (netlify.toml publishes this folder as-is)
├── index.html landing page + the file-by-file data catalog
├── metrics.html the app: drag in your export, get your chapters
├── demo.html live example, rendered from an anonymized sample
├── trainer-model.html the Trainer Model: a friends-list cohort vs. the level cap
├── js/
│ ├── app.js the engine — parsers + every chapter
│ ├── catalog.js knowledge base: one entry per file in a Niantic export
│ ├── catalog-ui.js the filterable catalog on the landing page
│ ├── nav.js shared top navigation
│ ├── pokedex.js name → National Dex map (gens 1–3)
│ └── trainer-model.js the Trainer Model dashboard engine
├── css/style.css the site-wide stylesheet — no preprocessor
├── css/trainer-model.css page-only styles for the Trainer Model, scoped under .tmodel
├── sample-export/ anonymized sample export (named for what it is, not for the
│ page that loads it — see netlify.toml on the name collision)
├── data/trainer-model/ the anonymized cohort JSONs behind the Trainer Model page
├── tools/scrub-demo.mjs regenerates sample-export/ from a real export
├── tools/test-parsers.mjs runs every parser against sample-export/ as a regression check
├── og-card.html source for the share image; render it to regenerate og-image.png
│ (og-card-demo.html / og-card-model.html do the same for their pages)
├── og-image.png 1200×630 Open Graph / Twitter card (+ -demo and -model variants)
├── 404.html branded not-found page (Netlify serves it automatically)
├── sw.js service worker: installable + fully offline-capable
├── site.webmanifest PWA manifest (+ favicon-32 / apple-touch-icon / icon-192 / icon-512)
├── robots.txt keeps the og-card pages out of search (sample export + cohort data are
│ excluded via noindex headers instead — see netlify.toml); sitemap.xml alongside
├── static-server.mjs tiny dependency-free static server for local preview
└── vendor/ Chart.js, Leaflet, globe.gl, fonts, geo — all vendored, lazy-loaded
sample-export/ is generated from a real export by tools/scrub-demo.mjs. Every name, email, order number,
IP, ad-ID, account ID and referral code is faked or dropped, support message bodies are removed,
cities and countries are remapped, and the big event logs are downsampled. Numbers, dates, medals,
species and timing are preserved so the story still feels real.
Coordinates are generated, not anonymized. No location in sample-export/ is derived from a real one.
The scrubber builds a synthetic world — one home city and seven travel cities — and assigns each
distinct real coordinate a place in it by how often it appears, never by where it is. Frequency
rank is the only thing that crosses over, and visit counts are already on screen in the app, so
nothing new is exposed. Two real stops that were metres apart routinely land on different
continents. What survives is the distribution that makes the sample worth looking at: one stop you
visit constantly, a long tail you don't, a home city, some travel, and raids far enough away to
count as remote.
The scrubber will not let you ship a half-anonymized demo: it records every identifier it replaces, then re-reads everything it wrote and fails — deleting the output rather than publishing it — if any of them survived, or if any email address, IP address, or real coordinate value appears anywhere. No real personal data is present, and that is checked rather than asserted.
node pogo-metrics/tools/scrub-demo.mjs "<path to an unzipped export>"Everything above is one player's story, told from their own export. trainer-model.html is the
population view: a real friends-list cohort — 390 trainers in a single snapshot from February
2025 (when the level cap was 50) and 493 trainers re-recorded across three sessions in August
2026 (under the new cap of 80) — plotted to show what the level cap does to trainer stats. It marks the project's
original straight-line level model honestly against reality, lets visitors benchmark their own
numbers against their level band, and keeps the two eras strictly separate, because the XP
rebalance made levels incomparable across them.
Because that second era was recorded more than once, it is also the only place a clock touches
this data: trainers seen in two sessions give a measured interval, published as an aggregate
pace block. It is reported as what happened in one short window — 8 of 213 re-recorded
trainers gained a level — and deliberately never extrapolated into a time-to-80.
The data ships in data/trainer-model/ as two JSONs. Handles are replaced with placeholder IDs
before the data ever enters this repo; every stat is real and unmodified. Per-level statistics
are withheld wherever fewer than five trainers share a level — at that size a "median" is just
one person's numbers, so publishing it would be neither an average nor anonymous. Like /sample-export/*,
the raw files are crawlable but carry an X-Robots-Tag: noindex header (see netlify.toml) so
they never surface in search results themselves.
POGO Metrics is one instrument in the Observation Deck — a fleet of small, live web tools built from a curious mind that loves to learn.
Independent fan project, made for the community. Not affiliated with, endorsed by, or sponsored by Niantic, Scopely, Nintendo, or The Pokémon Company. Pokémon and Pokémon GO are trademarks of their respective owners.