Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/smogon/pokemon-showdown/llms.txt

Use this file to discover all available pages before exploring further.

This page documents the message types used for communication between clients and servers, including room initialization, chat, authentication, and global events.

User Representation

USER represents a user with their rank as the first character (users with no rank use a space), followed by their username. Optionally, USER may be appended with @ followed by a status message, or @! to indicate the user is away.

Room Initialization

Init

|init|ROOMTYPE
The first message received when joining a room. ROOMTYPE is one of:
  • chat - A chat room
  • battle - A battle room

Title

|title|TITLE
Sets the room title. The title is not guaranteed to resemble the room ID.
For example, room battle-gen7uu-779767714 could have title Alice vs. Bob.

Users List

|users|USERLIST
Sent when joining chat rooms. USERLIST is a comma-separated list of USERs.

Room Messages

Raw Message

||MESSAGE
or
MESSAGE
Displays MESSAGE directly in the room log.

HTML Message

|html|HTML
Displays sanitized HTML directly in the room log.

Updatable HTML

|uhtml|NAME|HTML
Displays HTML that can be updated later (used for polls, etc.).
|uhtmlchange|NAME|HTML
Updates the HTML of a previous |uhtml| message.

Join

|join|USER
|j|USER
|J|USER
USER joined the room.
  • Lowercase j is for normal display
  • Uppercase J indicates high-frequency events that should not be displayed inline

Leave

|leave|USER
|l|USER
|L|USER
USER left the room.

Name Change

|name|USER|OLDID
|n|USER|OLDID
|N|USER|OLDID
A user changed their name to USER from OLDID.

Chat

|chat|USER|MESSAGE
|c|USER|MESSAGE
USER said MESSAGE.
MESSAGE can contain | characters, so you cannot simply split by | and take the fourth element.

Special Messages

If MESSAGE starts with /, it’s a special command:
  • /me TEXT - Action message
  • /announce TEXT - Announcement
  • /uhtml HTML - HTML in PM (stopgap before client rewrite)
If the server wants to render a message starting with /, it will send it starting with //.

Timestamped Chat

|:|TIMESTAMP
Sets the current server time (UNIX timestamp).
|c:|TIMESTAMP|USER|MESSAGE
Same as |c| but includes a UNIX timestamp for accurate chat logs.

Notify

|notify|TITLE|MESSAGE
Sends a notification. TITLE is usually bold, MESSAGE is optional.
|notify|TITLE|MESSAGE|HIGHLIGHTTOKEN
Sends a notification only if HIGHLIGHTTOKEN would trigger the user’s highlight settings.

Battle Started

|battle|ROOMID|USER1|USER2
|b|ROOMID|USER1|USER2
A battle started between USER1 and USER2 in room ROOMID.

Global Messages

|popup|MESSAGE
Shows a popup containing MESSAGE. || denotes a newline.

Private Message

|pm|SENDER|RECEIVER|MESSAGE
A PM was sent from SENDER to RECEIVER.

User Count

|usercount|USERCOUNT
Indicates the number of users on the server.

Name Taken

|nametaken|USERNAME|MESSAGE
Your attempt to change to USERNAME failed for the reason in MESSAGE.

Authentication

Challenge String

|challstr|CHALLSTR
Received upon connection. Used for authentication.
1

Check for existing session

If you have session cookies, make an HTTP GET request:
https://play.pokemonshowdown.com/api/upkeep?challstr=CHALLSTR
2

Or login with credentials

Make an HTTP POST request with:
https://play.pokemonshowdown.com/api/login
With data:
name=USERNAME&pass=PASSWORD&challstr=CHALLSTR
3

Parse response

The response starts with ] followed by a JSON object. Extract data.assertion.
4

Complete login

Send to the server:
/trn USERNAME,0,ASSERTION
Where ASSERTION is data.assertion from the previous step.

Update User

|updateuser|USER|NAMED|AVATAR|SETTINGS
Your name, avatar, or settings changed successfully.
  • USER - Your rank and username
  • NAMED - 0 if guest, 1 otherwise
  • AVATAR - Your avatar identifier
  • SETTINGS - JSON object with user settings

