-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
hailsDotGO exposes a read-only JSON API for the game data it aggregates, a set of session-authenticated endpoints used by the site frontend, and a private API tier for trusted consumers. This page documents the endpoints, rate limits, and authentication rules. A live, always-current version of the public and private API tables is on the site itself: open https://pogo.hails.live/credits and switch to the API tab.
All endpoints are relative to the site root (for the production instance, https://pogo.hails.live). Errors are returned as JSON objects of the form {"error": "message"} with an appropriate HTTP status.
No authentication required. All responses carry Cache-Control: public, max-age=300.
| Endpoint | Method | Returns | Rate limit (per IP) |
|---|---|---|---|
/api/data |
GET | Combined bundle: Pokemon stats, moves, raids, Max Battles, shinies, shadow list, type chart, CP multipliers, types, localized names | 10 per 2 minutes |
/api/raids |
GET | Current raid bosses grouped by tier ("1", "3", "5", "6" for Mega; Shadow bosses fold into their tier with a Shadow name prefix) |
10 per 2 minutes |
/api/maxbattles |
GET | Current Max Battle bosses grouped by tier ("1", "2", "3") |
10 per 2 minutes |
/api/events |
GET | Current and upcoming events (ScrapedDuck feed) | 10 per 2 minutes |
/api/events/{id} |
GET | Sanitized HTML detail for one event; id must match ^[a-z0-9-]{1,128}$
|
30 per 2 minutes |
/api/pokemon |
GET | Pokemon base stats | 10 per 2 minutes |
/api/moves |
GET |
{"fast": [...], "charged": [...]} move data |
10 per 2 minutes |
On top of the request limits, the public data endpoints share a per-IP bandwidth budget: 15 MB per rolling 5-minute window, counted across all of the endpoints above. Exceeding it blocks the IP from these endpoints for 30 minutes and returns 429 with {"error":"bandwidth limit exceeded, try again later"}. Logged-in site users are unaffected because the frontend uses the session endpoint below.
Where the data comes from and how often it refreshes is documented in Data Sources.
These are the endpoints the site frontend uses. Authentication is the hgo_session cookie; there are no API keys. Mutating requests from a browser must also send the CSRF token in the X-CSRF-Token header (the token is rendered into every page; gorilla/csrf pairs it with the _pogo_csrf cookie). The PayPal webhook is the only CSRF-exempt route.
| Endpoint | Method | Purpose |
|---|---|---|
/api/app/data |
GET | Same payload as /api/data, but session-authenticated and not subject to the public rate limits |
/api/weather |
GET | Current in-game weather and boosted types for the user's saved location (see Accounts and Roles) |
/api/shinies |
GET | The user's shiny collection |
/api/shinies |
POST | Add a shiny |
/api/shinies/{id} |
PUT | Update a shiny entry |
/api/shinies/{id} |
DELETE | Remove a shiny entry |
/api/shinies/{id}/evolve |
POST | Evolve a caught shiny: changes its pokemon_id to the target form and stamps evolved_at; body {"into": "PokemonName"}, plus an optional target region so regional evolution lines stay consistent |
The shiny write endpoints (POST, PUT, and the public GET /api/shinies/of/{username} reader) carry a region field alongside the entry. The POST body fields are pokemon_id, form, region, method, costume, event_tag, and an optional caught_at date (YYYY-MM-DD). region is one of the four geographic forms (alolan, galarian, hisuian, paldean), one of the battle formes that reuse the same field (therian, origin, attack, defense, speed, sky), a Vivillon pattern code or Unown letter code for those species, or empty for the original form; any unrecognized value is rejected. It is kept separate from form so a regional or battle forme variant and a status such as Shadow can coexist on one entry. caught_at is accepted on both POST and PUT, validated to fall between Pokemon GO's launch (2016-07-06) and tomorrow; omitting it on an update leaves the stored date unchanged.
See Social Features for the full behavioural description.
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/social/{username} |
GET | session | Relationship state: {is_self, is_friend, is_blocked, they_blocked_you}
|
/api/social/{username}/friend |
POST | session + CSRF | Add {username} as a friend |
/api/social/{username}/friend |
DELETE | session + CSRF | Remove friend |
/api/social/{username}/block |
POST | session + CSRF | Block {username}; removes friendship in both directions |
/api/social/{username}/block |
DELETE | session + CSRF | Unblock |
/api/notifications |
GET | session | Active raids (open, full, raiding) hosted by the caller's friends; used by the 🔔 badge poller and the /notifications page |
/api/feedback/{username} |
GET | none | All feedback entries for {username} (public) |
/api/feedback/{username} |
POST | session + CSRF | Submit or update your feedback; body {"option_id": N}
|
/api/feedback/entry/{id} |
DELETE | session + CSRF | Delete your own feedback entry |
/api/users/search?q= |
GET | session | Search trainers by username or trainer name; returns [{username, trainer_name}]
|
Admin-only feedback option management (Admin role required):
| Endpoint | Method | Purpose |
|---|---|---|
/api/admin/feedback-options |
GET | List all feedback options |
/api/admin/feedback-options |
POST | Create a new option |
/api/admin/feedback-options/{id} |
PUT | Update label, sentiment, sort order, or enabled state |
/api/admin/feedback-options/{id} |
DELETE | Delete an option |
Admin-only sprite lock management (Admin role required):
| Endpoint | Method | Purpose |
|---|---|---|
/api/admin/sprite-locks |
GET | List all trainer sprites with slug, label, group, and current min_rank |
/api/admin/sprite-lock/{slug} |
POST | Set min_rank for a sprite; body {"min_rank": N} where N is one of {0, 1, 2, 4, 5, 100}. Returns 400 if the sprite is a professor (auto-locked server-side) |
/api/admin/sprite-lock/{slug} |
DELETE | Remove the lock row, returning the sprite to rank 0 (unlocked) |
Admin-only costume management (Admin role required). See the Admin Guide Costumes tab for the workflow:
| Endpoint | Method | Purpose |
|---|---|---|
/api/admin/costumes/name |
POST | Give an unlabelled costume code a display label; lands in a server-side overlay so it is live in the picker immediately (add-only, cannot rename) |
/api/admin/costumes/name |
DELETE | Remove a label (un-name), refused when any saved user_shinies row uses that label |
/api/admin/costumes/hide |
POST | Dismiss a code the game flags as a costume but no trainer would record (e.g. the Gimmighoul coins) |
/admin/check-costumes |
POST | Read-only drift check: reports mined-asset costume codes not yet in the compiled catalog and the asset commit it was built from. Rate limited 5 per minute |
The costumed sprites those labels resolve to are served by a public proxy:
| Endpoint | Method | Purpose |
|---|---|---|
/api/costume-sprite/{file} |
GET | Serves a shiny costume sprite from the app's own origin (pulled from the mined-asset CDN once, cached, served immutably). Only filenames the catalog can produce are allowed |
Reporter and participant facing (writes also require CSRF). See Bug Reports and Player Reports.
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/bug-reports |
POST | session | File a bug report; body {subject, body}. Rate limited 6 per minute |
/api/bug-reports |
GET | session | List the reports the caller participates in |
/api/bug-reports/{id} |
GET | session | Full thread (internal notes only for staff) |
/api/bug-reports/{id}/messages |
POST | session | Reply; staff may set visibility:"internal"
|
/api/bug-reports/{id}/invite |
POST | session | Invite a collaborator (reporter and collaborators up to 4; staff unlimited) |
/api/bug-reports/{id}/status |
POST | session | Reporter resolve/reopen (staff get the full set) |
/api/bug-reports/{id}/rating |
POST | session | Reporter CSAT `{rating:"good" |
/api/player-reports |
POST | session | File a player report; body {username, reason, details}. Rate limited 6 per minute |
Staff and admin management (Moderator role unless noted):
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/admin/bug-reports |
GET | mod | List all reports; filters status, label, `assignee=me |
/api/admin/staff |
GET | mod | Active staff list (assignee dropdown and filter) |
/api/admin/bug-reports/{id}/status |
POST | mod | Set status |
/api/admin/bug-reports/{id}/priority |
POST | mod | Set priority (`low |
/api/admin/bug-reports/{id}/assign |
POST | mod | Assign to a staff member (empty username unassigns) |
/api/admin/bug-reports/{id}/labels |
POST | mod | Attach a label {label_id}
|
/api/admin/bug-reports/{id}/labels/{labelId} |
DELETE | mod | Detach a label |
/api/admin/bug-reports/{id}/actioned |
POST | mod | Close a player report as actioned and thank the reporter |
/api/admin/bug-report-labels |
GET | mod | List labels |
/api/admin/bug-report-labels |
POST | admin | Create a custom label |
/api/admin/bug-report-labels/{id} |
PUT / DELETE | admin | Update or delete a label (built-ins cannot be deleted) |
/api/admin/bug-report-macros |
GET | mod | List canned responses |
/api/admin/bug-report-macros |
POST | admin | Create a canned response |
/api/admin/bug-report-macros/{id} |
PUT / DELETE | admin | Update or delete a canned response |
The full lobby lifecycle behind these is described in Raid Finder.
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/raid/overview |
GET | none | Public overview: per-boss open lobby and queue counts plus open custom lobbies (slow poll) |
/api/raid/state |
GET | session | The caller's full raid state: queue position, lobby, deadlines, feedback owed (fast poll; doubles as the queue heartbeat) |
/api/raid/queue |
POST | session | Join the matchmaking queue for a boss |
/api/raid/queue |
DELETE | session | Leave the queue |
/api/raid/lobbies |
POST | session | Create a lobby (host) |
/api/raid/lobbies/{id} |
DELETE | session | Cancel a lobby (host or staff) |
/api/raid/lobbies/{id}/confirm |
POST | session | Member confirms within the confirm window |
/api/raid/lobbies/{id}/leave |
POST | session | Member leaves the lobby |
/api/raid/lobbies/{id}/kick |
POST | session | Host or staff removes a member |
/api/raid/lobbies/{id}/invited |
POST | session | Host confirms in-game invites were sent |
/api/raid/lobbies/{id}/report |
POST | session | Host's post-raid attendance report |
/api/raid/lobbies/{id}/feedback |
POST | session | Member's post-raid feedback (raid success, commend or dislike) |
See Trust and Awards for granting rules.
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/awards |
GET | none | Active award catalog |
/api/awards/of/{username} |
GET | none | Awards a user has received |
/api/awards/{id}/grant |
POST | session | Grant an award by username (staff always; community granting behind a feature flag plus a minimum trust score) |
/api/shinies/of/{username} |
GET | none | A user's public shiny collection; includes sprite_url (shiny variant, pre-resolved). Returns [] when the user does not exist, has a private profile, or has enabled Hide shiny collection in Settings |
See IV Calculator for the user-facing description.
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/iv/calculate |
POST | none | Enumerate all matching IV spreads. Body: {pokemon_name, cp, hp, dust_cost, trainer_level, top_stat, appraisal_bars}. Returns {candidates, count, definitive, pokemon}
|
/api/iv/ocr |
POST | session | Upload a screenshot (multipart image field, JPEG/PNG) and receive the same response shape as /api/iv/calculate after OCR extraction. Rate-limited to 10 per minute per IP |
/api/iv/pokemon |
GET | session | Paginated Pokémon box: ?limit=N&offset=N. Returns {pokemon: [...], total}
|
The OCR response carries several extra fields on top of the shared calculate shape:
-
arc_level: the level read from the level arc (when the arc scan succeeds,cp_sourceis reported asarc-level). -
best_buddy_assumed: set when the CP was interpreted as a best-buddy boosted value. -
arc_rescue: set when the arc reading rescued a spread the CP alone could not pin down. -
iv_summary: the min and max IV percent across the returned candidates. -
truncated_from: present when the candidate list was capped, giving the pre-cap count. -
species_candidates: present when the species is ambiguous, listing the plausible matches. -
name_source: how the species was identified, now includingcandy(read from the candy line, for nicknamed Pokemon) andfulltext. |/api/iv/pokemon| POST | session + CSRF | Save a Pokémon to the box. Returns HTTP 409 when the 3000-entry limit is reached | |/api/iv/pokemon/{id}| DELETE | session + CSRF | Remove a box entry by ID |
The private tier mirrors the public data endpoints without the public rate limits and bandwidth cap, and adds a refresh trigger. It requires the api_access account flag, which only the superadmin can grant and which only takes effect on admin accounts (the superadmin always has access). Requests still authenticate with the session cookie. Contact the site operator to request access.
| Endpoint | Method | Notes |
|---|---|---|
/api/private/data |
GET | Mirror of /api/data
|
/api/private/raids |
GET | Mirror of /api/raids
|
/api/private/maxbattles |
GET | Mirror of /api/maxbattles
|
/api/private/events |
GET | Mirror of /api/events
|
/api/private/events/{id} |
GET | Mirror of /api/events/{id}
|
/api/private/pokemon |
GET | Mirror of /api/pokemon
|
/api/private/moves |
GET | Mirror of /api/moves
|
/api/refresh |
POST | Triggers an immediate background re-fetch of all PoGoAPI data; globally limited to 2 requests per 10 minutes across all callers |
The mobile companion app uses a versioned prefix so the routes remain stable as the main web API evolves. All /api/mobile/v1/* routes are CSRF-exempt (mobile clients cannot set _pogo_csrf cookies). Authentication uses Bearer tokens:
Authorization: Bearer <session_token>
The session token is the same value used by the web cookie (hgo_session); it is returned by /api/mobile/v1/auth/login and remains valid until the user logs out or the token expires (30-day rolling TTL).
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/mobile/v1/auth/login |
POST | none | Exchange {username, password} for a session token. Rate-limited to 5 per minute per IP. Returns {token, user}
|
/api/mobile/v1/auth/session |
DELETE | Bearer | Log out and invalidate the token |
/api/mobile/v1/auth/me |
GET | Bearer | Current user profile including trainer_level |
/api/mobile/v1/profile |
PUT | Bearer | Update trainer name, code, level, avatar, pronouns, location fields |
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/mobile/v1/push/token |
POST | Bearer | Register a device push token. Body: {token, platform, device_name} where platform is "android" or "ios"
|
/api/mobile/v1/push/token |
DELETE | Bearer | Unregister the device push token |
Push notifications are sent by the server for raid events (match found, host kicked you, lobby cancelled, 30-second confirm warning). Android uses FCM; iOS uses APNs. Both are silently disabled when the required environment variables are absent. See Configuration for the env var names.
Stable versioned mirrors of the public data endpoints, same responses, same cache headers, no rate limits for authenticated clients.
| Endpoint | Method | Purpose |
|---|---|---|
/api/mobile/v1/pokemon |
GET | Pokémon base stats |
/api/mobile/v1/raids |
GET | Current raid bosses |
/api/mobile/v1/events |
GET | Current and upcoming events |
/api/mobile/v1/data |
GET | Full data bundle |
/api/mobile/v1/raid/overview |
GET | Per-boss lobby and queue counts (public) |
The same collection as the web /api/shinies endpoints, under the versioned path. Every entry the app receives carries a server-resolved sprite_url (costume, regional, or base variant) so the app never duplicates the sprite tables.
| Endpoint | Method | Purpose |
|---|---|---|
/api/mobile/v1/shinies |
GET | List the caller's collection, each entry with sprite_url
|
/api/mobile/v1/shinies |
POST | Add a catch; returns {id, sprite_url} for immediate render |
/api/mobile/v1/shinies/{id} |
PUT | Update an entry (shared with the web handler) |
/api/mobile/v1/shinies/{id} |
DELETE | Remove an entry |
/api/mobile/v1/shinies/{id}/evolve |
POST | Evolve a caught shiny (accepts the target region) |
/api/mobile/v1/shinies/reference |
GET | The region and catch-method choices with translated labels, so the app's pickers track the site without an app update |
Same logic as the web IV endpoints under a versioned path:
| Endpoint | Method | Purpose |
|---|---|---|
/api/mobile/v1/iv/calculate |
POST | Find IV candidates |
/api/mobile/v1/iv/ocr |
POST | Screenshot OCR; 10 per minute per IP |
/api/mobile/v1/iv/pokemon |
GET | Paginated Pokémon box |
/api/mobile/v1/iv/pokemon |
POST | Save a Pokémon to box |
/api/mobile/v1/iv/pokemon/{id} |
DELETE | Remove a box entry |
Same logic as the web raid endpoints; see Raid Finder for the state machine.
| Endpoint | Method | Purpose |
|---|---|---|
/api/mobile/v1/raid/state |
GET | Caller's full raid state (queue + lobby) |
/api/mobile/v1/raid/queue |
POST | Join the matchmaking queue |
/api/mobile/v1/raid/queue |
DELETE | Leave the queue |
/api/mobile/v1/raid/lobbies |
POST | Create a lobby |
/api/mobile/v1/raid/lobbies/{id} |
DELETE | Cancel a lobby |
/api/mobile/v1/raid/lobbies/{id}/confirm |
POST | Confirm within the confirm window |
/api/mobile/v1/raid/lobbies/{id}/leave |
POST | Leave the lobby |
/api/mobile/v1/raid/lobbies/{id}/kick |
POST | Host removes a member |
/api/mobile/v1/raid/lobbies/{id}/invited |
POST | Host confirms in-game invites were sent |
/api/mobile/v1/raid/lobbies/{id}/report |
POST | Host's post-raid attendance report |
/api/mobile/v1/raid/lobbies/{id}/feedback |
POST | Member's post-raid feedback |
| Endpoint | Method | Notes |
|---|---|---|
/api/store/webhook |
POST | PayPal server-to-server webhook (CHECKOUT.ORDER.APPROVED). CSRF-exempt; authenticity is checked by verifying the transmission signature against PAYPAL_WEBHOOK_ID through PayPal's verification API. Always answers 200 so PayPal does not retry. See Store. |
Login, registration, settings, translation, and the admin toolset are session-flow routes rather than a stable API surface and are intentionally not exhaustively documented here. The login endpoint is limited to 10 attempts per minute per IP and registration to 5 per minute per IP. For the full admin route set and the role each action requires, see the Admin Guide; for the translation endpoints see Translator Workspace.
Repository | Live site | hailsDotGO is a fan-made project, not affiliated with, endorsed by, or connected to Niantic or The Pokémon Company. Game data comes from community sources credited on the Data Sources page.
Start Here
Features
- Raids and Counters
- DPS Calculator
- IV Calculator
- PvP IV Ranker
- Events
- Shiny Tracking
- Trainer Directory
- Raid Finder
- Social Features
- Trust and Awards
- Bug Reports
- Player Reports
- Store
- Accounts and Roles
- Admin Guide
Self-Hosting
Development
Translations