MyAnimeList

MyAnimeList records, keyed by mal_id — the same key the map is built on, so any id here goes straight into /api/map/{id}.

Routes

GET/api/mal/ids

Every mal_id animap has actually fetched, with its main title, ordered by mal_id. Every id it returns resolves on /api/mal/{id}. An empty dataset returns [], never null. title may be null.

curl https://animap.id/api/mal/ids
[
  {"mal_id": 1, "title": "Cowboy Bebop"},
  {"mal_id": 5, "title": "Cowboy Bebop: Tengoku no Tobira"},
  {"mal_id": 6, "title": "Trigun"}
]

GET/api/mal/{id}

The parsed record for one mal_id. 404 if that id has not been fetched. Scores, ranks and member counts are not in this projection — they change constantly, so they are served only by /api/mal/{id}/raw. See the field reference below.

curl https://animap.id/api/mal/1
{
  "mal_id": 1,
  "title": "Cowboy Bebop",
  "title_english": "Cowboy Bebop",
  "title_japanese": "カウボーイビバップ",
  "title_synonyms": [],
  "type": "TV",
  "source": "Original",
  "status": "Finished Airing",
  "rating": "R - 17+ (violence & profanity)",
  "approved": true,
  "airing": false,
  "episodes": 26,
  "duration": "24 min per ep",
  "aired_from": "1998-04-03",
  "aired_to": "1999-04-24",
  "season": "spring",
  "year": 1998,
  "genres": ["Action", "Award Winning", "Sci-Fi"],
  "explicit_genres": [],
  "themes": ["Adult Cast", "Space"],
  "demographics": [],
  "studios": ["Sunrise"],
  "producers": ["Bandai Visual"],
  "licensors": ["Funimation", "Bandai Entertainment"],
  "synopsis": "Crime is timeless…",
  "url": "https://myanimelist.net/anime/1/Cowboy_Bebop",
  "image_url": "https://cdn.myanimelist.net/images/anime/4/19644l.jpg",
  "absent": false,
  "absent_at": null
}

GET/api/mal/{id}/raw

The full upstream MyAnimeList record for this id, served verbatim as stored. Much richer than the parsed record: this is where score, scored_by, rank, popularity, members and favorites live, along with relations, streaming, external, theme and the full images / trailer objects. 404 if the id is unknown or its payload has not been fetched yet. There is no /api/mal/{id}/raw/xml — MyAnimeList is JSON only.

These counters are a snapshot taken when we last fetched the record, not a live value. Treat them as stale by up to a couple of days.

curl https://animap.id/api/mal/1/raw
{
  "mal_id": 1,
  "url": "https://myanimelist.net/anime/1/Cowboy_Bebop",
  "title": "Cowboy Bebop",
  "type": "TV",
  "episodes": 26,
  "status": "Finished Airing",
  "aired": {"from": "1998-04-03T00:00:00+00:00", "to": "1999-04-24T00:00:00+00:00"},
  "score": 8.75,
  "scored_by": 1054321,
  "rank": 46,
  "popularity": 43,
  "members": 1980000,
  "favorites": 82000,
  "genres": [{"mal_id": 1, "type": "anime", "name": "Action"}],
  "studios": [{"mal_id": 14, "type": "anime", "name": "Sunrise"}],
  "relations": [{"relation": "Adaptation", "entry": [{"mal_id": 173, "type": "manga"}]}]
}

Field reference — /api/mal/{id}

Field Type Notes
mal_id integer The MyAnimeList id. Stable primary key, and the key of /api/map/{id}.
title string · null The default title, usually romaji.
title_english
title_japanese
string · null null for a large fraction of entries — most have no English title.
title_synonyms array of string Alternative titles. Empty [] when there are none, never null.
type string · null TV, Movie, OVA, ONA, Special, TV Special, Music, CM, PV, or the literal Unknown.
source string · null What it was adapted from: Original, Manga, Light novel, Game, …
status string · null Finished Airing, Currently Airing, or Not yet aired.
rating string · null Content rating, e.g. PG-13 - Teens 13 or older. The literal string None means MyAnimeList records no rating.
approved boolean Whether MyAnimeList has approved the entry.
airing boolean Whether it was airing when we last fetched the record.
episodes integer · null null when unknown (often for currently-airing or unaired entries).
duration string · null Free-form upstream text, not a number: 24 min per ep, 1 hr 35 min, Unknown. Parse it yourself if you need minutes.
aired_from
aired_to
string · null Air-start / air-end date as YYYY-MM-DD. aired_to is null for well over half of entries (single-episode works, and anything still airing).
season string · null winter, spring, summer or fall. null together with year for entries with no seasonal slot.
year integer · null The season's year. null exactly when season is.
genres
explicit_genres
themes
demographics
array of string Names only (the upstream ids and URLs are dropped; they are in /raw). Empty [] rather than null.
studios
producers
licensors
array of string Company names only. Empty [] rather than null.
synopsis string · null Plot summary, as written on MyAnimeList.
url string · null Canonical MyAnimeList permalink. It carries a title slug, so it is not derivable from mal_id alone.
image_url string · null A full cover-art URL on cdn.myanimelist.net (unlike AniDB's picture, which is a bare filename). Fetch it from there, not through this API.
absent boolean true when the entry has disappeared from MyAnimeList's catalogue since we archived it. The record is kept and still served — that is when this mirror is most useful. The flag clears if the entry reappears.
absent_at string · null RFC 3339 timestamp of when the entry was first observed missing. null whenever absent is false.

No scores, ranks or member counts here. score, scored_by, rank, popularity, members and favorites move for nearly every title every time we refresh it, so keeping them in the parsed projection would mean rewriting the whole table continuously for numbers that are stale the moment they are served. They are still archived, and /api/mal/{id}/raw returns them verbatim — just read them as a snapshot, not a live figure.