Format and Search Messages

Formats List

|formats|FORMATSLIST
Lists available battle formats. FORMATSLIST is pipe-separated with these suffixes:
  • ,# - Uses random teams
  • ,, - Only available for searching
  • , - Only available for challenging
Sections are separated by || with column numbers.
|updatesearch|JSON
JSON represents the current state of battle searches. Example:
{
  "searching": ["gen9ou", "gen9randombattle"],
  "games": {
    "battle-gen9ou-12345": "Player1 vs. Player2"
  }
}

Update Challenges

|updatechallenges|JSON
JSON represents current challenge state. Example:
{
  "challengesFrom": {
    "player1": "gen7randombattle"
  },
  "challengeTo": {
    "to": "player2",
    "format": "gen7ou"
  }
}

Query Response

|queryresponse|QUERYTYPE|JSON
Response to /query QUERYTYPE commands. Possible queries:
  • /query roomlist - List of rooms
  • /query userdetails USERNAME - User information

Challenge System

Sending a Challenge

/utm TEAM
/challenge USERNAME, FORMAT
TEAM is in packed format or null for formats like Random Battle.

Accepting a Challenge

/utm TEAM
/accept USERNAME

Rejecting a Challenge

/reject USERNAME

Canceling a Challenge

/cancelchallenge USERNAME

Ladder System

/utm TEAM
/search FORMAT
/cancelsearch

Tournament Messages

Create Tournament

|tournament|create|FORMAT|GENERATOR|PLAYERCAP
  • FORMAT - Battle format name
  • GENERATOR - Elimination or Round Robin
    • Elimination includes prefix: Single, Double, etc.
    • Round Robin includes Double prefix if matchups battle twice
  • PLAYERCAP - Maximum players, or 0 for no cap

Tournament Update

|tournament|update|JSON
JSON object with tournament changes:
{
  "format": "gen9ou",
  "teambuilderFormat": "gen9ou",
  "isStarted": true,
  "isJoined": true,
  "generator": "Single Elimination",
  "playerCap": 16,
  "bracketData": {},
  "challenges": [],
  "challengeBys": [],
  "challenged": null,
  "challenging": null
}

Tournament Events

|tournament|updateEnd
Signals end of update period.
|tournament|error|ERROR
An error occurred.
|tournament|forceend
Tournament was forcibly ended.
|tournament|join|USER
USER joined the tournament.
|tournament|leave|USER
USER left the tournament.
|tournament|replace|OLD|NEW
OLD was replaced with NEW.
|tournament|start|NUMPLAYERS
Tournament started with NUMPLAYERS participants.
|tournament|disqualify|USER
USER was disqualified.

Tournament Battles

|tournament|battlestart|USER1|USER2|ROOMID
Tournament battle started between USER1 and USER2.
|tournament|battleend|USER1|USER2|RESULT|SCORE|RECORDED|ROOMID
Tournament battle ended.
  • RESULT - From USER1’s perspective: win, loss, or draw
  • SCORE - Array [USER1_POKEMON_LEFT, USER2_POKEMON_LEFT]
  • RECORDED - success or fail (if bracket doesn’t support draws)
|tournament|end|JSON
Tournament ended with results:
{
  "results": ["Winner1", "Winner2"],
  "format": "gen9ou",
  "generator": "Single Elimination",
  "bracketData": {}
}

Tournament Settings

|tournament|scouting|SETTING
Scouting is now allow or disallow.
|tournament|autostart|on|TIMEOUT
Auto-start timer set for TIMEOUT seconds.
|tournament|autostart|off
Auto-start timer turned off.
|tournament|autodq|on|TIMEOUT
Auto-disqualify timer set for TIMEOUT seconds.
|tournament|autodq|off
Auto-disqualify timer turned off.
|tournament|autodq|target|TIME
You have TIME seconds to act or be disqualified.

Next Steps

Battle Protocol

Learn about battle-specific message types

Choice Requests

Understand how to make decisions in battles