Skip to main content

Documentation Index

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

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

The Pokémon Showdown Replays API gives you programmatic access to recorded battle replays hosted at replay.pokemonshowdown.com. Every endpoint sets Access-Control-Allow-Origin: *, so you can call them directly from browser JavaScript without a proxy. Replays are identified by a slug that combines the format name and a numeric battle ID (e.g. gen8doublesubers-1097585496). In addition to individual replay retrieval, the search endpoint lets you filter by player, format, or both, and supports cursor-based pagination for large result sets.
All Pokémon Showdown web APIs are available by appending .json to most PS URLs. The .log and .inputlog suffixes are convenience aliases — the same data is always present inside the .json response.

Get a Replay

JSON replay

curl https://replay.pokemonshowdown.com/gen8doublesubers-1097585496.json
GET https://replay.pokemonshowdown.com/{id}.json Returns the full replay object, including the complete battle log and metadata.
id
string
required
The replay identifier. Follows the pattern {format}-{battleNumber}, for example gen8doublesubers-1097585496 or gen8randombattle-2005209836.

Response

id
string
The replay ID (e.g. gen8doublesubers-1097585496).
format
string
The format ID this battle was played in (e.g. gen8doublesubers).
players
string[]
Array of player usernames in turn order. Two entries for a standard battle.
log
string
The full battle log in Pokémon Showdown protocol format. This is the same content served by the .log endpoint.
inputlog
string | null
The input log recording player decisions. Only present for formats with auto-generated teams (e.g. Random Battle). Matches the .inputlog endpoint.
uploadtime
number
Unix timestamp (seconds) when the replay was uploaded. Used as the cursor value for paginating search results.
rating
number | null
Average Elo rating of the two players at the time of the battle, or null for unrated games.

Raw battle log

GET https://replay.pokemonshowdown.com/{id}.log Returns the battle log as plain text — identical to the log field in the JSON response. Useful when you only need the protocol output without the rest of the metadata.
curl https://replay.pokemonshowdown.com/gen8doublesubers-1097585496.log
Prefer the .json endpoint when you need both metadata and the log in a single request. Use .log only when you specifically want plain text output.

Input log

GET https://replay.pokemonshowdown.com/{id}.inputlog Returns the raw input log as plain text. This endpoint is only meaningful for formats where teams are auto-generated (Random Battle and its variants). For teambuilder formats the server does not record individual player inputs, and this endpoint may return an empty body or an error.
curl https://replay.pokemonshowdown.com/gen8randombattle-2005209836.inputlog
Do not request .inputlog for teambuilder formats — the data will not be present. Check the inputlog field of the JSON response first to confirm it is non-null before building tooling around this endpoint.

Search Replays

GET https://replay.pokemonshowdown.com/search.json Search and browse replays with optional filters. All parameters are optional; omitting them all returns a list of the most recently uploaded replays.
Results are capped at 51 entries per page. If exactly 51 results are returned, at least one additional page exists. Pages are offset by 50, so use the uploadtime of the 51st result as the before cursor for the next page.

Query parameters

user
string
Filter replays to those involving this username. The server normalises the value to a lowercase ID, so capitalisation does not matter.
user2
string
When provided alongside user, only return replays where both user and user2 appear as participants. Has no effect without user.
format
string
Filter by format ID, e.g. gen8ou or gen7randombattle. Must match the canonical format ID exactly.
before
number
Cursor for pagination. Pass the uploadtime (Unix timestamp) of the last replay in the current page to retrieve the next page of older results.
page
number
Legacy numeric page offset. Poorly supported — avoid in new integrations. Use before for reliable pagination instead.

Examples

curl
curl "https://replay.pokemonshowdown.com/search.json"

JavaScript pagination example

fetch
async function* searchReplays(params = {}) {
  const base = "https://replay.pokemonshowdown.com/search.json";
  let cursor = params.before ?? undefined;

  while (true) {
    const url = new URL(base);
    if (params.user)   url.searchParams.set("user",   params.user);
    if (params.user2)  url.searchParams.set("user2",  params.user2);
    if (params.format) url.searchParams.set("format", params.format);
    if (cursor !== undefined) url.searchParams.set("before", String(cursor));

    const page = await fetch(url).then((r) => r.json());

    // Yield the first 50 results (the 51st is just a "more pages" sentinel)
    yield page.slice(0, 50);

    if (page.length < 51) break; // no more pages
    cursor = page[50].uploadtime;
  }
}

// Usage: iterate all replays for a user
for await (const batch of searchReplays({ user: "zarel" })) {
  for (const replay of batch) {
    console.log(replay.id, replay.format, replay.uploadtime);
  }
}

Response

The endpoint returns a JSON array. Each element is a replay summary object.
[].id
string
Replay identifier (e.g. gen8ou-1234567890).
[].format
string
Format ID of the battle.
[].players
string[]
Usernames of both players.
[].uploadtime
number
Unix timestamp of upload. Use as the before cursor value when paginating.
[].rating
number | null
Average Elo at time of battle, or null for unrated games.

Dex Resources

Static JSON dumps of Pokédex and move data are served from the main client origin and are suitable for caching aggressively. Like all PS web endpoints, they carry Access-Control-Allow-Origin: *.

Pokédex

GET https://play.pokemonshowdown.com/data/pokedex.json Returns a JSON object keyed by Pokémon ID (e.g. "pikachu") containing base stats, types, abilities, and other species data.
curl
curl https://play.pokemonshowdown.com/data/pokedex.json

Moves

GET https://play.pokemonshowdown.com/data/moves.json Returns a JSON object keyed by move ID (e.g. "thunderbolt") containing base power, accuracy, PP, type, category, and effect metadata.
curl
curl https://play.pokemonshowdown.com/data/moves.json
Both dex resources can be hundreds of kilobytes. Load them once at startup and cache the result in memory rather than fetching on every request.

Build docs developers (and LLMs) love