A free, typed and edge-cached GraphQL API for PokéAPI.
Ask for a Pokémon. Get only what you asked for. No API key.
- Ask for less. Pick the fields you need. A
pokemonquery can be thousands of times smaller than the REST response. - One request. Follow relations (types, moves, abilities, species) in the same query.
- Typed schema. Your editor can autocomplete every field.
- Edge cached. Repeat queries come from the edge, not from PokéAPI.
- Free and open source. MIT license. No sign-up, no API key.
curl -X POST https://graphql-pokeapi.graphcdn.app/ \
-H 'Content-Type: application/json' \
-d '{"query":"{ pokemon(name: \"ditto\") { id name } }"}'{ "data": { "pokemon": { "id": 132, "name": "ditto" } } }Open the homepage to try the live Query Lab, or the playground to write your own queries.
| Use | URL |
|---|---|
| Edge cached (recommended) | https://graphql-pokeapi.graphcdn.app/ |
| Origin | https://gql-poke.mazipan.space/api/graphql |
| Playground | https://gql-poke.mazipan.space/api/graphql |
| Homepage | https://gql-poke.mazipan.space |
GET requests: the server blocks a plain
GETas CSRF protection. Add the headerapollo-require-preflight: true, or send aPOSTwithContent-Type: application/json.
The homepage has copy-ready samples for Fetch, Apollo Client, urql, graphql-request, TanStack Query, Python and curl.
Runnable files are in examples/:
- WIP - Fetch API - GET
- Fetch API - POST
- WIP - Apollo - GET
- Apollo - POST
All 28 queries. Most detail queries return params, status, message and response, where response is JSON. The pokemon and pokemons queries return typed fields.
| Query | Description | Arguments |
|---|---|---|
abilities |
Get list of abilities | |
ability |
Get detail of ability | ability: String! |
berries |
Get list of berries | |
berry |
Get detail of berry | berry: String! |
eggGroups |
Get list of egg groups | |
eggGroup |
Get detail of egg group | eggGroup: String! |
encounterMethods |
Get list of encounter methods | |
encounterMethod |
Get detail of encounter method | encounterMethod: String! |
evolutionChains |
Get list of evolution chains | |
evolutionChain |
Get detail of evolution chain | id: String! |
evolutionTriggers |
Get list of evolution triggers | |
evolutionTrigger |
Get detail of evolution trigger | name: String! |
genders |
Get list of genders | |
gender |
Get detail of gender | gender: String! |
growthRates |
Get list of growth rates | |
growthRate |
Get detail of growth rate | growthRate: String! |
locations |
Get list of locations | |
location |
Get detail of location | location: String! |
moves |
Get list of moves | |
move |
Get detail of move | move: String! |
natures |
Get list of natures | |
nature |
Get detail of nature | nature: String! |
pokemons |
Get list of Pokémon | limit: Int, offset: Int |
pokemon |
Get detail of Pokémon | name: String! |
regions |
Get list of regions | |
region |
Get detail of region | region: String! |
species |
Get list of species | |
types |
Get list of types |
Every query has a sample query, sample variables and a real result on the homepage.
Sample query
query pokemons($limit: Int, $offset: Int) {
pokemons(limit: $limit, offset: $offset) {
count
next
previous
status
message
results {
url
name
image
}
}
}Sample variables
{
"limit": 2,
"offset": 1
}Sample result
{
"data": {
"pokemons": {
"count": 964,
"next": "https://pokeapi.co/api/v2/pokemon/?offset=3&limit=3",
"previous": null,
"results": [
{
"url": "https://pokeapi.co/api/v2/pokemon/1/",
"name": "bulbasaur",
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png"
},
{
"url": "https://pokeapi.co/api/v2/pokemon/2/",
"name": "ivysaur",
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/2.png"
},
{
"url": "https://pokeapi.co/api/v2/pokemon/3/",
"name": "venusaur",
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/3.png"
}
],
"status": true,
"message": ""
}
}
}Sample query
query pokemon($name: String!) {
pokemon(name: $name) {
id
name
abilities {
ability {
name
}
}
moves {
move {
name
}
}
types {
type {
name
}
}
message
status
}
}Sample variables
{
"name": "ditto"
}Sample result
{
"data": {
"pokemon": {
"id": 132,
"name": "ditto",
"abilities": [{ "ability": { "name": "imposter" } }, { "ability": { "name": "limber" } }],
"moves": [{ "move": { "name": "transform" } }],
"types": [{ "type": { "name": "normal" } }],
"message": "",
"status": true
}
}
}The project is a static homepage (public/) and Vercel Functions (api/). It needs Node 26 (see engines.node in package.json) and npm.
npm ci # install
npm run build # build the CSS and the homepage into public/
npm run serve # build, then serve public/ on a local port
npm start # run the functions with `vercel dev` (needs `vercel login`)
npx eslint . # lint| Path | What it does |
|---|---|
api/graphql.js |
Apollo Server 5 handler |
typeDefs/, resolvers/ |
GraphQL schema and resolvers |
requests/ |
Calls to PokéAPI |
public/ |
Homepage template (index.ejs), styles, query data |
stellate.ts |
Edge cache configuration |
Before you upgrade a dependency, read AGENTS.md. Some packages are held back on purpose. Always test a Vercel preview deploy.
If you use graphql-pokeapi, add your app to awesome-list.md.
- PokéAPI
- Pokedex Promise V2
- Apollo Server
- Stellate for the edge cache
- Vercel
Thanks to these wonderful people!
This is an unofficial project. It is not affiliated with Nintendo, The Pokémon Company or PokéAPI.
MIT © Irfan Maulana