WebSocket messages
The live channel: every message the client sends and the server pushes.
Everything that happens in real time (encounters, battles, challenges, trades, tournaments, flyovers) travels over one WebSocket at /pokemon-ws?token=<ID token>. Messages are JSON objects with a t field naming the message. Open one socket per tab; a trainer may have many tabs, and battle updates reach all of them. When the sign-in token refreshes, reconnect with the new one.
The first message on a new socket is welcome. Send context right after it and again whenever the page, the visibility or the local hour changes: the server uses it to place encounters (full screen or as a side panel on a live page), to pick the community's wild pool and to know the time of day.
These tables are generated from the ClientMessage and ServerMessage unions in net/protocol.ts.
Client to server
t | Fields |
|---|---|
context | context: ClientContext |
battle-action | battleId: string; turn: number; action: BattleAction |
battle-forfeit | battleId: string |
challenge | toUserId: string; communityHandle: string | null |
challenge-response | challengeId: string; accept: boolean |
gym-challenge | communityHandle: string |
encounter-dismiss | battleId: string |
debug-encounter | speciesId: number | null |
tournament-open | communityHandle: string |
tournament-enter | tournamentId: string; team: string[] |
tournament-leave | tournamentId: string |
tournament-start | tournamentId: string |
tournament-cancel | tournamentId: string |
tournament-final | tournamentId: string; hostTeam: string[] | null |
stage-decision | tournamentId: string; invited: boolean |
legendary-event | communityHandle: string; speciesId: number |
flyover-engage | flyoverId: string |
ping | none |
Server to client
t | Fields |
|---|---|
welcome | me: MeResponse; serverTime: number |
trainer | trainer: TrainerState |
encounter | battle: BattleView; display: "fullscreen" | "panel" |
battle-start | battle: BattleView; deadline: number | null |
battle-update | battle: BattleView; events: BattleEvent[]; deadline: number | null |
battle-end | battle: BattleView; events: BattleEvent[]; rewards: BattleRewards | null |
challenge-incoming | challenge: ChallengeView |
challenge-closed | challengeId: string; reason: "declined" | "expired" | "cancelled" | "accepted" | "busy" |
trade | trade: TradeView |
tournament | tournament: TournamentView |
stage-request | tournamentId: string; winner: TrainerSummary |
stage-result | tournamentId: string; invited: boolean |
legendary | communityHandle: string; speciesId: number; by: TrainerSummary |
toast | level: "info" | "success" | "warning"; text: string |
error | code: string; message: string |
flyover | flyover: FlyoverView |
flyover-closed | flyoverId: string; reason: "engaged" | "expired" | "stolen" |
pong | serverTime: number |
TapIn Pokémon is an unofficial fan project. Pokémon and all related names and artwork are trademarks and © of Nintendo, Game Freak and Creatures. Legal