Understanding Evolution Chains and Species Relationships

· 2 min read · Ash K.

Of all the resources PokéAPI exposes, evolution chains cause the most confusion for first-time integrators — not because the API is inconsistent, but because the real-world data it models is genuinely branching and conditional.

Species vs. Pokémon — two different resources

The first surprise: /pokemon-species/eevee and /pokemon/eevee are different endpoints with different jobs. Species is the taxonomic concept — Eevee-the-species has an evolution_chain URL, egg groups, and a genus. Pokémon is a specific form — Eevee has stats, types, and abilities, and its various evolutions (Vaporeon, Jolteon, Umbreon, and seven more) are each their own separate Pokémon resource, each pointing back to the same species chain. See Species vs. Pokémon for the full field reference.

An evolution chain isn't a linked list — it's a tree. Eevee's chain has eight children at the same depth (one per Eeveelution), each potentially conditional on an item, a friendship threshold, a time of day, or a held item. The response models this with an evolves_to array on every node, recursively, so a naive "walk until null" loop breaks the moment you hit Eevee.

type ChainLink = {
  species: { name: string; url: string };
  evolves_to: ChainLink[];
  evolution_details: { trigger: { name: string }; item?: { name: string } }[];
};
 
function flatten(link: ChainLink): string[] {
  return [link.species.name, ...link.evolves_to.flatMap(flatten)];
}

Recursion, not iteration — that's the whole fix. See Evolution for the complete condition-type reference (level-up, trade, item-use, friendship, and the rarer location- and time-gated triggers).

Why this matters beyond Pokémon trivia

This is a genuinely common real-world data shape — anything with conditional, branching state transitions (order fulfillment, approval workflows, game-content unlock trees) ends up looking like this. PokéAPI's evolution chain is a good, free dataset for practicing recursive-tree traversal without inventing synthetic data first.