Credits & Info
What is hailsDotGO?
hailsDotGO is a fan-made toolkit for Pokémon GO players: raid counters, DPS calculations, PvP IV rankings, a full shiny Pokémon dex, a personal shiny collection tracker, a Trainer Directory, and a live Raid Finder for coordinating remote raids with other players.
The site is not affiliated with Niantic, The Pokémon Company, or Nintendo.
Data Sources
- PoGoAPI: Pokémon stats, moves, type effectiveness, shiny availability, CP multipliers
- LeekDuck via pokemon-go-api: current raid bosses
- PokeMiners: mined costume art for the shiny dex, served from our own cache
- WatWowMap Masterfile: costume and form names behind the costume picker
- Dittobase: cross-checking costume names and release events
- snacknap via pokemon-go-api: Max Battles
- LeekDuck via ScrapedDuck: current and upcoming event data, full event details, and event images, from LeekDuck
- PokéAPI: Pokémon sprites, Pokédex flavor text, genus, legendary/mythical flags, in-game cries, and official localized Pokémon names
- Open-Meteo: current weather data used to determine Pokémon GO weather boosts
- Pokémon Showdown: trainer class and named character sprites for the Classic avatar set
- Dreamstone Mysteries (dsmyst): GBA-style trainer sprites for the Dreamstone avatar set
- pokeemerald-expansion (Rom Hacking Hideout): FRLG-style trainer sprites for the pokeemerald-expansion avatar set
- pret/pokeplatinum: native Gen 4 Diamond/Pearl/Platinum trainer sprites for the Platinum avatar set
Project
- Built with Go, chi, and TypeScript
- Hosted on hails.cc
- Open source: github.com/Hailey-Ross/hailsDotGO
- Documentation: github.com/Hailey-Ross/hailsDotGO/wiki
Public API
The following endpoints are publicly accessible and return game data as JSON. Two limits apply per IP: a per-endpoint request rate limit and an aggregate bandwidth cap across all endpoints in this table combined.
| Endpoint | Description | Rate Limit |
|---|---|---|
GET /api/data | All game data in one payload (Pokémon, moves, raids, shinies, type chart, CP multipliers) | 10 / 2 min per IP |
GET /api/raids | Current raid bosses by tier | 10 / 2 min per IP |
GET /api/maxbattles | Current Max Battle bosses by tier | 10 / 2 min per IP |
GET /api/events | Current and upcoming events (LeekDuck via ScrapedDuck) | 10 / 2 min per IP |
GET /api/events/{id} | Full details for one event (sanitized HTML from LeekDuck) | 30 / 2 min per IP |
GET /api/pokemon | Pokémon base stats list | 10 / 2 min per IP |
GET /api/moves | Fast and charged move data | 10 / 2 min per IP |
Bandwidth limit: 15 MB total across all endpoints per 5-minute window. Exceeding this triggers a 30-minute block.
All responses include Cache-Control: public, max-age=300. Game data refreshes every 6 hours; events every 30 minutes; raid bosses every 4 hours on Mountain Time.
Community Data
These endpoints return per-user profile data. No rate limit applies, but profile-scoped endpoints respect privacy settings and return an empty result rather than an error when data is not visible.
| Endpoint | Description |
|---|---|
GET /api/awards | Full awards catalog with names, descriptions, and icons |
GET /api/awards/of/{username} | Awards earned by a specific user |
GET /api/shinies/of/{username} | A user's public shiny collection; empty array if their profile is private or they have hidden their collection in Settings |
Private API
The private API is intended for trusted server-side consumers. It exposes the same data as the public API with no rate limiting, but requires an account with API access granted by the site superadmin.
| Endpoint | Description |
|---|---|
GET /api/private/data | All game data (same as public) |
GET /api/private/raids | Current raid bosses (same as public) |
GET /api/private/maxbattles | Current Max Battle bosses (same as public) |
GET /api/private/events | Events feed (same as public) |
GET /api/private/events/{id} | Full event detail (same as public) |
GET /api/private/pokemon | Pokémon base stats (same as public) |
GET /api/private/moves | Move data (same as public) |
POST /api/refresh | Force an immediate refresh of all cached game data (rate-limited to 2 per 10 minutes globally) |
Authentication uses your session cookie. Contact the site operator if you need access.
Mobile API
The companion mobile app uses a versioned /api/mobile/v1 prefix so its routes stay stable as the web API changes. Game-data endpoints are open; everything else authenticates with a Bearer token returned by the login endpoint (the same session token the website uses).
Authorization: Bearer <your-token>
| Endpoint | Description | Auth |
|---|---|---|
POST /api/mobile/v1/auth/login | Exchange username and password for a Bearer session token (rate-limited to 5 per minute per IP) | None |
DELETE /api/mobile/v1/auth/session | Log out and invalidate the current token | Bearer |
GET /api/mobile/v1/auth/me | Current user profile, including trainer level | Bearer |
PUT /api/mobile/v1/profile | Update trainer name, code, level, avatar, pronouns, and location | Bearer |
POST/DELETE /api/mobile/v1/push/token | Register or unregister a device push token for raid notifications (FCM on Android, APNs on iOS) | Bearer |
GET /api/mobile/v1/data, /pokemon, /raids, /events, /raid/overview | Stable versioned mirrors of the public game-data endpoints | None |
POST /api/mobile/v1/iv/calculate, /iv/ocr | Run the IV calculator, or upload a screenshot for OCR (10 per minute per IP) | Bearer |
GET/POST/DELETE /api/mobile/v1/iv/pokemon | Save, list, and delete Pokémon in the user's IV box | Bearer |
/api/mobile/v1/raid/* | Full Raid Finder lifecycle: queue, lobbies, confirm, leave, kick, invite, report, and feedback | Bearer |
These endpoints back the official companion app. See the project wiki's API Reference for full request and response details.
Usage Notes
- All endpoints return
application/json. - Exceeding the public rate limit returns
429 Too Many Requests. - Private endpoints return
403 Forbiddenwithout a valid API-access session. - This is an unofficial fan-made toolkit; endpoints may change without notice.
A running log of updates and improvements.
A new home: pogo.hails.app
- The site has a new address, pogo.hails.app. It is the same tools, the same account and the same data, just a tidier name to type
- Your old bookmarks still work: every pogo.hails.live link now forwards to the matching page on pogo.hails.app, so nothing you saved is lost
- If you subscribe to the events calendar it keeps working unchanged, and any emails from us (like a password reset) now come from the new address
Costume names added by staff now make it back into the site
- When a new costume is given a name in the admin panel it goes live straight away, and the site quietly files that name back into its own costume list so it survives the next rebuild. That filing step was rewriting the entire list every time instead of adding the one new line, which left it too tangled to go through at all
- It now adds just the new name and leaves every other entry byte for byte as it was written, so the list keeps the order and the notes it was curated with
- A name that has already been filed is no longer filed a second time, and the request tidies itself away once there is nothing left to file
A Wiki link in the sidebar
- The sidebar now has a Wiki link that goes straight to the project's documentation, covering everything from setting up your own instance to how roles, translations and the API work
- It opens in a new tab, so whatever you were in the middle of stays where you left it
- The link is there whether or not you are signed in, since the guides are just as useful before you make an account
Shiny Collection: the event box now suggests the events actually running
- The event box on a shiny now suggests real events as they happen, straight from the same live feed the Events page uses, so something like "Special Anniversary Pikachu Celebration" is there to pick the moment it starts instead of waiting for the list to be updated by hand
- Current and upcoming events are listed first, since a shiny is usually logged during the event that produced it, with the familiar categories like Community Day and GO Fest kept underneath
- Only events worth tagging a catch with are suggested: Raid Hours, GO Battle League cups and GO Pass are left out to keep the list short, and the general "Raid Hour" and "Spotlight Hour" entries still cover those
- Added the recurring formats the list never had: Ultra Unlock, Hatch Day, Max Battle Day, Choose Your Path, Wild Area and City Safari
- The box is still free text, so you can type any event you like, and anything you have already saved keeps exactly the name you gave it
Shiny Collection: the companion app can now manage your shinies
- The mobile companion app can now read and update your shiny collection directly: list what you have, add a new catch, edit an entry, evolve it, or remove it, all against the same collection you see here on the site
- Every shiny the app shows carries the right artwork: costume, regional form and Vivillon or Unown pattern sprites are resolved by the site, so what you see in the app always matches your collection and its checklist
- The app's region and catch method pickers are fed from the site too, so a new region or method added here shows up in the app without an update
Events: add events to your calendar
- The Events page can now feed straight into Google Calendar, Apple Calendar or any other calendar app. Open the "Subscribe to calendar" panel, tick the kinds of events you care about (Community Day, Spotlight Hour, Raids, GO Battle League, Research, or simply Everything), then copy the link or add it to Google in one tap
- You can also add a single event on its own, without subscribing to the whole feed. Open any event and use "Add to Google Calendar" or download it to the calendar app on your phone, so an upcoming Kyogre raid takes a tap or two to save and set an alarm for
- Times come through correctly for wherever you are: local events like Spotlight Hour show at 6pm your time, while worldwide events stay pinned to the real global moment, so the alarms you set actually go off when they should. The calendar refreshes itself as new events are announced, so once you have subscribed you never have to touch it again
Shiny Collection: Scatterbug remembers its pattern through evolution
- A Scatterbug or Spewpa can now be tagged with its Vivillon pattern in your collection, the same way you set a regional form. It still looks like a plain shiny Scatterbug or Spewpa (they are identical whichever region they came from), but the pattern is remembered
- When you press Evolve on a tagged Spewpa, it turns into the matching Vivillon pattern automatically, so an Elegant Scatterbug you caught from Japan becomes an Elegant Vivillon without you having to pick the pattern again. The pattern carries the whole way up the line
- Tagging a Scatterbug with a pattern does not split it into its own card: the single Scatterbug card still ticks and counts as before, so nothing you have recorded changes
Shiny Collection: every Vivillon pattern is its own card
- Vivillon now has a card for all 20 of its wing patterns (Meadow, Polar, Elegant, Icy Snow, Continental, and the rest, right through to the event only Fancy and Poke Ball). Each pattern is ticked, counted and searched on its own, so the Missing tab tells a shiny Vivillon hunter exactly which patterns are still out there
- Every pattern shows its own artwork on the checklist, in your collection and on your public profile, and hovering a card names the real world region that pattern is collected from (Elegant is Japan, Garden is the UK and Ireland, and so on)
- A plain Vivillon card is still there for a catch whose pattern you never noted, and anything you already recorded is untouched. Scatterbug and Spewpa stay a single card each, because they look the same whichever region they came from: only Vivillon shows the pattern
Shiny Collection: Unown is tracked letter by letter
- Unown now has a card for every form it comes in: A to Z, plus the exclamation mark and the question mark. Each one is ticked, counted and searched on its own, so the Missing tab finally answers the only question a shiny Unown hunter actually has, which is which letters are still out there
- Every letter shows its own artwork, on the checklist, in your collection and on your public profile, so a shiny Unown F no longer looks exactly like a shiny Unown G
- A plain Unown card is still there for a catch whose letter you never wrote down, and anything you have already recorded is untouched. If you do remember the letter, you can set it on the entry in your collection at any time and it will move to the right card
Trainer pages: tap a shiny to see the story behind it
- Clicking any shiny in a Shiny Collection, yours or another trainer's, now opens it larger along with everything that trainer recorded about it: how it was caught, the costume it is wearing, the event it came from, whether it is Shadow or Purified, its regional form, when it was caught, and whether it was evolved. Only the details they actually filled in are shown
- The catch date is now yours to set, both when you add a shiny and afterwards from your collection. Until now the site quietly recorded the day you added the entry, which is not the same thing at all if you log a catch a few days later. Existing entries keep the date they have unless you change it
- On your own profile, the detail view has a link that takes you straight to that exact entry in your collection and highlights it, so you do not have to hunt through a long list to fix a typo
Shiny Collection: the Visor costume is live, and costume art now comes from us
- The Visor costume (the Kanto starters and their evolutions, so a visored Charmander evolves into a visored Charizard) is now in the picker. It turns out the art had existed since 2020 all along: we had recorded the wrong internal code for it and were checking an image source that had quietly stopped updating back in April, so the costume was switched off for no reason. If you caught one, it will render properly now
- Costume art is no longer loaded from someone else's server. Sprites are fetched once, cached here, and served from pogo.hails.app, so browsing the shiny dex no longer sends a request per costumed Pokemon to a third party
- Costume data is now derived from the game's own mined assets rather than typed in by hand. Which Pokemon can wear a costume, and whether its shiny exists at all, are read straight from the art that Niantic ships, so a costume can no longer be listed for a Pokemon that never had it, and a missing sprite can no longer hide behind a plain shiny
- Six costumes that had been sitting unlabelled are now available: the Marathon Visor, Fossil and Willow's Lab Coat Pikachu, the three team caps from GO Fest 2026, and Caterpie's Poke Ball Hat
Shiny Collection: four costumes were showing the wrong art, and 43 more are now available
- Costume names are now cross-checked against a second source, and it immediately caught four costumes that had been pointing at the wrong artwork for months. If you recorded a Detective Hat Pikachu you were being shown a straw hat, and a Flower Crown Pikachu was showing the detective hat. Both now render the costume you actually picked. Dawn's Hat was pointing at Rei's cap, so Dawn's Hat has been corrected and Rei's Cap has been added as its own costume
- Two Pikachu costumes that were sharing a name have been separated: the plain straw hat and the summer hat with sunglasses are now distinct entries
- 43 costumes that the game had but we had never named are now in the picker, including the World Championships caps, the Flying Pikachu balloon set, the GO Fest 2025 goggles and monocles, Armored Mewtwo, Lucas's and Dawn's hats on the Sinnoh starters, and the Day of the Dead crowns
- Nothing you have already recorded was renamed. Every existing costume label still works exactly as before
Admin: a Costumes tab, so new costumes stop going unnoticed
- Admins get a new Costumes tab listing every costume the game has that has not been named yet, each shown with its real shiny artwork. A costume with no name cannot appear in the picker, so this list is the backlog of costumes nobody can record yet. Seeing the art matters: the game's internal names are misleading, which is exactly how four costumes ended up pointing at the wrong picture
- Costumes can now be named right there in the panel, and the new name is available in the shiny checklist immediately, with no update to the site needed. A costume that is not really a costume (the Gimmighoul coins) can be dismissed from the list in the same way
- Clicking a costume's picture opens it at full size, on every Pokemon that can wear it, without leaving the page. Most costumes are shared across a whole family, and the small preview only ever showed the first one, which is not much to go on when the name you pick is the one everyone will use
- A "Fetch new costumes" button checks the game's asset data for costumes that have not been picked up at all yet, so a new event no longer has to be spotted by hand
- The data health panel used to report costumes as in sync while costumes were sitting unnamed and unusable. It now says how many are waiting
Shiny Collection: more alternate forms, and a fixed add screen
- A dex wide audit filled in the alternate battle forms that were still missing their own checklist card: Dusk Mane and Dawn Wings Necrozma, Crowned Sword Zacian, Crowned Shield Zamazenta, Black and White Kyurem, and Resolute Keldeo
- Several non legendary form families gained cards too, each tracked and counted separately from the default form: Midnight and Dusk Lycanroc, Sandy Cloak and Trash Cloak Wormadam, Low Key Toxtricity, Pom-Pom, Pa'u and Sensu Oricorio, Blue-Striped and White-Striped Basculin, and Wash Rotom
- The add screen no longer overflows the page. When a Pokemon has extra forms to preview (like Primal Groudon), those sprites now sit in a tidy "Other forms" dropdown you can show or hide, and any tall add screen scrolls instead of running off the top and bottom of the window
Shiny Collection: GO Fest 2026 Pikachu Visor queued up
- The Pikachu Visor costume from GO Fest 2026 (the Kanto starters and their evolutions, so a visored Charmander evolves into a visored Charizard) is now recorded in the costume tables, but it is switched off for the moment. The game asset source we pull costumed shiny art from has not published the visor sprites yet, so offering it would only ever show a plain shiny. It will light up in the picker as soon as that art lands
Shiny Collection: shared costumes render for every eligible Pokemon
- Event costumes that were handed out to many species (Party Hat, Flower Crown, Cherry Blossom, Sunglasses, Flower Hat, Holiday Wreath, Witch Hat, Fashion Outfit, and more) now show their costumed shiny sprite on every Pokemon that actually received them, so a Party Hat Venusaur finally wears its hat
- The costume picker now suggests a costume only for the species that truly have it, checked against the live game asset list, instead of offering the same three generic options to everything
- Costumed sprites now also appear on public trainer profiles, not just your own collection page
Shiny Collection: costume sprites overhauled
- Party Hat Wurmple now renders its costumed shiny sprite, and Eevee and Pikachu gained their GO Fest Sun Crown and Moon Crown sprites
- Every offered costume was cross checked against the live game asset source and, where needed, against the actual sprite art. Three costumes that were showing the wrong picture are fixed: Sunglasses Squirtle now shows the real sunglasses, New Year Slowpoke now shows the "2020" glasses, and Gardevoir's costume is now correctly labelled Meloetta Hat
- Pikachu picked up a large batch of real costumes that now render, including World Cap, Original Cap, Rayquaza, Charizard, Lucario and Umbreon Hats, Meloetta Hat, Cherry Blossom, Ph.D., Clone, Mimikyu Costume, Flying Pikachu, Cap's Hat, the regional shirts (Green, Purple, Batik, Kurta, Saree) and the five gemstone Crowns. Snorlax gained its Studded Jacket, Slowbro and Slowking their New Year outfits, and Raichu its Original Cap
- Options with no real costumed shiny art were removed so the picker only suggests costumes that actually render: Sealeo and Walrein Festive Outfit, Luxio and Luxray Fashion Outfit, Caterpie Cowboy Hat, costumed Ditto, and a handful of Pikachu suggestions with no released shiny art (Ash Hat, Red's and Leaf's Hat, Dracula, Team Instinct and Team Mystic caps)
Shiny Collection: alternate battle forms added
- Tornadus, Thundurus, and Landorus now show a second checklist card for their Therian form with the correct shiny sprite, tracked and counted separately from the default Incarnate form
- A follow-up audit added the remaining shiny-released battle forms as their own cards: Deoxys (Attack, Defense, Speed), Origin Giratina, Origin Dialga, Origin Palkia, and Sky Shaymin
- Each form works everywhere regional forms do: the selector on every entry, evolving, and the form badge and sprite on public trainer profiles
Shiny Collection: event tags brought up to date
- The event tag suggestions when logging a shiny now include every Pokémon GO season from launch through the current Forever Forward, listed in order, plus GO Tour: Kalos and the Road of Legends event
- Your existing tags are untouched; the seasons are just easier to pick from a complete, ordered list
IV Calculator: smarter screenshot scanning
- Scans no longer need the appraisal screen: the level arc is now read with the same math the game uses (recalibrated against real reference screenshots), so a scan of the plain stats screen resolves the level directly
- Dust costs are matched fuzzily: lucky, shadow, and purified discounts are recognized automatically, so a purified Pokémon showing 5,400 dust now finds its true level bracket instead of failing
- Nicknamed Pokémon are identified from their candy line: a Machamp named "John Cena" is recognized via its Machop candy and its stats
- If the CP digits are misread or hidden behind the Pokémon, the arc level rescues the search instead of returning no matches
- Fixed the stardust table for levels 41 to 50 (some costs were wrong, so legitimately powered-up Pokémon could return zero results), removed an incorrect level cap for powered-up Pokémon, and corrected shadow dust handling
- Best Buddy boosts are detected: if a scan only makes sense one level higher, results say so instead of failing
- Manual calculator: enter the dust cost exactly as shown in game; the status buttons (lucky, shadow, purified) now handle the discount for you
Shiny Collection: regional forms are now first-class
- Alolan, Galarian, Hisuian, and Paldean forms now appear as their own checklist cards with the correct shiny sprites, so Hisuian Growlithe and Kanto Growlithe are tracked (and counted) separately
- Every entry has a new region selector, so shinies you logged before this update can be edited to record which form they are; shadow and purified still combine freely with a region
- Evolving now understands regional lines: a Galarian Meowth offers Perrserker (not Persian), an Alolan Rattata evolves into an Alolan Raticate, and forms that could not evolve (base Qwilfish, base Linoone) no longer offer wrong targets
- Public trainer profiles show region badges and the proper regional shiny sprites
Shiny Collection: 21 missing Pokémon added
- A full audit of the shiny checklist against every Pokémon shiny-available in Pokémon GO found 21 missing entries, including the complete Scorbunny and Sobble evolution lines; all 21 are now in the list
- Also added: Honedge, Doublade, Aegislash, Hawlucha, Klefki, Diancie, Sizzlipede, Centiskorch, Mr. Rime, Ursaluna, Toedscool, Toedscruel, Varoom, Revavroom, and Orthworm
- The gaps came from the upstream data source, which had stopped tracking new shiny releases; the site now carries its own curated corrections that survive every data refresh, so future upstream gaps can be patched immediately
Trainers: cards link straight to profiles
- Clicking a trainer card in the directory now opens that trainer's full profile page instead of a popup; profile pages show everything the popup did and more
Account: email confirmation at signup
- New accounts receive a confirmation email with a 24 hour link; a small banner reminds you until the address is confirmed, with a one-click resend
- Nothing is locked while unconfirmed: every feature keeps working, the banner is just a nudge
- Accounts created before this feature are treated as already confirmed
Account: self-service password reset by email
- Forgot your password? The login page now links to a reset form: enter your account email and a one-time reset link (valid for one hour) is sent to you
- Completing a reset signs you out on all devices, so an old or stolen session cannot survive a recovery
- Reset links are single-use and stored only as secure hashes; requesting a new link invalidates older ones
- Signup now validates the email address format on the server, so mistyped addresses are caught before the account exists
Admin: Check/Run Scrapers button
- The Site Stats tab has a new Check/Run Scrapers button beside Force Data Refresh that fetches every scraped source right now (raids, max battles, events, and all PoGoAPI/PokeAPI data) and reports per source whether it is reachable, parses without errors, and matches the live upstream data
- Unlike Force Data Refresh (which only covers the PoGoAPI game data and Pokémon names), this also runs the raids, max battles, and events scrapers, and applies any changed data immediately
- Results show inline as a table: an OK/ERROR badge per source plus item count, payload size, and whether the data was already in sync or freshly updated
Admin: cleaner, grouped dashboard navigation
- The admin dashboard's long row of tabs is now a grouped sidebar, with related tools organized under named sections: Site Config, Users & Moderation, Community, Localization, Raids, and System
- On phones the sidebar collapses into a single dropdown that shows the current section and expands to the grouped list when tapped
- All existing tools and permissions are unchanged; only the layout and navigation were reorganized
Admin: edit canned responses and labels for bug reports
- Admins can now edit existing canned responses and custom labels in the Bug Reports tools, not just create or delete them; click Edit to reuse the add form, then Save changes
- Built-in labels stay protected: they cannot be edited or deleted, but a new Duplicate button copies a built-in's name and colour into the add form so you can spin off your own variant
Mobile API: rate limiting on all endpoints
- The
/api/mobile/v1public game-data endpoints (/pokemon,/raids,/events,/data) now carry the same per-IP rate limit as the legacy web API;/raid/overviewgets a looser polling-friendly limit - Authenticated mobile endpoints gained a baseline per-IP abuse ceiling on top of the existing token auth, closing the gap where only the OCR endpoint was throttled
Shiny Collection: search now finds the whole evolution line
- Searching any member of an evolution family now shows the entire line, not just the one you typed: searching "Deino", "Zweilous", or "Hydreigon" returns all three
- Branching families work too: searching "Eevee" surfaces Eevee and every Eeveelution
- Applies to both the full grid and your caught list
API docs: Mobile API now listed on the Credits page
- The Credits page API tab now documents the versioned
/api/mobile/v1companion-app endpoints alongside the public, community, and private tiers - Corrected the project wiki's API Reference to name the CSRF cookie
_pogo_csrf
Translations: your edits are kept across updates
- Your in-progress and approved translations are preserved across site updates; a deploy never discards pending submissions or approved strings
- Approved translations are now backed up to our code repository automatically, so they are safe even if the server is rebuilt
- If an English source string is later reworded, your translated text is now archived and recoverable instead of being dropped
Trainer Sprites: new Pokémon Platinum avatar set
- Added a Pokémon Platinum (DS) set: 105 native Gen 4 Diamond/Pearl/Platinum trainer sprites including Cynthia, every Sinnoh gym leader and Elite Four member, Team Galactic (Cyrus and commanders Mars/Jupiter/Saturn), the Battle Frontier Brains, and the DP player characters
- All 105 new sprites are fully searchable by name, role, type, region, and gender in the avatar picker
Sidebar navigation redesign
- Every sidebar link now has its own icon, and the menu is grouped into clear "Tools" and "Account" sections with subtle labels
- The page you are on is highlighted with a rounded accent pill instead of a thin edge line, so it is much easier to see at a glance
- Polished the brand header, spacing, and scrollbar for a cleaner overall look
Self-hosting: database migration tool
- New
cmd/migratetool upgrades an existing install to the latest schema automatically; it tracks applied migrations in aschema_migrationstable and runs only what is pending, replacing the manual "apply sections by hand" process - First run baselines your database at its current version (
go run ./cmd/migrate -from v0.1.3a); after that a plaingo run ./cmd/migrateapplies any new migrations
Player Reports: flag bad actors
- A small report flag now sits next to trainer names across the site, and every Trainer Profile has a "Report Player" button, so you can flag spoofers, scammers, harassers, and other bad actors
- Pick a reason and add details; the report goes privately to our moderation team and the reported player is never told who reported them
- You can follow up with staff on your own report from the Reports page, and if your report leads to action you will be notified that you helped keep the community safe
Bug Reports: report issues right from the sidebar
- A new red bug button at the bottom of the sidebar opens a quick report form: tell us what broke and our staff picks it up
- Each report becomes a private conversation: a red "Reports" link appears above Social while you have an open report, opening a two-pane messenger where you and staff can talk it through
- You can invite up to four other users into a report; staff can apply labels, leave internal notes, change status, and loop in other team members
- Replies notify you on mobile, and reopening a resolved report is as simple as sending another message
Bug Reports: staff triage upgrade
- Your "Reports" link now stays in the sidebar after you have ever filed a report, and your list separates Active tickets from Closed & Resolved ones
- Every ticket now carries a clear reference number, and you can mark your own report resolved, reopen it, and rate how it was handled once it is closed
- Staff get real triage tools: sort by status, opener, priority, or who the ticket is waiting on, filter by assignee, and search across ticket text
- Staff can assign tickets to a team member, set priority, and insert reusable canned responses for faster replies
Trainer Sprites: keyword search expansion
- Avatar picker now supports rich keyword searches: type specialty ("fire", "dragon", "ghost"), role ("gym leader", "elite four", "champion", "rival", "villain", "professor", "kahuna", "trial captain"), gender ("female", "girl", "male", "boy"), and Pokémon GO ("go rocket", "go team", "mystic", "valor", "instinct")
- Generation and region search works across all 739 generation-styled sprites automatically: "kanto", "johto", "hoenn", "gen 1", "gold silver", "diamond pearl", "xy", "scarlet violet", "hisui", "lgpe" all filter the correct sprite group
- Named trainers across all 9 generations are tagged with their game of origin, so searches like "sinnoh gym leader" or "alola water" return the right results in the modern sprite group too
IV OCR: neural screenshot reading
- Screenshot scanning now reads CP, name, HP, and stardust through a neural OCR engine (the same class of text recognition the mobile app uses), fixing the white "CP" font and dust cost that the previous engine could not read over bokeh backgrounds
- The on-screen clock in the status bar is no longer mistaken for the CP value, and the CP arc scanner is now used only as a fallback when text reading is unavailable
Trainer Sprites: massively expanded avatar library
- Scraped all 1,454 sprites from the Pokémon Showdown trainer directory and added 1,314 new trainer avatars across 16 generation groups
- New sprites include every game generation (Gen 1 RB through Gen 9), Let's Go variants, Masters EX artwork, Pokémon GO player avatars, Team GO Rocket leaders (Arlo, Cliff, Sierra), GO team leaders (Blanche, Candela, Spark), and hundreds of gym leaders, Elite Four members, and named NPCs previously missing
- Avatar picker reorganized by Source, then Generation, then alphabetically: 18 groups total including the new Showdown generation groups plus existing Dreamstone and PEX sprite packs
- Existing avatar selections are fully backward-compatible; all original slugs unchanged
IV Calculator: fix My Box failing to load
- The My Box tab showed "Failed to load data. Please try again later." because the box API endpoints were only registered under the mobile API route group; the web UI routes were missing entirely
- Added
GET/POST/DELETE /api/iv/pokemonroutes to the web route group; no handler or database changes were needed
IV OCR: CP arc and dust cost detection fixes
- Narrowed the camera-icon exclusion zone in the CP arc scanner; the previous zone was too wide and caused it to skip the correct arc endpoint for high-CP Pokémon, producing wrong CP values (e.g. reading 1828 instead of 2895 for a Snorlax)
- Changed arc brightness check from sum > 580 to requiring all three colour channels above 200; this filters out coloured bokeh and background elements that previously triggered false arc endpoints
- Added a narrow dust-cost-only crop region to read the power-up stardust cost in isolation; the wider region was allowing Tesseract to merge the cost with the adjacent candy count (e.g. "7,0008") which then failed to match any valid dust value
Sidebar: user section overhaul
- Username in the nav user row now links to your trainer profile instead of logging you out; a small × icon button beside it handles logout
- New quick-links section below the user row: Social (your social page), Friends, My Profile, and Logout, visually separated from the main nav links with a divider
IV Calculator: design alignment
- Restructured the Manual and OCR tab containers to match the site-wide calc page pattern: form inputs now live in their own glass card (column 1 on desktop) separate from the results panel (column 2), matching how the DPS and Raid counters are laid out
- OCR tab now wraps the upload button, scan status, and extracted data card in a unified controls card instead of loose floating elements
- Fixed "Log in" hint messages (OCR and My Box tabs when not logged in, and the My Box empty state): now shown in a proper glass card instead of floating plain text
- Fixed broken Pokémon Status labels (Normal / Shadow / Purified / Lucky): the i18n strings were defined but not passed to the page script, causing "undefined" to render for each button
Trainer profile: shiny grid responsive columns
- Shiny collection grid now uses
auto-fillwith a 95px minimum column width, so it naturally shows 6 columns on desktop and shrinks to 5, 4, 3, or 2 as the viewport narrows; no fixed breakpoint overrides needed and no overflow at any screen size
Trainer profile: shiny grid layout
- Shiny collection now shows 6 sprites per row instead of 9, giving each entry more room and reducing visual cramping
- Gap between items bumped from 0.5rem to 0.75rem for additional breathing room
Trainer profile: shiny collection sort on expand
- Expanding the shiny collection on a trainer profile now re-orders the full list by Pokédex number (ascending) instead of keeping entry order
- The initial preview still shows the most recently caught first
Shiny Collection: evolve transform
- Evolving a shiny now transforms it in place: Charmander becomes Charmeleon, Charmeleon becomes Charizard, and so on through the full evolutionary line
- Click "Evolve" on any caught entry to see the next available form; for branching evolutions (Eevee, Gloom, Slowpoke, etc.) a sprite picker lets you choose which branch
- Evolution is permanent and one-way; the entry stays in your collection with a ⬆ chip marking when it evolved
- Counter counts all entries including evolved ones; the Evolved tab filters to shinies that have been evolved at least once
- Evolution data is bundled statically for all GO-relevant species across generations 1-9; unknown/final forms show "No evolutions"
- Available in all five supported locales
Shiny Collection: Go Pass catch method
- Added "Go Pass" as a catch method for the shiny collection (passes that grant encounters, e.g. Paid Event Passes, GO Battle League reward encounters)
- Displayed with 🎫 icon on shiny cards and trainer profiles; available in all five supported locales
Trainer Avatars: 101 new Classic sprites
- Added 101 named characters to the Classic (Showdown) avatar set, now spanning Generations 1-9
- Villains & team bosses: Giovanni, Cyrus, Ghetsis, Lysandre, Lusamine, Guzma, Chairman Rose, Volo
- Rivals: Blue, Silver, Wally, Barry, Cheren, Bianca, Hugh, Calem, Serena, Hop, Bede, Marnie, Kieran
- Fan favorites: N, Colress, Gladion, Lillie, Hau, Plumeria, Sonia, Penny
- Champions: Cynthia, Diantha, Iris, Alder, Leon, Geeta, Steven
- Gym leaders. Kanto: Brock, Misty, Lt. Surge, Erika, Koga, Sabrina, Blaine; Johto: Falkner, Bugsy, Whitney, Morty, Jasmine, Pryce, Clair; Galar: Nessa, Kabu, Bea, Allister, Opal, Gordie, Melony, Piers, Raihan; Paldea: Brassius, Iono, Larry, Ryme, Tulip, Grusha, Hassel, Poppy
- Elite Four: Aaron, Bertha, Flint, Lucian, Volkner (Sinnoh); Malva, Wikstrom, Siebold, Drasna (Kalos)
- Scientists: Scientist, Prof. Sycamore, Prof. Kukui, Faba
- Playable characters: Kris, Ethan, Lyra, Hilbert, Hilda, Dawn, Lucas, Nate, Rosa, Elio, Selene, Victor, Gloria, Florian, Juliana, Arven (multiple outfit variants for Paldea characters)
- Sprites proxied through the existing Showdown CDN handler; no new assets stored locally
- Added 86 FRLG-style trainer sprites from pokeemerald-expansion (Rom Hacking Hideout) as a new "pokeemerald-expansion (FRLG)" avatar set: Kanto gym leaders (Brock, Misty, Lt. Surge, Erika, Koga, Sabrina, Blaine, Giovanni in GBA art style), Kanto Elite Four (Lorelei, Bruno, Agatha, Lance), Blue as rival and champion (both outfits), Steven (FRLG), Prof. Oak, Team Rocket grunts (F/M), and 60+ trainer class variants in FRLG art style including new-to-GBA classes (Burglar, Biker, Juggler, Channeler, Cue Ball, Gamer, Painter, Rocker, Tamer, Crush Girl, Crush Kin, Super Nerd, Engineer, Scientist)
- Credits page updated with pokeemerald-expansion attribution
Admin: Trainer Avatar lock management
- New "Trainer Avatars" section in the admin panel for managing which users can access each sprite
- Professor sprites are automatically locked to Trusted rank or higher; plain users cannot select them
- All other sprites can be individually locked to a rank tier (Trusted, Content Creator, Tester, Moderator, Admin) via the admin UI
- Locked sprites are hidden from the avatar picker for ineligible users
Avatar picker: expanded researcher & professor sprites
- Added 13 new researcher/scientist-type trainer avatars to the Classic (Showdown) set
- Professors (each generation now represented): Prof. Elm, Prof. Birch, Prof. Rowan, Prof. Juniper, Prof. Burnet, Prof. Magnolia, Prof. Laventon, Prof. Turo, Prof. Sada, Prof. Willow
- Trainer classes: Doctor, Nurse (added alongside the existing Scientist and Super Nerd classes)
- Named researchers: Molayne (Alola Trial Captain and scientist)
Avatar picker: searchable combobox
- The Trainer Avatar dropdown is now a typed, searchable combobox: type a character name to filter across all 310+ sprites instantly
- Smart ranking: exact name match surfaces first, then starts-with, then contains; typing "N" finds the character N before Nessa, Nate, etc.
- Each dropdown result shows a sprite thumbnail alongside the character name, grouped by set (Classic / Dreamstone / FRLG)
- Cross-set search: typing "Giovanni" shows both Classic and FRLG variants; typing "FRLG" shows all 86 pokeemerald-expansion sprites
- Fixed: pokeemerald-expansion sprites were not displaying on the live site: the deploy script was missing the
static/sprites/pex/directory, so the 86 PNG files were never uploaded to the server
IV Calculator OCR: appraisal star detection
- OCR scan now attempts to detect the appraisal star rating (0-3 stars, hundo) automatically from the screenshot without requiring manual input
- Strategy 1: reads ★ characters captured by Tesseract in the full-image OCR pass; works on both standard and appraisal screenshots when the symbol is legible
- Strategy 2: orange/gold pixel scan in the correct region of the standard detail screen (the small appraisal dots to the right of the Pokémon name); region is calibrated as best-guess and may be refined
- Strategy 3: if the screenshot is an appraisal-results view (contains "Attack / Defense / HP" labels), the coloured stat bars at the left of the screen are scanned instead
- If no strategy succeeds the extracted card still shows the Stars field as editable so it can be entered manually before recalculating
- Fixed the server-side upload timeout:
ReadTimeoutwas cutting off PNG uploads larger than ~200 KB on slow connections; changed toReadHeaderTimeoutwhich only limits reading HTTP headers, leaving body upload time unrestricted
IV Calculator: bug fixes and form-aware lookup
- Fixed "Failed to load data" for valid inputs: the server was returning JSON
nullfor an empty candidate list, which crashed the page; now always returns an empty array - Fixed a systematic off-by-half-level bug where every dust bracket missed its final half-level: e.g. CP 985 Dugtrio (level 22) and CP 1790 Altaria (level 32.5) were silently skipped and reported as "no results"
- Fixed wrong base stats for regional-form Pokémon: Alolan Dugtrio was being used instead of Normal Dugtrio because the picker deduplicated by name; forms now appear as separate picker entries (e.g. "Dugtrio (Alolan)") and the correct form's stats are sent to the server
- Added Pokémon Status selector (Normal / Shadow / Purified / Lucky); automatically normalises the displayed stardust cost to the standard bracket value so entering 5,400 + Purified correctly maps to the 6,000 tier
- Added 5,400 dust bracket as a server-side fallback for purified Pokémon at levels 31-32
- OCR scan: fixed name and HP regions that were reading the wrong part of the screenshot for most modern phone aspect ratios; added full-image OCR fallback so the Pokémon name and HP fraction are recovered even when the crop misses
- CP input field maximum raised from 9,999 to 50,000 to support Mega Pokémon
Admin: scrollable tab bar
- Admin tab bar now wraps to the next row when the window is too narrow to show all tabs; no more silent overflow bleeding off-screen
- Other tab bars (IV calculator, credits) are unaffected
IV scanner: mobile OCR algorithm backport
- CP extraction now runs two passes: a top-25% zone scan preferring lines containing "CP", plus a contrast-enhanced top-18% retry; results take the highest of both, matching the Android app's approach for large Pokémon that partially cover the digits
- CP arc detection ported from the Android scanner: scans the white horseshoe arc pixel-by-pixel to derive CP when text OCR returns nothing, with camera-icon exclusion so Celesteela and similar don't trigger a false endpoint
- Name detection upgraded to three strategies in priority order: "This X was caught in..." footer text (highest confidence), "X MEGA ENERGY" line, then card-zone OCR as fallback; source tag ("footer" / "mega" / "card") shown in the scan results panel
- Lucky, Shadow, and Purified detection: scans full OCR text for status keywords; if not found explicitly, infers from the dust cost (halved = Lucky, x0.9 = Purified, x6 = Shadow) and normalises the dust before sending to the IV calculator
- HP extraction now applies O/0 character substitution before parsing and uses a fraction regex (current/max HP) instead of the first number found
- Appraisal star count upgraded to the gap-based algorithm: 13-row orange pixel scan with gap detection distinguishes 1-star (ring only, gap visible) from 2-star (partial fill) from 3-star (no gap); rainbow pixel classifier detects hundos
- Scan results panel now shows an "extracted values" card with editable CP, HP, dust, name, and star fields so you can correct any misread before recalculating; no need to re-upload
- Status badges shown: 100% IV (golden), Lucky (amber), Shadow (purple), Purified (blue), CP source (arc vs text)
- Trainer level is now read from your account settings server-side and passed automatically; no longer defaults to 40 for logged-in users
- CP multiplier table extended to level 51 (was missing levels 45.5-51); IV search now covers level 49-51 Pokémon for high-level trainers
Rank, badges and awards always visible on trainer profiles
- Raid rank, donator badge, user tags, and awards now show on trainer profiles and in the directory regardless of the "Show my full profile" setting
- The "Show my full profile" toggle now only controls truly personal details: trainer name, pronouns, and location
- Updated the setting description to reflect what it actually hides
Awards, tags and rank on trainer profiles
- Trainer profile pages now show a dedicated achievements section below the profile card, grouping rank badge, donator badge, and tags in one place
- Awards earned by the trainer are displayed as colored pills in the achievements section, loaded lazily from the existing awards API
- Hovering an award pill shows which community members granted it and any note they left
- The achievements card hides itself entirely when a trainer has no rank, no tags, and no awards
Per-award grant rank permissions
- Each award now has a configurable minimum rank required to grant it: Anyone, Trusted+, Content Creator+, Translator+, Tester+, or Moderator only
- Admins and Super Admins can always grant any award regardless of rank setting
- The grant award modal only shows awards the current user is eligible to give
- Admins can change the minimum rank on any award directly from the Awards panel using the inline dropdown
- Replaced the old trust-score-based community grant gate with this explicit rank system
Logout confirmation prompt
- Clicking the logout button now shows a confirmation dialog before logging out
Connections page and social overhaul
- Trainer profiles now have a "Connections" link and clickable follower/following counts that open the new Connections page
- New Connections page at /social/{username} shows three tabs: Friends (mutual follows), Followers, and Following
- The Connections page is publicly accessible: visit any trainer's page to see their social graph
- Own-profile Connections page includes an Unfollow button on the Following tab
- Old /friends URL redirects to your own Connections page
Layout refinements and Shinydex removal
- IV Calculator, Current Raids, and Raid Finder pages now cap their width so they don't sprawl across the full screen on wide monitors
- Input boxes across all pages are capped to a sensible maximum width
- Shinydex page removed; shiny browsing is consolidated into My Collection
Content fills available screen width on desktop
- Content area now expands to fill the full viewport width to the right of the sidebar instead of being capped at a narrow fixed width
- Grids (raid bosses, shinies, trainers) show more columns at wider resolutions automatically
Responsive layout: desktop improvements
- Navigation sidebar is now permanently visible on desktop (1024px+) instead of always hiding behind a burger button
- Active page is highlighted in the sidebar navigation
- IV Calculator and DPS Calculator show a two-column layout on desktop (form on left, results on right)
- Content is no longer artificially constrained to a narrow column on wide screens
IV Calculator, box limit, and raid confirm warning
- New IV Calculator page at /iv: enter CP, HP, and stardust cost to find all possible IV spreads for any Pokémon
- Logged-in users can save results to a personal Pokémon box (up to 3000 entries) and scan screenshots via OCR to auto-fill the form
- Pokémon box enforces a 3000-entry per-user limit to prevent runaway storage
- Raid lobby members now receive a push notification 30 seconds before their confirm window expires
Trainer profile: shiny collection improvements
- Shiny collection now shows the 9 most recent catches in a fixed row; rainbow animated border on the section card
Shiny caught list: costume and event fields now show placeholder hints
- Costume and event fields in the Caught tab now show example text when empty so their purpose is clear
CSRF fix
- Fixed an error causing friend requests, feedback, and other actions to fail; no action required from users
Tiny Pokémon sprite boost
- Baby Pokémon, Mew, Celebi, Jirachi, Manaphy, Victini, Plusle, Minun, Joltik, Flabébé, Floette, Cutiefly, and Ribombee now render at an additional 5% scale: their in-game sprite canvases are the same size as other Pokémon but the subject is proportionally smaller, so the boost compensates
- Applies to the shiny dex grid, the caught list, and the public trainer profile shiny grid
Sprites enlarged by 15%
- All sprite images across all pages are 15% larger: trainer avatars, favourite Pokémon, shiny dex grid, shiny modal compare panel, shiny caught list rows, trainer profile shiny grid, and all modal/settings previews
Shiny dex: costume Pokémon sprites
- Costume entries now display the actual costumed sprite instead of the plain base shiny: Party Hat Pikachu shows with its hat, Nightcap Snorlax wears the cap, Sunglasses Squirtle has its glasses, etc.
- Sprites update live in the add modal when you pick a costume from the dropdown; the shiny compare panel swaps to the costumed variant as you type
- Sprite falls back to the base shiny if no known costume code exists for that Pokémon/costume combination
- Source: pokemon-go-api/assets on GitHub (256x256 in-game icon assets, same source used for raid boss images); covers ~40 species and ~65+ named costumes including all GO Tour trainer hats, Fashion Week outfits, seasonal events, and regional exclusives
- Costume sprites also appear on public trainer profiles for visitors viewing someone else's shiny collection
Social: friending replaced with followers/following model
- Trainer profiles now show Followers and Following counts, visible to all visitors
- "Add Friend" is now "Follow": following is one-directional; when two trainers both follow each other a Friends indicator appears
- The Following preview (own profile) is now nested inside the stat card; the /friends page now lists who you follow with an Unfollow button
- Raid notifications continue to come from trainers you follow
Privacy: avatar and favourite Pokémon always visible
- Trainer avatar and favourite Pokémon sprite now appear on profile pages and directory cards even when the full public profile is disabled; neither is personally identifiable
- All other private fields (trainer name, code, location, pronouns, shiny collection) remain gated behind the public profile toggle
Shiny collection on trainer profile pages
- Trainer profile pages (
/trainer/{username}) now show a Shiny Collection card below the friends section - Displays the 10 most recent catches by default; a "Show all N" button expands to the full collection
- Each entry shows the Pokémon sprite, name, costume/event tag subtitle, and catch method icon
- Hidden automatically for trainers with the "Hide shiny collection" setting enabled
- Fixed:
trainer.ts,social.ts, andnotifications.tswere missing from the esbuild command and were not being rebuilt on deploy; added all three topackage.json
Shiny collection: inline costume and event editing, CSRF fix
- Caught list entries now have inline dropdowns for Costume and Event Tag: change either field directly in the list and it saves automatically, same as form and method
- Costume dropdown is filtered per Pokémon: Pikachu shows all regional cap variants plus Lucha Libre, Detective Hat, etc.; Snorlax shows Night Cap; Squirtle line shows Sunglasses; generic options (Party Hat, Flower Crown, Witch Hat, etc.) appear for all Pokémon
- Event Tag dropdown is a static list of all major PoGO events (GO Fest 2018-2026, GO Tour Kanto-Unova, Community Day, seasonal events, etc.); no more guessing the exact wording
- Fixed a site-wide CSRF 403 error that broke every write action (friend requests, shiny edits, admin actions): CSRF cookie renamed from
_pogo_csrfto_pogo_csrf2to invalidate stale cookies signed with an old random key; all users get a fresh cookie on their next page load with no action required
Shiny collection: costume and event labels in caught list and trainer cards
- Caught list entries now show a subtitle below the Pokémon name with the form variant, costume, and event tag when set (e.g. "Shadow · Party Hat · GO Fest 2025"), making duplicate entries visually distinct at a glance
- Trainer profile shiny grids now display costume and event tag as an italic subtitle beneath the Pokémon name
Shiny collection: true duplicate shinies and event autocomplete
- The unique constraint on the shiny collection is now fully removed: you can add the same Pokémon (same form, costume, and event) as many times as you like, making it possible to track every duplicate shiny you own
- Grid cards now show a blue ×N badge in the top-left corner when you own more than one of that species
- The Event field in the add modal now has autocomplete: start typing and common events (GO Fest, GO Tour, Community Day, etc.) appear as suggestions
- DB migration 33 added to
migrate.sql; run section 33 on existing installs
Trainer Level setting and mobile profile API
- New Trainer Level field on the Settings page (Profile tab): accepts 1-80, blank means not set; used by the Android companion app to pre-fill the trainer level input in IV scans
GET /api/mobile/v1/auth/menow includestrainer_levelin the response; the login response also includes it so the app has the value immediately on first login- New
PUT /api/mobile/v1/profileendpoint lets the app updatetrainer_levelwhen the user levels up; field is optional in the body, validated 0-80, zero means "unset" - DB migration 32 added; run
migrate.sqlsection 32 on existing installs
Shiny collection: costume and event Pokémon support
- Shiny collection now supports two new dimensions per catch: Costume (e.g. Party Hat, Witch Hat, Detective Hat) and Event (e.g. GO Fest 2024, Community Day); both are freeform text fields so any future variants work without code changes
- The unique constraint was widened from
(user, pokemon, form)to(user, pokemon, form, costume, event), meaning you can now log the same Pokémon multiple times if the costume or event differs: e.g. Party Hat Pikachu from GO Fest 2022 and GO Fest 2024 count as separate catches - Add modal shows labelled Costume (with autocomplete datalist of 20 common PoGO costumes) and Event inputs above the existing Form and Method selectors
- Caught list rows display costume and event as a compact italic subtitle under the Pokémon name when set; form and method remain inline-editable as before
- DB migration 31 added; run
migrate.sqlsection 31 on existing installs
Mobile app backend: Phase 3 (OCR endpoint) and Phase 4 (push notifications)
- Screenshot OCR:
POST /api/iv/ocraccepts a JPEG or PNG screenshot of the Pokemon info screen (multipart upload, max 8 MB), runs Tesseract to extract CP, HP, dust cost, and Pokemon name, detects appraisal star count from pixel color analysis, and immediately returns IV candidates; rate-limited to 10 requests/min; requirestesseract-ocron the VPS - OCR endpoint mirrored at
POST /api/mobile/v1/iv/ocr(Bearer auth, no CSRF) for the future Android and iOS apps; web endpoint is under standard auth+CSRF - Push notification dispatch: all four raid events now fire push notifications asynchronously: user matched into lobby, lobby full (host), lobby cancelled (members), and raid reported (attended members prompted to rate host)
- FCM (Android) via HTTP v1 API with service-account OAuth2 token auto-refresh; APNs (iOS) via HTTP/2 with p8 JWT auth using
github.com/sideshow/apns2 - Push is opt-in at deploy time: server starts without push if
FCM_PROJECT_ID/APNS_KEY_PATHenv vars are absent; no functionality is broken by unconfigured credentials - New env vars added to
deploy.ps1:FCM_PROJECT_ID,FCM_CREDENTIALS_JSON,APNS_KEY_PATH,APNS_KEY_ID,APNS_TEAM_ID,APNS_BUNDLE_ID,APNS_PRODUCTION
Mobile app backend: Phase 1 (auth) and Phase 2 (IV calculator)
- Bearer token auth: all existing session tokens now work via
Authorization: Bearer <token>header, enabling a future companion app to authenticate without cookies - New mobile API namespace at
/api/mobile/v1/: login, logout, current user, and game data aliases (Pokemon, raids, events) outside CSRF scope - Push notification token registration endpoints (
POST/DELETE /api/mobile/v1/push/token) ready for FCM (Android) and APNs (iOS); dispatch to be wired in a future phase - IV calculator:
POST /api/iv/calculateaccepts Pokemon name, CP, HP, dust cost, trainer level, top-stat appraisal, and star rating; returns all valid IV spreads sorted by IV% with adefinitiveflag when only one spread matches - Pokemon box:
POST/GET/DELETE /api/mobile/v1/iv/pokemonlets users save, list (paginated), and delete IV appraisal results for their own collection - Two new DB tables:
user_pokemon_box(saved IV records with optional candidate JSON) andmobile_device_tokens(per-device push tokens with platform and device name)
Dedicated notifications page, friends preview on trainer profile, volume cap
- The 🔔 bell now links to
/notifications, a dedicated page listing active friend-raid notifications with individual dismiss (×) and "Clear all" buttons; empty state shows a "You're all up to date" message - Visiting the notifications page marks all current notifications as seen, so the badge resets to 0 on the next poll
- Your own trainer profile (
/trainer/{username}) now shows a "Friends" preview section with your 5 most recent friends and a "View all" link to the Friends page - Notification ding volume is now capped at 50% gain regardless of the slider value, preventing accidentally ear-splitting levels while keeping the 0-100% visual scale intact
Social UI restructure, notification sound, and trainer profile overhaul
- Blocked users management moved from the Friends page to a new "Blocked Users" tab in Settings, with a live search field that finds users by username or trainer name
- The notification bell is now an emoji (🔔) displayed inline next to your username in the sidebar, replacing the standalone "Notifications" nav link
- A short ding plays when a new friend-raid toast appears; volume (including mute) is controlled from a new "Notifications" tab in Settings and is saved per browser
- Trainer profile pages (
/trainer/{username}) have been redesigned with a proper hero layout, larger avatar, clearer name and pronouns display, and better badge/tag arrangement - Fixed favorite Pokémon sprite appearing at the bottom of the page instead of layered behind the trainer avatar
Friends, notifications, and trainer feedback
- Users can now add each other as friends (directional follow) and block users from a dedicated
/friendspage and from trainer profile pages - Blocking a user removes the friendship in both directions and prevents further social interaction
- Logged-in users receive a toast notification in the top-right corner when a friend opens a Raid lobby, and a badge on the new notifications nav button shows the count of active friend raids
- Each trainer now has a dedicated profile page at
/trainer/{username}, linked from the trainer directory cards - Logged-in users can leave one Pokemon-themed feedback tag per trainer (positive, neutral, or negative) from the trainer profile page; submissions are updatable
- Moderators and above can delete any feedback using a delete button visible only to them
- Admins can manage the feedback option list (add, edit, enable/disable, delete) from a new Feedback Options tab in the admin panel
Updated site descriptions to reflect current features
- Login and registration page subtitles updated to reflect the full feature set (raids, trainer profiles, community tools) rather than shiny collection tracking only
- Home page now includes cards for Trainer Directory and Raid Finder, both gated by their respective maintenance flags
Raid Finder gets its own dedicated page
- The Raid Finder has moved from the Trainers page tab to its own page at
/raidfinder, with a new nav link - Non-logged-in users see the page content blurred behind a frosted-glass overlay with Login and Sign Up prompts
- Logged-in users who haven't set a Trainer Name or Trainer Code see a red warning banner explaining they won't be able to join raids until their profile is updated
- The Trainer Directory page is simplified to a single-section layout with no tabs
Wiki documentation overhaul
- Corrected and expanded 12 wiki pages: fixed the schema migration instructions, admin panel tab list, site stats access level, store toggle placement, translator flag grant authority, super donator pre-queue wording, and a copy-paste error in Data Sources
- Added a practical "how to build trust" guide, awards granting UI walkthrough, and host kick documentation to the Trust and Raid Finder pages
- Added the Shiny collection hidden privacy setting and translator application tables to Accounts and Database Guide
- Updated README to link directly to all major feature wiki pages
Shiny Collection visible on trainer cards
- Trainer cards in the Trainer Directory now show a "My Collection" link that expands inline to display the trainer's full shiny collection
- Each entry shows the shiny sprite, Pokémon name, a Shadow or Purified badge where applicable, and the capture method (omitted when set to Any method)
- A new Privacy setting ("Hide shiny collection") lets users opt out; the link is absent on their card when enabled
DPS calculator: target selection remembered for logged-in users
- The target Pokémon selected in the DPS calculator (both Calculate and Compare tabs) is now saved and restored across page reloads for logged-in users
- Guests still see the picker reset on every load
Code quality and database setup improvements
- Removed superfluous comments from Go and TypeScript source files; only comments explaining non-obvious behavior remain
- Database setup files reorganized to better support fresh installs and version upgrades
API access for any user; admin panel modal polish
- The superadmin can now grant private API access to any user account, not just those with the admin role; the Admin Panel Users tab shows the Grant/Revoke API button for all users
- Users granted API access now see a personalized card on the Credits API tab explaining how to authenticate with their session cookie and example curl commands
- Role changes no longer automatically revoke API access; the permission is now independent of role
- User detail modal in the Admin Panel now uses the same frosted dark card background as the rest of the site
Translator application flow
- Any user (logged in or out) can now reach
/translate: logged-out visitors see a program overview with login/register CTAs, logged-in users see an application form - Application form collects target languages with proficiency levels, motivation, optional experience, and optional country of residence; applicants must be proficient in English as the source language
- After submitting, users see a live status badge: Pending, Being Reviewed, Accepted, or Rejected (with rejection reason if provided)
- Accepted translators continue to see the workspace as normal; admin panel gains a new Translator Apps tab with Pending/Reviewing/All filter and accept/reject actions
- Admin Pages tab gains a "Translator Applications" toggle; when disabled, logged-in users without an application see a "applications are currently closed" message instead of the form
- Homepage now shows a purple-bordered Translator card; sidebar Translate link is visible to all users
Raid Finder: host reliability tracking
- Hosts whose lobbies repeatedly end without the raid ever starting (expiring unfilled, or cancelled before the raid begins) now take a minor trust penalty; occasional unstarted lobbies in a short period carry no penalty
- Every unstarted lobby is logged to the trust event audit trail either way, and staff cancellations never count against the host
Full translation coverage and official localized Pokémon names
- Every user-facing string now has a locale key and can be translated: roughly 250 new keys covering server error messages (all JSON API errors, login/registration, access control, maintenance fallbacks), the admin panel, store, settings, trainers, and register pages, and all client-side text on the Raids, DPS, PvP, Shinies, and Shiny Dex pages
- All new keys ship with German, Spanish, French, and Japanese translations; Japanese is now at full parity with English
- Pokémon names are localized again using official in-game names from PokéAPI species data (PoGoAPI stopped providing language data), now including Japanese; raid counter headers also show localized names
- Translators can refine any of the new strings in the in-app translator workspace as usual
Raid Finder: shorter lobby lifetime
- Lobbies now expire after 10 minutes instead of 2 hours, keeping the open lobby list current; as before, non-host members are dropped without any penalty when a lobby times out
Project wiki and README overhaul
- Launched a full project wiki on GitHub covering everything: getting started, configuration, database, deployment, operations, architecture, the API, data sources, every feature page, roles and the admin panel, and the translation workflow
- Simplified the README into a quick start that links into the wiki for the deep dives
Japanese translation
- Added a full Japanese locale covering every string on the site, using official Pokémon GO terminology (色違い, レイド, 対策ポケモン, and friends)
Raid Finder: in-place lobby list refresh and gated queueing
- The Current Activity list now reloads in place; the rest of the screen (including anything typed into the host form) stays put during the periodic refresh
- Queueing now requires an open lobby: join straight from the activity list with the new per-boss Queue buttons
- Staff and Super Donators get a Pre-Queue card to line up for any boss before a host appears; Super Donators also keep built-in queue priority
- Store cards for Priority Pass and Super Donator now list every included perk
- The Custom Raid boss field is now a sprite search picker with autocomplete covering every Pokémon plus Shadow, Mega, and Dynamax forms
Raid Finder rewrite: matchmaking queues, trust system, and awards
- The Raid Finder is now a matchmaking system: pick a boss, join its queue, and get matched automatically with the next open lobby; Priority Pass holders jump ahead in line
- While waiting you see a live queue position with the spinning pokéball from the maintenance page
- Matched trainers get the host's Trainer Name and Code with a copy button and 2 minutes to send the friend request; hosts see matched names gray out and light up as each member confirms
- When a lobby fills, the host gets a 4 minute window to send all in-game invites; if it lapses, everyone returns to the front of the queue with no penalty
- After each raid, hosts confirm who joined and flag early leavers, and members report whether the raid succeeded and can commend or dislike the host
- New trust system replaces 5-star ratings: behavior (timeouts, early leaves, commends, dislikes) feeds a score shown publicly as a Trusted / Neutral / Caution badge; staff reports always carry heavy weight, and the system includes protections against coordinated reputation attacks
- New admin-granted special ranks with badges: ✅ Trusted and 🎬 Content Creator; holders (plus staff and top-trust users) can host custom raids for any boss
- New community awards: Pokémon-themed recognitions like Helping Hand and Professor's Aide, granted by staff (community granting can be enabled later for top-trust users) and shown on trainer profiles
- New admin Raids tab: live lobby moderation, awards management, per-user trust logs and adjustments
New community locales and GitHub translation sync
- Translators can now create entirely new languages from the Translate page; new locales fall back to English until translated and stay hidden from the public language switcher until an admin publishes them
- New Locales panel in the admin Translations tab: enable or disable any language for the public switcher and see translation progress per locale
- The public language switcher is now dynamic, so newly published languages appear for everyone without a redeploy
- New Sync to GitHub button commits approved translations to the repository on a dedicated branch and opens a pull request, replacing the manual download-and-overwrite step
Translator workspace and translation review
- New Translator permission, granted per user by the site owner from the admin panel
- Translators get a Translate page: a live site preview in the chosen language (ES/FR/DE) on top, and a searchable editor for every translation string below; saved suggestions appear in the preview immediately
- Admins review suggestions in a new Translations tab with old/new comparison; approving applies the change to the live site instantly, rejecting requires a reason the translator can see
- Approved changes are written to locale override files on the server, with the previous version backed up automatically so changes can be reverted
- Merged locale files can be downloaded from the admin panel to sync translations back into the codebase
Home page respects page toggles + Shiny Collection card
- Tool cards on the home page now hide automatically when staff disable the corresponding page in Admin Settings, matching the existing navbar behavior
- Logged-in trainers now see a gold-bordered Shiny Collection card on the home page linking to their personal collection
DPS Calculator redesign
- Pokémon are now chosen with a sprite search picker: suggestions show each Pokémon's sprite, and the selection appears with a larger sprite and its type badges
- The Compare tab's target is now a single search box that lists current raid bosses first (with tier tags), with a Custom types toggle for manual typings
- Compare results on phones now display as ranked attacker cards with big DPS and TDO numbers instead of a sideways-scrolling table; the desktop table is unchanged
- Fixed open picker dropdowns being covered by the card below them (also affected the raids page)
Data Sources attribution split by usage
- The Credits Data Sources list now credits LeekDuck (via pokemon-go-api) for current raid bosses and snacknap (via pokemon-go-api) for Max Battles as separate entries, so each source is credited for exactly the data it provides
Documentation refresh
- README brought up to date with the Events feature, Shiny Dex, Max Battles, the full public and private API set, and the CACHE_DIR environment variable
- Credits private API table now lists all available endpoints, including Max Battles and both event endpoints
- Data source descriptions updated to mention event images served from the LeekDuck CDN
- Runtime cache directory excluded from the repository
Event details now shown in full on site
- Event detail views now include the complete event write-up: descriptions, bonuses, featured spawns, shinies, raid bosses, eggs, field and special research, GBL schedules, and GO Pass ranks
- Details are fetched server side from each LeekDuck event page, sanitized, restyled to match the site, and cached to disk; pages refresh every 12 hours with polite request spacing
- New /api/events/{id} endpoint (public and private) serving the sanitized detail for one event
- If a page has not been scraped yet, the detail view falls back to the summary data from the feed
- GO Pass reward icons (Candy, XL Candy, Raid Passes and similar items) are now sized to match the Pokémon icons, with aligned rank rows and Basic/Deluxe columns
Real Events page added; shiny gallery moved to its own Shiny Dex page
- The Events page now shows actual Pokémon GO events: current and upcoming events with images, category badges, start and end times, and live countdowns
- Clicking an event opens a detail view with bonuses, featured Pokémon, shinies, raid bosses, spotlight details, special research steps, and a link to the LeekDuck event page
- Event data is sourced from LeekDuck via ScrapedDuck, refreshed every 30 minutes server side and cached to disk
- New /api/events endpoint (public and private) serving the raw events feed
- The public shiny gallery that previously lived at /events moved to its own page at /shinydex, with its own nav link, home card, and admin maintenance toggle
Raid tier tabs and automatic cache-busting
- The Raids page now uses tier tabs (ordered highest to lowest) instead of one long stacked list; Max Battles got the same treatment, so only one tier is shown at a time
- Static assets (JS and CSS) now carry an automatic version stamp derived from their contents, so every deploy busts the browser cache and you always get the latest page without a hard refresh
- HTML pages are served with no-cache and versioned assets get a long cache, removing the need to bump version numbers by hand
Raids moved to pokemon-go-api and Max Battles added
- Current Raids now sources from pokemon-go-api instead of ScrapedDuck, which provides richer data (shadow raids, multi tier CP and boosted CP)
- Added a Max Battles section to the Raids page showing current Dynamax bosses by tier, with the same boss cards, type filtering, and counter lookups
- New /api/maxbattles endpoint (public and private), and max battles are included in the combined game data API
- Both raids and Max Battles refresh on the same schedule and are cached to disk
Per-IP bandwidth throttling added to public API
- Public API endpoints now enforce a rolling bandwidth limit per IP in addition to per-request rate limiting
- IPs that exceed the limit are temporarily blocked regardless of which endpoints they used
- Logged-in users are unaffected
Public API rate limit raised to 10 requests per 2 minutes
- All four public API endpoints are now limited to 10 requests per 2 minutes per IP (previously 5 per 30 minutes)
- Credits page table and all locale strings updated to reflect the new limit
Site frontend excluded from public API rate limit
- Logged-in users now fetch game data through an authenticated session channel, completely separate from the public API rate limit
- Logged-in users will never hit the public rate limit regardless of how many pages they visit
- External and unauthenticated callers still use the public endpoint with its standard rate limit
Public API rate limit reduced to 5 requests per 30 minutes; raid boss refresh schedule corrected
- All four public API endpoints (/api/data, /api/raids, /api/pokemon, /api/moves) are now limited to 5 requests per 30 minutes per IP, down from 5-10 per minute
- Credits page API table and all locale strings updated to reflect the new limit
- Corrected the raid boss refresh schedule display in the API section: refreshes every 4 hours from midnight MT, not daily at noon
Admin Users tab redesigned as mini-card grid with modal detail view
- Users are now displayed as a compact mini-card grid showing username, role, status, and tags at a glance
- Clicking any user card opens a modal overlay with the full detail view and all action controls
- Modal closes on click-outside or Escape; after any action the mini grid and modal both refresh automatically
- All existing user management controls work inside the modal
Account suspension reason and login message
- Disabled users who try to log in now see a clear message: "Your account has been suspended by a staff member"
- Admins can optionally provide a reason when suspending an account; the reason is shown to the user on the login page
- The suspension reason is displayed on the user card in the Admin Panel Users tab
- Re-enabling an account automatically clears the reason
- Suspend button now opens an inline reason field before confirming, instead of acting immediately
- Translated into ES, FR, and DE
Custom Tag Requests moved to own Admin Panel tab; paid tags protected in Users tab
- Tag Requests is now a dedicated tab in the Admin Panel between Tags and Pages
- Custom tags (purchased via Supporter Pack) no longer show a remove button in the Users tab; they can only be revoked or revised from the Tag Requests tab
- Backend blocks deletion of custom tags via the user tag remove endpoint and returns a clear error if attempted
- The tag expand panel in Users shows custom tags as read-only pills with a note directing staff to Tag Requests
Custom tag: admin revoke, weekly cooldown, and color rate limit
- Admins can now request revisions on already-approved tags (not just pending ones); the tag is removed from the user's profile until resubmitted and approved again
- Admins can deny/revoke an approved tag outright, removing it from the trainer card and requiring the user to restart the request process
- New tag requests are on a 7-day cooldown per user; revision resubmissions are exempt from the cooldown
- Tag color can be changed freely; changing it more than 5 times in 30 minutes triggers a short cooldown
- Cooldown expiry date shown on the rejected status block in Settings and the Store page
- Color picker added to the approved status block in Settings for inline color changes
- All new strings translated into ES, FR, and DE
Settings: custom tag request status tab
- Users with a tag request now see a "Custom Tag" tab in Settings showing the current status (pending, approved, rejected, or awaiting revision)
- Staff notes are displayed for rejected and revision states
- Users with a revision request can update their tag name and color and resubmit directly from the Settings page without visiting the store
- Translated into ES, FR, and DE
Raid data now refreshes six times daily
- Raid boss data previously refreshed once daily; it now refreshes multiple times throughout the day
- Schedule is DST-aware
Trainer Directory: modal layout restructured
- Profile modal now has a distinct header zone (surface background) containing sprites, name, and a single combined pronouns/location line
- Details section (rank, tags, trainer code, join date, favourite Pokémon) lives in a separate body zone below
Moderator rank: PKMN Researcher
- Moderators now display a distinct "PKMN Researcher" rank badge (purple) instead of sharing "PKMN PROF" with admins
- PKMN PROF is now exclusive to admins and the superadmin
Trainer Directory: sort order by online/role/rank
- Directory now sorts on every load: online staff by rank (SuperAdmin, Admin, Moderator, Tester), then online players by XP rank, then offline staff by rank, then offline players by XP rank
Tester role: PKMN Scientist rank
- Users with the Tester role now display a "PKMN Scientist" rank badge in the Trainer Directory and Raid Finder
Trainer Directory: all users now visible
- All registered users now appear in the Trainer Directory by default, not just those who opted in with a trainer code
- Users with no trainer name and no trainer code show their username with an asterisk (*) to indicate their profile is not yet set up
- The "Show me in the Trainer Directory" setting has been renamed to "Show my full profile" and now controls whether trainer name, avatar, pronouns, trainer code, location, and favourite Pokemon are visible; staff badges, rank, and tags always show
- A footnote below the search bar explains the asterisk convention
- Search now matches on username in addition to trainer name
- Directory results ordered: full profiles first, then minimal entries
Admin: per-page and per-section maintenance mode
- Admins and superadmins can now put individual pages into maintenance mode from a new "Pages" tab in the Admin panel
- Disabled pages return HTTP 503 and show a styled maintenance screen with a "Back to Home" button; the nav link for that page is hidden while it is disabled
- The Trainers page supports section-level control: Trainer Directory and Raid Finder can each be disabled independently while the other section remains live
- All eight controllable pages covered: Raids, DPS Calculator, PvP IV Ranker, Events, Trainers (with sub-sections), and Shiny Collection
- All settings default to enabled so pages remain accessible if not yet configured
Admin panel: tag editing and assignment fixes
- Tags can now be renamed and recolored inline from the Tags tab (superadmin only)
- Fixed "Manage Tags" button not appearing: it was incorrectly restricted to admin-role users as targets; it now appears for any user (except the superadmin); superadmins can manage their own tags
- Tag assignment and removal now available to moderators and above (previously admin+ only)
- Removed backend restriction that prevented tags from being assigned to non-admin-role users
- Fixed a bug where opening "Manage Tags" showed "All tags assigned" if the Tags tab had not been visited yet in the same session
Superadmin: force data refresh button in Admin panel
- New "Data Refresh" card in the Admin Stats tab, visible only to the superadmin
- Clicking "Force Data Refresh" triggers an immediate background reload of all game data from PoGoAPI (Pokémon, moves, shinies, type chart, Pokémon names) without waiting for the scheduled 6-hour cycle
- Translated into ES, FR, and DE
i18n audit: translation completeness verified, JS double-quoting bug fixed, and pokemon_names parser updated
- All ES, FR, and DE locale files audited and confirmed complete against the English master (no missing keys)
- Fixed a bug where translated strings embedded in JavaScript were double-encoded; affected strings now render correctly across all templates
- Fixed
<html lang="en">being hardcoded; the page language attribute now reflects the active locale - Fixed pokemon_names parser to handle the updated PoGoAPI response format (object-of-objects instead of array)
Full i18n coverage: all pages, JS strings, and Pokémon names
- Every page now has translated titles, headings, and static text (Home, Raids, DPS, PvP, Events, Shinies, Credits)
- All JavaScript-rendered strings in the Admin panel, Raid Finder, and Shiny Collection are now translated
- Pokémon species names are translated in all four supported languages on the Raids, Events, Shinies, DPS, and PvP pages
- Go handler error messages (login, registration, settings, admin actions) are now returned in the user's active language
- Raid Finder strings now fully covered: tier labels, queue status, lobby messages, rating panel, and weather banner
Translations: Spanish, French, and German language support
- Language switcher added to the navigation sidebar; persists via cookie for guests, and is saved to your account for logged-in users
- Spanish (ES), French (FR), and German (DE) translations available for navigation, auth pages, settings, trainer directory, and the store
- Translation fallback: missing keys in a locale automatically fall back to English so no UI string is ever blank
- Language preference is stored in the database for logged-in users, meaning your choice follows you across devices and browsers
Donations: Super Donator tier, subscription management, staff tag review
- New Super Donator tier ($24.99/month): animated rainbow username and trainer name in the Trainer Directory and Raid Finder, DONATOR badge on profile, queue priority included, and future rewards as they are added
- Subscriptions are now manageable directly on the Donations page, even when the store is temporarily disabled
- Cancel button on each active subscription ends the perk immediately
- Staff can now send custom tag requests back to the user for revision before approval; users can update and resubmit
- Admins can enable or disable individual store items from the Donations tab in the Admin Panel
- Store renamed to "Donations" across all navigation and customer-facing areas
Settings: Dreamstone Mysteries trainer avatars
- 96 GBA-style trainer sprites from the open-source Pokémon Dreamstone Mysteries ROM hack are now available as trainer avatars in the Settings avatar picker
- Sprites are stored locally (no external CDN) and are served as static files
- The avatar picker now groups options under "Classic (Showdown)" and "Dreamstone Mysteries (GBA)" for easier browsing
- Credit: sprites from dsmyst/dreamstone-mysteries
Store: PayPal-backed perks for supporting the site
- New /store page (superadmin-toggled, off by default) offering two perks: Supporter Pack ($4.99 one-time) and Priority Pass ($2.99/30 days)
- Supporter Pack grants the ability to submit a custom tag for your trainer profile; staff review and approve or reject submissions from the new Tag Requests panel in the Admin Users tab
- Priority Pass moves the holder to the front of the raid join queue for 30 days; queue position is determined at join time
- Payments are processed via PayPal REST API; store toggle in Admin Settings (superadmin-only) shows or hides the page and nav link without affecting active perks
- Custom tag submission form appears on /store for active Supporter Pack holders; shows current request status (pending, approved, rejected) and allows resubmission after a rejection
Admin: Raid Stats panel for adjusting rank and ratings
- Each user card in the Admin Panel now has a "Raid Stats" section (admin-only) showing the user's current raid XP and rating metrics
- Admins can set a user's XP directly to any value; rank updates immediately based on the new total
- Admins can adjust how much influence a user's ratings carry in consensus calculations
- Tools to reset a user's received ratings or reactivate their host score are available to admins
DPS Compare: all Pokémon in target dropdown; queue position in Raid Finder
- DPS Compare target dropdown now shows current raids first, then all remaining Pokémon in an "All Pokémon" group; Pokémon already listed as a raid boss are not duplicated
- Raid Finder pending queue status now shows your position in the queue (e.g. "#2 in the queue") so you know where you stand
- Missing trainer name or code now shows a "Go to Settings" link inline with the error, instead of just the error text
Tags display inline next to rank badges
- On trainer directory cards and profile modals, user tags now appear on the same row as the rank badge instead of on a separate line below it
DPS Calculator: target Pokémon picker
- The Calculator tab now has an optional "vs. Target" section: type any Pokémon name to set a defender and see type-effectiveness-adjusted DPS values
- Type badges appear automatically once a valid Pokémon is entered; a Clear button removes the target
- Move rows show a coloured multiplier label (e.g. 1.60× or 0.63×) when the move type is super effective or not very effective against the target
- The Compare tab's target section gains a Pokémon name input as an additional way to set the defender (alongside the existing raid boss dropdown and manual type selectors)
- Pokémon type data is now fetched from PoGoAPI and included in the game data bundle, with a compiled-in fallback so the feature works offline
Two-tier API and API documentation
- Public game data API endpoints remain accessible to everyone but are now rate-limited per IP to protect server bandwidth
- Private API added for trusted consumers: same data, no rate limit, requires API access permission
- The data refresh endpoint requires API access and is globally rate-limited to prevent hammering upstream data sources
- New API tab added to this page documenting available endpoints and authentication requirements
User tag system
- Admins can be assigned coloured tag pills (e.g. Dev) visible on their Trainer Directory card and profile modal
- Tags are created and deleted by the superadmin from a new Tags tab in the Admin Panel; assignment and removal is available to all admins
- Tags are stored in the database with full cascade-delete support
API access permission system
- Private API access is now a separate permission rather than being open to all admin accounts
- API access can only be held by admin-role accounts and can only be granted or revoked by the site owner
- Removing admin privileges from an account automatically revokes API access
- Admin panel shows a blue "API Access" badge on users who hold the permission
Improved Pokémon GO weather detection
- Switched weather provider from OpenWeatherMap to Open-Meteo, which uses standardised WMO weather codes for a much more accurate PoGO condition mapping
- Weather is now determined from your city's coordinates (geocoded automatically) rather than a city-name string lookup, improving location accuracy
- Wind speed is now factored in correctly: Windy weather activates only when wind exceeds ~36 km/h and there is no rain, snow, or fog
- No API key required; OPENWEATHER_KEY is no longer used or needed
Raid data reliability and caching
- Raid boss data is now cached to disk on every successful fetch, so a service restart never shows "temporarily unavailable"
- Raids refresh once daily at noon Mountain Time instead of on the same 6-hour cycle as other game data
- PoGoAPI data (moves, types, shinies, etc.) continues to refresh every 6 hours in the background
Tester rank
- New Tester role (below Moderator): shows a 🧪 badge in the navbar, Trainer Directory cards, and Raid Finder posts and joiners list
- Assignable from the Admin panel role selector
Raid Finder: ranking system, weighted ratings, lobby, and online status
- Trainer profiles and raid posts now show a Pokémon-themed raid rank earned by participating in raids: Youngster, Trainer, Gym Leader, Elite Four, Champion, and League Master, each with five roman numeral tiers (I-V)
- XP is awarded for each completed raid (as a joiner or as a host); rank advances automatically as XP accumulates
- Host ratings use a weighted system that reduces the impact of outlier votes
- A host's displayed rating is dimmed if they have not participated in a raid recently, signalling potentially stale data
- Accepted joiners can now see each other in a lobby panel before entering the raid, so you know who you are playing with
- Trainer Directory cards and modals show whether a trainer is currently online and the date they joined
Raid Finder: queue system and prerequisites
- Joining a raid now puts you in a queue; the host reviews requests and accepts or declines each one individually
- The host's trainer code is only revealed once you have been accepted
- Queue count on each post excludes declined entries so it reflects active requests only
- Hosts can set a player limit on their post; the queue closes when that number of pending and accepted entries is reached
- Users must have a Trainer Name and Trainer Code set in Settings before hosting or joining any raid
Favorite Pokémon on trainer profiles
- Trainers can now set a favorite Pokémon in Settings, with a choice of Normal, Shadow, Shiny, or Primal form (Primal is available only for Groudon and Kyogre)
- The Pokémon's sprite appears to the left and slightly behind the trainer's avatar on their directory card
- Clicking any trainer card opens a profile view with their avatar, favorite Pokémon, pronouns, location, and trainer code in one place
Mobile navbar hamburger menu
- Replaced overflowing inline nav links on mobile with a hamburger menu that drops down a full-width stacked list
- Fixes horizontal scrolling on phones caused by too many nav items at narrow widths
Security hardening and backend improvements
- Various security and backend stability improvements
Live weather boost display in the Raid Finder
- The Raid Finder now shows your current local weather condition and which Pokémon types are boosted, based on the city saved in your settings
- Weather is fetched from OpenWeatherMap and mapped to Pokémon GO weather types (Clear, Partly Cloudy, Overcast, Rainy, Snow, Fog, Windy, Extreme)
- Results are cached server-side and aligned to Pokémon GO's weather clock, so the data refreshes at :00 and :30 rather than on every page load
Role indicators, trainer name uniqueness, and Raid Finder improvements
- Staff role icons shown next to usernames everywhere they appear: 👑 Superadmin, 💎 Admin, 🏅 Moderator; visible in the navbar, Trainer Directory cards, raid post headers, and the joiner list
- In-game trainer name and trainer code must be unique across all accounts; duplicate submissions are rejected with an error
- Raid Finder: non-logged-in visitors can browse active raids but must log in to post or join; a "Log in to join" prompt appears on each card
- Trainer sprite size increased to 64px on directory cards and 80px in the settings preview
- Pronouns and location text on trainer cards now render without the global text outline and in a lighter colour for improved readability
Trainer avatar and pronouns dropdown polish
- Avatar picker converted from a radio button grid to a dropdown with a live sprite preview that updates as you change selection
- Pronouns converted from radio buttons to a dropdown; selecting "Other" reveals a custom text input
- Trainer sprites are now cached server-side on first load and served from the local proxy with a 30-day browser cache header, eliminating repeat fetches from the Pokémon Showdown CDN
- Expanded trainer class list to 27 confirmed sprites
Pronouns, trainer sprites, and settings tabs
- Trainers can now set pronouns (He/Him, She/Her, They/Them, Any/All, or custom); shown in muted text beside their name in the Trainer Directory
- Trainer avatar picker replaced with actual game trainer class sprites via Pokémon Showdown: Youngster, Lass, Bug Catcher, Hiker, Beauty, Psychic, Ace Trainer, Swimmer, Picnicker, Camper, Pokemaniac, Super Nerd, Gentleman, Medium, and Worker
- Trainer cards in the directory show the selected sprite; trainers with no avatar set show the default silhouette
- Settings page split into tabs: Trainer Profile (name, pronouns, avatar, trainer code) and Location & Privacy
Raid Finder, trainer avatars, and directory improvements
- New Raid Finder tab on /trainers: post and join remote raids with other players in real time
- Raid boss selection uses a live dropdown of current raid bosses grouped by tier
- Weather Boosted toggle on raid posts; boosted raids are badged in the list
- Raid posts expire automatically after 2 hours
- Joiners receive a remote raid pass reminder and a link to the Raids page for counters
- Host's trainer code is revealed to joiners upon joining so they can add the host in-game
- Joiners confirm they have sent a friend request; host is notified and can mark the invite as sent
- After the raid, joiners can rate the host (1-5 stars); host can rate confirmed joiners
- Anti-churn cooldown: repeatedly leaving raids in quick succession triggers a temporary join block
- Trainer Directory now shows trainer name only (not site username) for privacy
- Trainers can pick a colour avatar theme from Settings; shown on their directory card
Trainer Directory, Settings page, and location privacy controls
- New Settings page: set your in-game trainer name, 12-digit friend code, and opt into the public Trainer Directory
- New Trainer Directory (/trainers): public list of opted-in players with one-click trainer code copy buttons
- Trainer codes displayed as XXXX XXXX XXXX; copied without spaces for easy in-game pasting
- Location privacy controls: choose to show no location, country only, or state and country on your directory card
Pokédex details, shiny comparison, and collection improvements
- Normal vs shiny sprite comparison: opening any shiny card now shows both sprites side by side so you can compare the colour difference
- Pokédex flavor text pulled from PokéAPI and shown in shiny, raid, DPS, and PvP detail views
- Genus tag shown beneath each Pokémon name (e.g., "The Mouse Pokémon")
- Legendary and Mythical badges on applicable Pokémon across all detail views
- Pokémon cry audio button (🔊) in shiny modals plays the official in-game cry; includes a volume slider (displayed as 0-100%, capped at 30% actual output)
- Primal form sprites shown alongside Normal and Shiny in the compare panel for Groudon and Kyogre
- Shiny collection caught list now shows when each Pokémon was caught (e.g., "3 days ago")
- Collection stats bar: unique and total counts plus a method breakdown (Wild, Raid, Egg, etc.)
- Shiny method tabs show a tooltip on hover explaining how each method works
- Fixed shiny method details not displaying (PoGoAPI field name update)
- Removed focus glow rings from all input fields; fixed black text outline on mobile inputs
Pokémon lookup, weather boosted CPs, raid overhaul, and more
- New Pokémon lookup on the Raids page: search any Pokémon to see its best moveset and DPS/TDO against every current raid boss, sorted by best matchup first
- Pokémon lookup form selector: Normal, Shadow, and Purified are available for all Pokémon; Primal is available only for Groudon and Kyogre
- Pokémon lookup uses CP input instead of level; default CP shown at L40/15/15/15; CPM derived from CP and IVs automatically
- DPS calculator and compare tabs now use CP input instead of level
- Shiny Pokémon cards now show how to obtain each shiny in the detail popup
- Raid boss cards now show weather boosted CP range alongside the normal catch CP
- Rebranded to hailsDotGO Beta
- Combined Current Raids and Raid Counters into a single page
- Raid bosses now display as visual cards with artwork, type badges, CP, and shiny availability
- Pokémon sprites added throughout: counter table, DPS result, DPS compare table, PvP IV rankings
- Events page simplified to Shinies-only (raids moved to the Raids page)
- hailsDotGO branding is now pink across the site
- Black text outline added globally for readability
- Added this changelog
Raid counters, mobile, and deploy fixes
- Fixed raid counters showing wrong Pokémon and NaN DPS/TDO values
- Counters now only consider moves each Pokémon can actually learn
- Fixed duplicate Pokémon in counter list (keeps highest-DPS result per species)
- Lazy loading added for all 863 shiny images on the Shinies page
- Mobile-friendly layout: improved touch targets, horizontal table scroll, iOS font-size zoom fix
- Various backend stability improvements