Evolution

Evolution chains describe how Pokémon evolve from one form to another. PokéAPI models them as a linked tree: each node (ChainLink) has a species reference, optional evolution details (level, item, condition), and an array of what it can evolve into.

Endpoints

MethodPathDescription
GET/evolution-chain/List all evolution chains (paginated)
GET/evolution-chain/{id}Get a chain by ID
GET/evolution-trigger/List evolution trigger types
GET/evolution-trigger/{name}Get trigger details

Unlike Pokémon or moves, evolution chains have no name — only a numeric ID. To find a Pokémon's chain, fetch the species (/pokemon-species/{name}/) and follow its evolution_chain.url.

Finding a chain (two-step)

  1. Fetch the Pokémon species

    curl https://pokeapi.co/api/v2/pokemon-species/eevee

    The response includes:

    {
      "evolution_chain": {
        "url": "https://pokeapi.co/api/v2/evolution-chain/67/"
      }
    }
  2. Fetch the evolution chain

    curl https://pokeapi.co/api/v2/evolution-chain/67

Example response — Eevee

{
  "id": 67,
  "baby_trigger_item": null,
  "chain": {
    "is_baby": false,
    "species": { "name": "eevee", "url": "https://pokeapi.co/api/v2/pokemon-species/133/" },
    "evolution_details": [],
    "evolves_to": [
      {
        "is_baby": false,
        "species": { "name": "vaporeon", "url": "https://pokeapi.co/api/v2/pokemon-species/134/" },
        "evolution_details": [
          {
            "trigger": { "name": "use-item", "url": "..." },
            "item": { "name": "water-stone", "url": "..." },
            "gender": null, "held_item": null, "known_move": null,
            "location": null, "min_affection": null, "min_beauty": null,
            "min_happiness": null, "min_level": null, "needs_overworld_rain": false,
            "party_species": null, "party_type": null, "relative_physical_stats": null,
            "time_of_day": "", "trade_species": null, "turn_upside_down": false
          }
        ],
        "evolves_to": []
      },
      {
        "is_baby": false,
        "species": { "name": "jolteon", "url": "..." },
        "evolution_details": [
          { "trigger": { "name": "use-item" }, "item": { "name": "thunder-stone" } }
        ],
        "evolves_to": []
      },
      {
        "is_baby": false,
        "species": { "name": "espeon", "url": "..." },
        "evolution_details": [
          {
            "trigger": { "name": "level-up" },
            "min_happiness": 220, "time_of_day": "day"
          }
        ],
        "evolves_to": []
      }
    ]
  }
}
speciesNamedAPIResourcerequired

The Pokémon species at this stage of the chain.

is_babybooleanrequired

Whether this is a baby Pokémon (requires incense to breed for in the egg).

evolution_detailsEvolutionDetail[]required

The conditions required to reach this stage from the previous one. Empty array for the base species.

evolves_toChainLink[]required

The next evolution(s). Empty for final forms. Multiple entries = branching evolution.

Common evolution triggers

TriggerWhen it fires
level-upPokémon levels up (often with min_level)
use-itemSpecific item used on Pokémon (Evolution Stone etc.)
tradePokémon is traded (sometimes while holding an item)
shedShedninja appears when Nincada evolves with a free party slot
three-critical-hitsClobbopus → Grapploct (Gen VIII)
spinMilcery → Alcremie when spinning with a Sweet held item

Flattening a chain to an array

function flattenChain(link, chain = []) {
  chain.push({
    name: link.species.name,
    trigger: link.evolution_details[0]?.trigger?.name ?? null,
    minLevel: link.evolution_details[0]?.min_level ?? null,
    item: link.evolution_details[0]?.item?.name ?? null,
  });
  for (const next of link.evolves_to) {
    flattenChain(next, chain);
  }
  return chain;
}
 
// Usage
const res = await fetch('https://pokeapi.co/api/v2/evolution-chain/67').then(r => r.json());
console.log(flattenChain(res.chain));
// [
//   { name: 'eevee',    trigger: null,       minLevel: null, item: null },
//   { name: 'vaporeon', trigger: 'use-item', minLevel: null, item: 'water-stone' },
//   { name: 'jolteon',  trigger: 'use-item', minLevel: null, item: 'thunder-stone' },
//   { name: 'espeon',   trigger: 'level-up', minLevel: null, item: null },
//   ...
// ]

For branching chains like Eevee, the flat array has multiple entries that all share the same "previous" species. Render them as a tree (not a linear list) for best UX.