AniMap

animap aims to map anime between services.

This API is under active development. Expect endpoints, response formats, and data coverage to change.

I want anime mapping service - I did it.

Anime mappings with data provided. Use as much as you like. Base mapping provided to MAL. Mapping to AniDB is available. Data from AniDB (and other sites) in json and raw xml formats.

Base URL: https://animap.id

Contact: [email protected]

The map endpoint

GET/api/map/{id}

The cross-service ids for one mal_id, ids from any other services. Also contains the main title and all other known names as synonyms. The main title comes from the service the route is keyed on — MAL here, the targeted service on /api/map/{service}… routes. With year of MAL release. imdb_id and tmdb_id come from AniDB's cross-reference block for the entry's anidb_id set; a tmdb_id element carries its tv/movie namespace, since TMDB's id spaces are separate. tvdb_id lists the TheTVDB series that share an imdb_id or tmdb_id with the entry. AniDB groups a franchise onto one entry, so a franchise base may list its films' and specials' ids too.

curl https://animap.id/api/map/290
{
                    "mal_id": 290,
                    "anidb_id": [1],
                    "anilist_id": [290],
                    "ann_id": [14],
                    "kitsu_id": [265],
                    "imdb_id": ["tt0286390"],
                    "tmdb_id": [{"id": 26209, "type": "tv"}],
                    "tvdb_id": [72025],
                    "title": "Seikai no Monshou",
                    "synonyms": ["Crest of the Stars", "星界の紋章"],
                    "year": 1999
                    }

GET/api/map/{service}

The entire map, re-keyed to {service}'s id as the main one. title is that service's own title for the id.

curl https://animap.id/api/map/anidb
[{
                    "anidb_id": 1,
                    "mal_id": [290],
                    "anilist_id": [290],
                    "ann_id": [14],
                    "kitsu_id": [265],
                    "imdb_id": ["tt0286390"],
                    "tmdb_id": [{"id": 26209, "type": "tv"}],
                    "tvdb_id": [72025],
                    "title": "Seikai no Monshou",
                    "synonyms": ["Crest of the Stars", "星界の紋章"],
                    "year": 1999
                    }, …]

GET/api/map/{service}/{id}

The map projected from the requested service's standpoint: one object, keyed on {service}_id, with mal_id and every other axis as the unioned list. When one service id fans out across several MAL entries — an AniDB franchise grouping, a shared IMDb id — they are merged here rather than returned as separate rows. It is the same entry the pivoted /api/map/{service} listing carries for the id; 404 when the id is on no row. title is the targeted service's own title for the id (MAL's when the service has none).

IMDb ids are the tt-prefixed form (tt0877057); TVDB ids are the bare series integer (79481), like AniDB/AniList/ANN/Kitsu. A TMDB id is matched in both its tv and movie namespaces — a bare id cannot say which one it means — so tmdb_id stays the typed array of the matched refs (check each type), the one axis not collapsed to a scalar key. /api/map/mal/{id} is the MAL id's own key, so it stays a one-element array ([] when absent), same as /api/map's rows.

curl https://animap.id/api/map/anidb/69
{
                    "anidb_id": 69,
                    "mal_id": [21, 459, 4155, …],
                    "anilist_id": [21, 463, …],
                    "ann_id": [973],
                    "kitsu_id": [12, …],
                    "imdb_id": ["tt0388629"],
                    "tmdb_id": [{"id": 37854, "type": "tv"}],
                    "tvdb_id": [81797],
                    "title": "One Piece",
                    "synonyms": ["ワンピース", …],
                    "year": 1999
                    }

AniDB folds the whole One Piece franchise into one entry, so mal_id lists every MAL id mapped to it.

GET/api/map

The entire map, one object per MAL id (same shape as above), ordered by mal_id.

curl https://animap.id/api/map
[{
                    "mal_id": 1,
                    "anidb_id": [23],
                    "anilist_id": [1],
                    "ann_id": [13],
                    "kitsu_id": [1],
                    "imdb_id": ["tt0213338", "tt0889816"],
                    "tmdb_id": [{"id": 30991, "type": "tv"}],
                    "tvdb_id": [76885],
                    "title": "Cowboy Bebop",
                    "synonyms": [],
                    "year": 1998
                    }, …]

GET/api/search?q={query}

Full-text search over every known name of an entry. Words match as prefixes (narut finds Naruto). Each result carries the map entry's ids plus the full name bag as titles. AniDB entries without a MAL map row are included with mal_id: null and their AniDB id. Results have no imdb_id/tmdb_id/tvdb_id and no title/synonyms split; fetch the matching per-service route for those. Exact title matches are returned first, then mapped results by mal_id, then unmapped AniDB results by anidb_id. A trailing four-digit year in the query narrows search to year, so One Piece 1999 resolves to myanimelist.net/anime/21.

Punctuation is folded on both sides: × matches x (DxD finds High School D×D), apostrophes are elided (Journeys finds Journey's), and every other mark separates words (fate kaleid finds Fate/kaleid).

Optional limit (default 25, max 100). The query must contain at least two letters or digits, or exactly one together with a year.

curl 'https://animap.id/api/search?q=One+Piece+1999'
[{
                    "mal_id": 21,
                    "anidb_id": [69],
                    "anilist_id": [21],
                    "ann_id": [],
                    "kitsu_id": [12],
                    "titles": ["One Piece", "ワンピース"],
                    "year": 1999
                    }]

Per-service data

Behind the map are independent datasets, each keyed by its own upstream id and each served at two levels of detail: a flat parsed projection (/api/<service>/{id}) and the raw upstream payload, byte-for-byte as stored in /raw. Routes, examples and a full field reference are on each service's own page.

data is refreshed when it's refreshed. I use service myself, so I personally interested in most fresh dataset.

Errors

Errors are JSON with the matching HTTP status, on every route:

{"error": "not found"}

Data attribution