Practice: PokeAPI
About PokeAPI
Free Pokemon API. No authentication required. Great for learning.
-
Base URL:
pokeapi.co/api/v2 -
Documentation: pokeapi.co/docs/v2
Perfect for practicing:
-
Nested data traversal
-
Following URL references
-
Complex jq filters
-
Caching strategies
Basic Requests
Get a Pokemon
# By name
curl -s https://pokeapi.co/api/v2/pokemon/pikachu | jq
# By ID
curl -s https://pokeapi.co/api/v2/pokemon/25 | jq
# Just the basics
curl -s https://pokeapi.co/api/v2/pokemon/pikachu | jq '{name, id, height, weight}'
Pokemon Stats
# Get stats
curl -s https://pokeapi.co/api/v2/pokemon/charizard | jq '.stats[] | {stat: .stat.name, value: .base_stat}'
# Total base stats
curl -s https://pokeapi.co/api/v2/pokemon/charizard | jq '[.stats[].base_stat] | add'
Types
# Pokemon's types
curl -s https://pokeapi.co/api/v2/pokemon/bulbasaur | jq '.types[].type.name'
# All fire type Pokemon (paginated)
curl -s https://pokeapi.co/api/v2/type/fire | jq '.pokemon[:10] | .[].pokemon.name'
Abilities
# Pokemon's abilities
curl -s https://pokeapi.co/api/v2/pokemon/eevee | jq '.abilities[] | {ability: .ability.name, hidden: .is_hidden}'
# Ability details
curl -s https://pokeapi.co/api/v2/ability/intimidate | jq '{name, effect: .effect_entries[] | select(.language.name == "en") | .effect}'
Resource Lists
Paginated Lists
# List Pokemon (paginated)
curl -s "https://pokeapi.co/api/v2/pokemon?limit=10&offset=0" | jq '.results[].name'
# Count total
curl -s https://pokeapi.co/api/v2/pokemon | jq '.count'
# Next/previous pages
curl -s https://pokeapi.co/api/v2/pokemon | jq '{count, next, previous}'
Other Resources
# Generations
curl -s https://pokeapi.co/api/v2/generation | jq '.results[].name'
# Moves
curl -s "https://pokeapi.co/api/v2/move?limit=10" | jq '.results[].name'
# Items
curl -s "https://pokeapi.co/api/v2/item?limit=10" | jq '.results[].name'
Following References
PokeAPI returns URLs to related resources. You need to follow them:
# Get Pokemon's species URL
species_url=$(curl -s https://pokeapi.co/api/v2/pokemon/pikachu | jq -r '.species.url')
# Follow it
curl -s "$species_url" | jq '{name, generation: .generation.name, habitat: .habitat.name}'
Evolution Chain
# Get evolution chain (multi-step)
# 1. Get Pokemon
# 2. Get species
# 3. Get evolution chain
pokemon="eevee"
# Step through
species_url=$(curl -s "https://pokeapi.co/api/v2/pokemon/$pokemon" | jq -r '.species.url')
evo_url=$(curl -s "$species_url" | jq -r '.evolution_chain.url')
curl -s "$evo_url" | jq '.chain.evolves_to[].species.name'
Complex Queries
Pokemon Card
# Build a "Pokemon card" summary
pokemon_card() {
local pokemon="$1"
local data
data=$(curl -s "https://pokeapi.co/api/v2/pokemon/$pokemon")
echo "=== $(echo "$data" | jq -r '.name | ascii_upcase') ==="
echo "ID: $(echo "$data" | jq -r '.id')"
echo "Types: $(echo "$data" | jq -r '[.types[].type.name] | join(", ")')"
echo "Height: $(echo "$data" | jq -r '.height / 10')m"
echo "Weight: $(echo "$data" | jq -r '.weight / 10')kg"
echo ""
echo "Base Stats:"
echo "$data" | jq -r '.stats[] | " \(.stat.name): \(.base_stat)"'
echo ""
echo "Abilities:"
echo "$data" | jq -r '.abilities[] | " \(.ability.name)\(if .is_hidden then " (hidden)" else "" end)"'
}
pokemon_card charizard
Type Effectiveness
# Get type strengths/weaknesses
curl -s https://pokeapi.co/api/v2/type/fire | jq '{
name,
double_damage_to: [.damage_relations.double_damage_to[].name],
half_damage_to: [.damage_relations.half_damage_to[].name],
no_damage_to: [.damage_relations.no_damage_to[].name],
double_damage_from: [.damage_relations.double_damage_from[].name],
half_damage_from: [.damage_relations.half_damage_from[].name],
no_damage_from: [.damage_relations.no_damage_from[].name]
}'
Move Details
# Get move info
curl -s https://pokeapi.co/api/v2/move/thunderbolt | jq '{
name,
type: .type.name,
power,
accuracy,
pp,
damage_class: .damage_class.name,
effect: (.effect_entries[] | select(.language.name == "en") | .short_effect)
}'
Caching Example
PokeAPI data doesn’t change often. Cache it:
poke_cached() {
local endpoint="$1"
local cache_dir="/tmp/pokeapi_cache"
local cache_file="$cache_dir/$(echo "$endpoint" | md5sum | cut -d' ' -f1).json"
mkdir -p "$cache_dir"
if [[ -f "$cache_file" ]]; then
cat "$cache_file"
else
curl -s "https://pokeapi.co/api/v2/$endpoint" | tee "$cache_file"
fi
}
# Usage (instant after first call)
poke_cached pokemon/pikachu | jq '.name'
Shell Function
poke() {
local cmd="${1:-help}"
shift
case "$cmd" in
pokemon|p)
curl -s "https://pokeapi.co/api/v2/pokemon/$1" | jq "${2:-.}"
;;
type|t)
curl -s "https://pokeapi.co/api/v2/type/$1" | jq "${2:-.}"
;;
move|m)
curl -s "https://pokeapi.co/api/v2/move/$1" | jq "${2:-.}"
;;
ability|a)
curl -s "https://pokeapi.co/api/v2/ability/$1" | jq "${2:-.}"
;;
list)
curl -s "https://pokeapi.co/api/v2/$1?limit=${2:-20}" | jq '.results[].name' -r
;;
random)
local id=$((RANDOM % 898 + 1))
curl -s "https://pokeapi.co/api/v2/pokemon/$id" | jq '{id, name, types: [.types[].type.name]}'
;;
*)
echo "Usage: poke {pokemon|type|move|ability|list|random} [name/id] [jq filter]"
echo "Examples:"
echo " poke pokemon pikachu"
echo " poke type fire '.pokemon[:5]'"
echo " poke move thunderbolt"
echo " poke list pokemon 50"
echo " poke random"
;;
esac
}
Challenges
Challenge 1: Team Builder
# Get a random team of 6 Pokemon
for i in {1..6}; do
id=$((RANDOM % 898 + 1))
curl -s "https://pokeapi.co/api/v2/pokemon/$id" | jq -r '"\(.name) (\([.types[].type.name] | join("/")))"'
sleep 0.3
done
Challenge 2: Strongest by Stat
# Find Pokemon with highest attack (first 100)
for id in $(seq 1 100); do
curl -s "https://pokeapi.co/api/v2/pokemon/$id" 2>/dev/null | jq -r '"\(.stats[] | select(.stat.name == "attack") | .base_stat) \(.name)"'
sleep 0.2
done | sort -rn | head -10
Challenge 3: Type Coverage
# What types does this Pokemon's moves cover?
pokemon="charizard"
curl -s "https://pokeapi.co/api/v2/pokemon/$pokemon" | jq '[.moves[].move.name][:10]' | while read -r move; do
move=$(echo "$move" | tr -d '",')
[[ -z "$move" || "$move" == "[" || "$move" == "]" ]] && continue
curl -s "https://pokeapi.co/api/v2/move/$move" 2>/dev/null | jq -r '.type.name' 2>/dev/null
done | sort -u
Exercises Checklist
-
Get Pikachu’s base stats total
-
List all fire-type Pokemon names
-
Find Eevee’s evolution options
-
Get the effect text for the move "Earthquake"
-
Build a "Pokemon card" function showing key info
-
Find which types fire is super effective against
-
Create a cached version of your Pokemon function
-
Generate a random team of 6 Pokemon