GraphQL Examples
Ready-to-use GraphQL queries and mutations for AniList API integration.
Quick Reference
API Endpoint
https://graphql.anilist.co
Authentication
Authorization: Bearer YOUR_TOKEN
User Queries
Get Current User
Retrieve authenticated user's profile information.
query {
Viewer {
id
name
avatar {
large
medium
}
bannerImage
about
statistics {
anime {
count
meanScore
minutesWatched
episodesWatched
}
manga {
count
meanScore
chaptersRead
volumesRead
}
}
options {
displayAdultContent
titleLanguage
}
}
} Get User by Name
Search for a specific user by their username.
query ($userName: String) {
User(name: $userName) {
id
name
avatar {
large
}
bannerImage
statistics {
anime {
count
meanScore
}
}
}
}
// Variables
{
"userName": "username"
} Media Queries
Search Anime/Manga
Search for anime or manga by title.
query ($search: String, $type: MediaType) {
Page(page: 1, perPage: 20) {
media(search: $search, type: $type) {
id
title {
romaji
english
native
}
coverImage {
large
medium
color
}
type
format
status
episodes
chapters
volumes
season
seasonYear
averageScore
popularity
genres
isAdult
}
}
}
// Variables
{
"search": "Attack on Titan",
"type": "ANIME"
} Get Media Details
Get full details for a specific anime or manga.
query ($id: Int) {
Media(id: $id) {
id
title {
romaji
english
native
}
coverImage {
extraLarge
large
color
}
bannerImage
description
type
format
status
episodes
chapters
volumes
season
seasonYear
startDate {
year
month
day
}
endDate {
year
month
day
}
averageScore
meanScore
popularity
favourites
genres
tags {
name
rank
}
studios {
nodes {
name
}
}
relations {
edges {
node {
id
title {
romaji
}
coverImage {
medium
}
}
relationType
}
}
characters {
edges {
node {
id
name {
full
}
image {
medium
}
}
role
voiceActors {
name {
full
}
language
}
}
}
isAdult
}
}
// Variables
{
"id": 16498
} Airing Schedule
Get upcoming anime episodes.
query ($airingAt_greater: Int, $airingAt_lesser: Int) {
Page(page: 1, perPage: 50) {
airingSchedules(
airingAt_greater: $airingAt_greater
airingAt_lesser: $airingAt_lesser
sort: TIME
) {
id
airingAt
episode
media {
id
title {
romaji
english
}
coverImage {
large
}
status
}
}
}
}
// Variables (next 7 days)
{
"airingAt_greater": Math.floor(Date.now() / 1000),
"airingAt_lesser": Math.floor(Date.now() / 1000) + (7 * 24 * 60 * 60)
} Media List Queries
Get User's List
Retrieve user's anime or manga list.
query ($userId: Int, $type: MediaType) {
MediaListCollection(userId: $userId, type: $type) {
lists {
name
isCustomList
entries {
id
status
score
progress
progressVolumes
repeat
priority
notes
startedAt {
year
month
day
}
completedAt {
year
month
day
}
updatedAt
media {
id
title {
romaji
english
native
}
coverImage {
large
medium
}
type
format
status
episodes
chapters
volumes
averageScore
genres
isAdult
}
}
}
}
}
// Variables
{
"userId": 123456,
"type": "ANIME"
} Get Single List Entry
Get details for a specific list entry.
query ($mediaId: Int, $userId: Int) {
MediaList(mediaId: $mediaId, userId: $userId) {
id
status
score
progress
progressVolumes
repeat
priority
private
notes
hiddenFromStatusLists
startedAt {
year
month
day
}
completedAt {
year
month
day
}
updatedAt
}
}
// Variables
{
"mediaId": 16498,
"userId": 123456
} Mutations
Save Media List Entry
Add or update an entry in user's list.
mutation (
$mediaId: Int
$status: MediaListStatus
$score: Float
$progress: Int
$progressVolumes: Int
$repeat: Int
$priority: Int
$private: Boolean
$notes: String
$startedAt: FuzzyDateInput
$completedAt: FuzzyDateInput
) {
SaveMediaListEntry(
mediaId: $mediaId
status: $status
score: $score
progress: $progress
progressVolumes: $progressVolumes
repeat: $repeat
priority: $priority
private: $private
notes: $notes
startedAt: $startedAt
completedAt: $completedAt
) {
id
status
score
progress
progressVolumes
}
}
// Variables
{
"mediaId": 16498,
"status": "CURRENT",
"score": 9.5,
"progress": 12,
"notes": "Great anime!"
} Delete Media List Entry
Remove an entry from user's list.
mutation ($id: Int) {
DeleteMediaListEntry(id: $id) {
deleted
}
}
// Variables
{
"id": 123456789
} Toggle Favourite
Add or remove media from favourites.
mutation ($animeId: Int, $mangaId: Int) {
ToggleFavourite(animeId: $animeId, mangaId: $mangaId) {
anime {
nodes {
id
title {
romaji
}
}
}
manga {
nodes {
id
title {
romaji
}
}
}
}
}
// Variables (for anime)
{
"animeId": 16498
} Activity Feed
Get User Activity
Retrieve recent activity from following users.
query ($userId: Int, $page: Int) {
Page(page: $page, perPage: 20) {
activities(userId: $userId, sort: ID_DESC) {
... on ListActivity {
id
type
status
progress
createdAt
user {
id
name
avatar {
medium
}
}
media {
id
title {
romaji
}
coverImage {
medium
}
}
}
... on TextActivity {
id
type
text
createdAt
user {
id
name
avatar {
medium
}
}
}
... on MessageActivity {
id
type
message
createdAt
messenger {
id
name
avatar {
medium
}
}
}
}
}
}
// Variables
{
"userId": 123456,
"page": 1
} Advanced Queries
Trending Media
Get currently trending anime or manga.
query ($type: MediaType) {
Page(page: 1, perPage: 10) {
media(type: $type, sort: TRENDING_DESC) {
id
title {
romaji
english
}
coverImage {
large
}
trending
popularity
averageScore
genres
}
}
}
// Variables
{
"type": "ANIME"
} Seasonal Anime
Get anime from a specific season and year.
query ($season: MediaSeason, $year: Int) {
Page(page: 1, perPage: 20) {
media(
season: $season
seasonYear: $year
type: ANIME
sort: POPULARITY_DESC
) {
id
title {
romaji
english
}
coverImage {
large
}
format
episodes
status
averageScore
popularity
}
}
}
// Variables
{
"season": "FALL",
"year": 2024
} Get Recommendations
Get recommended anime/manga based on a specific media.
query ($id: Int) {
Media(id: $id) {
id
recommendations {
edges {
node {
id
rating
mediaRecommendation {
id
title {
romaji
english
}
coverImage {
large
}
type
format
averageScore
}
}
}
}
}
}
// Variables
{
"id": 16498
} Flutter Implementation Example
Example of how to make GraphQL requests in Flutter using the graphql_flutter package.
import 'package:graphql_flutter/graphql_flutter.dart';
// Initialize GraphQL client
final HttpLink httpLink = HttpLink('https://graphql.anilist.co');
final AuthLink authLink = AuthLink(
getToken: () async => 'Bearer $accessToken',
);
final Link link = authLink.concat(httpLink);
final GraphQLClient client = GraphQLClient(
cache: GraphQLCache(),
link: link,
);
// Execute query
Future<QueryResult> getUserAnimeList(int userId) async {
const String query = r'''
query ($userId: Int, $type: MediaType) {
MediaListCollection(userId: $userId, type: $type) {
lists {
name
entries {
id
status
score
progress
media {
id
title {
romaji
}
}
}
}
}
}
''';
final QueryOptions options = QueryOptions(
document: gql(query),
variables: {
'userId': userId,
'type': 'ANIME',
},
);
return await client.query(options);
}
// Execute mutation
Future<QueryResult> saveMediaListEntry(
int mediaId,
String status,
double score,
) async {
const String mutation = r'''
mutation ($mediaId: Int, $status: MediaListStatus, $score: Float) {
SaveMediaListEntry(
mediaId: $mediaId
status: $status
score: $score
) {
id
status
score
}
}
''';
final MutationOptions options = MutationOptions(
document: gql(mutation),
variables: {
'mediaId': mediaId,
'status': status,
'score': score,
},
);
return await client.mutate(options);
} Rate Limiting
⚠️ Important
AniList API has rate limits to prevent abuse:
- • 90 requests per minute for authenticated requests
- • 30 requests per minute for unauthenticated requests
- • Implement exponential backoff for retries
- • Cache responses when possible
- • Batch queries together using GraphQL fragments
Response headers include rate limit info:
X-RateLimit-Limit: 90
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1234567890
Tips & Best Practices
📝 Request Only What You Need
GraphQL allows you to request exactly the fields you need. Don't request unnecessary data to reduce response size and improve performance.
💾 Implement Caching
Cache responses locally to reduce API calls. Use packages like hive or shared_preferences.
🔄 Handle Errors Gracefully
Always check for errors in the response and provide meaningful feedback to users. Network errors, rate limits, and invalid queries should all be handled.
🔍 Use Pagination
For large datasets, always use pagination with the Page query. This prevents timeout errors and improves performance.