// AniVault API — Documentation
Stream Anything.
From Anywhere.
A unified REST API to fetch anime stream URLs and embed links across multiple sources, addressed by MAL or AniList ID. Railway-ready, zero config.
Online
4 Streaming Sources
MAL Scraper
TMDB · Kitsu · AniList
Sub · Dub · Raw
Supported Sources
Each source has its own scraper. CSS selectors and resolvers are kept in sync with upstream sites.
AnimeHeaven
animeheaven.me
Keyanimeheaven
ID formatAnimeHeaven show ID
StreamsDirect MP4
AudioSub only
Anikoto
anikoto.net
Keyanikoto
ID formatTitle-search slug
ServersMegacloud, Megaplay, Kiwi Mapper
AudioSub, Dub
MegaPlay Direct
megaplay.buzz
Keymegaplay
ID formatMAL ID or AniList ID
StreamsPlayer page → HLS resolver
AudioSub / Dub (upstream dependent)
DesiDub
desidubanime.me
Keydesidub
ID formatShow slug / MAL ID
ServersMirror, VidMoly, StreamRuby, Abyss
AudioDub (Hindi/Muse/Official), Sub
API Tester
Two ways in: the guided streaming flow (search → source → server → watch), or a raw form for any of the ~35 documented endpoints.
anivault-api · tester
Anikoto
anikoto.net
AnimeHeaven
animeheaven.me
DesiDub
desidubanime.me
MegaPlay Direct
megaplay.buzz
⚡ Auto
Select an anime + episode first to load available servers
URL will appear here
Response
Waiting
Fetch data first
anivault-api · endpoint tester
← Pick an endpoint to build a request
URL Structure
Path-based is recommended. Query-based is also supported for backward compat.
Path-based (recommended)
# /api/watch/{source}/{id}/{ep}/{type}?server=Name # id = AniList ID OR mal-{malId} GET /api/watch/anikoto/20/1/sub GET /api/watch/desidub/mal-16498/1/dub?server=VMoly GET /api/watch/animeheaven/{heavenId}/3/sub
Query-based (compat)
GET /api/watch?source=desidub&malId=16498&ep=1&type=dub GET /api/watch?source=anikoto&anilistId=20&ep=1&type=sub GET /api/watch?source=animeheaven&heavenId=ukr6y&ep=5&type=sub
Endpoints
Click to expand params and example responses.
GET
/api/search
Search anime by title via AniList
▼
| Param | Type | Required | Description |
|---|---|---|---|
| q | string | required | Search query |
Example Response
{
"query": "naruto",
"count": 5,
"results": [{
"id": 20, // ← use this as anilistId
"malId": 20,
"title": "Naruto",
"coverImage": "https://s4.anilist.co/...",
"episodes": 220,
"status": "FINISHED",
"format": "TV"
}]
}
GET
/api/info
Anime metadata + all site-specific IDs
▼
| Param | Type | Required | Description |
|---|---|---|---|
| anilistId | number | one of | AniList ID |
| malId | number | one of | MyAnimeList ID |
Example Response
{
"anilistId": 20,
"malId": 20,
"title": "Naruto",
"siteIds": {
"zoro": "naruto-225", // zoro-style slug, kept for compat
"gogoanime": "naruto",
"animeheaven": "ukr6y",
"anikoto": "naruto-3"
}
}
GET
/api/episodes
Full episode list from a source
▼
| Param | Type | Required | Description |
|---|---|---|---|
| anilistId / malId | number | one required | Anime identifier |
| source | string | optional | animeheaven · anikoto |
Example Response
{
"anilistId": 20, "source": "anikoto", "count": 220,
"episodes": [
{ "num": 1, "id": "ep-id-001", "title": "Enter! Naruto Uzumaki!" }
]
}
GET
/api/servers
All available servers for an episode
▼
| Param | Type | Required | Description |
|---|---|---|---|
| anilistId / malId | number | one required | Anime identifier |
| ep | number | required | Episode number |
| type | string | optional | sub · dub · raw · all (default: sub) |
| source | string | optional | animeheaven · anikoto |
Example Response
{
"episode": 1, "type": "sub", "source": "anikoto",
"servers": [
{ "name": "Megacloud", "sourceId": "abc123", "type": "sub" },
{ "name": "Vidstreaming", "sourceId": "def456", "type": "sub" }
]
}
GET
/api/watch/{source}/{id}/{ep}/{type}
Embed URL + m3u8 + subtitles
▼
| Param | Type | Where | Description |
|---|---|---|---|
| source | string | path | animeheaven · anikoto |
| id | string | path | AniList ID or "mal-{malId}" |
| ep | number | path | Episode number |
| type | string | path | sub · dub · raw |
| server | string | query | Preferred server name (optional, e.g. "Megacloud") |
Example Response
{
"anilistId": 20, "malId": 20, "title": "Naruto",
"episode": 1, "type": "sub", "source": "anikoto",
"server": "Megacloud",
"availableServers": ["Megacloud", "Vidstreaming"],
"embedUrl": "https://megacloud.blog/embed-2/e-1/AbCdEf",
"m3u8": "https://cdn.megacloud.blog/hls/abc/master.m3u8",
"subtitles": [{ "lang": "English", "url": "https://.../en.vtt", "default": true }],
"intro": { "start": 0, "end": 90 },
"outro": { "start": 1350, "end": 1440 },
"note": null // non-null = m3u8 failed, use embedUrl instead
}
GET
/api/health
Server health + uptime + cache stats
▼
Unified with anivault.co's
/healthz shape so status.anivault.co can render both services the same way. meta.sources is a static list of configured scraper backends, not a live reachability probe of each source.Example Response
{
"status": "ok",
"checks": {
"process": {
"ok": true,
"label": "Scraper Process",
"detail": "API process is running and serving requests.",
"badges": [{ "label": "Uptime", "value": "60m" }],
"critical": true
},
"cache": {
"ok": true,
"label": "Response Cache",
"detail": "In-memory cache is active.",
"badges": [
{ "label": "Keys", "value": "12" },
{ "label": "Hits", "value": "340" },
{ "label": "Misses", "value": "22" }
],
"critical": false
}
},
"external": {},
"meta": {
"version": "1.1.0-anikoto",
"sources": ["animeheaven", "anikoto"]
},
"timestamp": "2026-06-04T12:00:00.000Z"
}
MAL Scraper
Direct MyAnimeList scraper — replaces Jikan for everything below. Cached, rate-limited to one request in flight at a time.
GET
/api/mal/anime/{id}
Full anime details
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{
"malId": 16498, "title": "Shingeki no Kyojin",
"titleEnglish": "Attack on Titan", "titleJapanese": "進撃の巨人",
"synopsis": "...", "image": "https://cdn.myanimelist.net/images/anime/10/47347.jpg",
"type": "TV", "episodes": 25, "status": "Finished Airing",
"aired": "Apr 7, 2013 to Sep 29, 2013", "score": 8.55, "rank": 115,
"genres": ["Action", "Drama"], "studios": ["Wit Studio"],
"streamingPlatforms": [{ "name": "Crunchyroll", "url": "https://..." }]
}
GET
/api/mal/anime/{id}/episodes
Paginated episode list, 100/page
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
| page | number | query | optional default 1 |
Example Response
{
"data": [
{ "malId": 1, "title": "To You, 2000 Years in the Future", "aired": "Apr 7, 2013", "filler": false, "recap": false }
],
"pagination": { "currentPage": 1, "hasNextPage": false }
}
GET
/api/mal/anime/{id}/episodes/{epNum}
One episode's title/aired/filler/recap
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
| epNum | number | path | Episode number |
Example Response
{ "data": { "malId": 1, "title": "To You, 2000 Years in the Future", "titleJapanese": "2000年後の君へ", "aired": "Apr 7, 2013", "filler": false, "recap": false } }
GET
/api/mal/anime/{id}/characters
Cast + voice actors for an anime
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{
"data": [{
"characterId": 40882, "name": "Yeager, Eren", "image": "https://cdn.myanimelist.net/...",
"role": "Main",
"voiceActors": [{ "peopleId": 118, "name": "Kaji, Yuuki", "language": "Japanese" }]
}]
}
GET
/api/mal/character/{id}
Single character: bio + animeography + voice actors in one scrape
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL character ID |
Example Response
{
"characterId": 45627, "name": "Levi (リヴァイ)", "nameKanji": "リヴァイ",
"about": "Levi is known as humanity's most powerful soldier...",
"note": "Levi is the official English translation by Kodansha.",
"spoilers": ["It is later revealed that his full name is Levi Ackerman."],
"favorites": 146754, "image": "https://cdn.myanimelist.net/...",
"animeography": [{ "animeId": 16498, "title": "Shingeki no Kyojin", "role": "Supporting" }],
"voiceActors": [{ "peopleId": 118, "name": "Kamiya, Hiroshi", "language": "Japanese" }]
}
GET
/api/mal/anime/{id}/pictures
Anime picture gallery
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{ "data": [{ "image": "https://cdn.myanimelist.net/images/anime/.../full.jpg", "thumbnail": "https://cdn.myanimelist.net/images/anime/.../small.jpg" }] }
GET
/api/mal/character/{id}/pictures
Character picture gallery
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL character ID |
Example Response
{ "data": [{ "image": "https://cdn.myanimelist.net/images/characters/.../full.jpg", "thumbnail": "https://cdn.myanimelist.net/images/characters/.../small.jpg" }] }
GET
/api/mal/anime/{id}/themes
Opening/ending theme credits + Spotify links
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{
"opening": [{ "number": 1, "title": "Guren no Yumiya", "artist": "Linked Horizon", "episodes": "1-13", "spotifyUrl": "https://open.spotify.com/track/..." }],
"ending": [{ "number": 1, "title": "Utsukushiki Zankoku na Sekai", "artist": "Yoko Hikasa", "episodes": "1-13", "spotifyUrl": null }]
}
GET
/api/mal/anime/{id}/videos
Trailers (PVs) + official music videos, with YouTube IDs
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{
"musicVideos": [{ "label": "ED 1 (Artist ver.)", "youtubeId": "kgZRAyVMcB8", "embedUrl": "https://www.youtube-nocookie.com/embed/...", "songTitle": "Utsukushiki Zankoku na Sekai", "songArtist": "Yoko Hikasa" }],
"trailers": [{ "label": "PV 1", "youtubeId": "KKzmOh4SuBc", "embedUrl": "https://www.youtube-nocookie.com/embed/...", "songTitle": null, "songArtist": null }]
}
GET
/api/mal/anime/{id}/recommendations
Top 12 "you might also like", vote-sorted
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{ "data": [{ "animeId": 28623, "title": "Koutetsujou no Kabaneri", "image": "https://cdn.myanimelist.net/...", "votes": 109 }] }
GET
/api/mal/anime/{id}/external
Official site + streaming/related outbound links
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{ "data": [{ "name": "Official Site", "url": "https://shingeki.tv/" }] }
GET
/api/mal/anime/{id}/streaming
Legal streaming platforms (Crunchyroll, Netflix, etc.)
▼
| Param | Type | Where | Description |
|---|---|---|---|
| id | number | path | MAL anime ID |
Example Response
{ "data": [{ "name": "Crunchyroll", "url": "https://www.crunchyroll.com/..." }] }
GET
/api/mal/search
MAL text search (Jikan-shaped)
▼
| Param | Type | Required | Description |
|---|---|---|---|
| q | string | required | Search query |
| limit | number | optional | default 8 |
Example Response
{ "data": [{ "malId": 16498, "title": "Shingeki no Kyojin", "image": "https://cdn.myanimelist.net/...", "type": "TV", "episodes": 25, "score": 8.55 }] }
AniList · TMDB · Kitsu
Supplementary metadata and art. All three "anime art" endpoints (
/anilist/anime, /tmdb/anime, /kitsu/anime) return the same shape so they're interchangeable as fallbacks.
GET
/api/anilist/season
Current airing season from AniList
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | optional | Return just this one show's entry from the season |
Example Response
{ "season": "SUMMER", "seasonYear": 2026, "media": [{ "idMal": 16498, "title": "..." }] }
GET
/api/anilist/top-banners
Banner images for top-rated anime, keyed by MAL ID
▼
| Param | Type | Required | Description |
|---|---|---|---|
| limit | number | optional | default 200 |
| malId | number | optional | Return just this one entry |
Example Response
{ "data": { "16498": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/16498.jpg" } }
GET
/api/anilist/id
MAL ID → AniList ID
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | required | MAL anime ID |
Example Response
{ "malId": 16498, "anilistId": 16498 }
GET
/api/anilist/episodes
AniList's streamingEpisodes list (titles + thumbnails, last-resort fallback)
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | required | MAL anime ID |
| ep | number | optional | Return just this one episode |
Example Response
{ "malId": 16498, "episodes": [{ "title": "Episode 1 - To You, in 2000 Years", "thumbnail": "https://s4.anilist.co/..." }] }
GET
/api/{anilist|tmdb|kitsu}/anime
Poster + cover art (+ logo on TMDB) — same shape across all 3
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | one of | MAL anime ID |
| title | string | one of | Direct title search, skips MAL lookup (TMDB/Kitsu only) |
| list | string | optional | 1 to skip cache (fresh lookup) |
Example: /api/tmdb/anime?malId=16498
{ "data": { "poster": "https://image.tmdb.org/t/p/original/...", "cover": "https://image.tmdb.org/t/p/original/...", "logo": "https://image.tmdb.org/t/p/original/..." }, "log": ["..."] }
Example: /api/kitsu/anime?malId=16498
{ "data": { "poster": "https://media.kitsu.app/anime/poster_images/.../original.jpg", "cover": "https://media.kitsu.app/anime/cover_images/.../original.jpg" }, "log": ["..."] }
GET
/api/{tmdb|kitsu}/episode-thumb
Single episode still/thumbnail
▼
| Param | Type | Required | Description |
|---|---|---|---|
| ep | number | required | Episode number |
| malId | number | one of | MAL anime ID |
| title | string | one of | Direct title search |
Example Response
{ "data": { "thumbnail": "https://image.tmdb.org/t/p/original/still.jpg" }, "log": ["..."] }
Combined Endpoints
One call instead of chaining several — MAL metadata merged with art/thumbnails from the fallback chain above.
GET
/api/anime
MAL details + poster/cover/logo, one call
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | required | MAL anime ID |
| list | string | optional | 1 to skip art cache |
Example Response
{
"data": {
"malId": 16498, "title": "Shingeki no Kyojin", "episodes": 25, "score": 8.55,
"genres": ["Action"], "streamingPlatforms": [{ "name": "Crunchyroll", "url": "..." }],
"poster": "https://image.tmdb.org/...", "posterSource": "tmdb",
"cover": "https://image.tmdb.org/...", "coverSource": "tmdb",
"logo": "https://image.tmdb.org/...", "logoSource": "tmdb"
},
"log": ["..."]
}
GET
/api/episode
MAL episode metadata + thumbnail (single episode, or the whole show)
▼
| Param | Type | Required | Description |
|---|---|---|---|
| malId | number | required | MAL anime ID |
| ep | number | optional | Omit for the whole show's episode list |
| concurrency | number | optional | Whole-show mode only. Default 5, max 10 |
| list | string | optional | 1 to skip thumbnail cache |
Example: single episode (?ep=1)
{
"data": {
"malId": 16498, "episode": 1, "title": "To You, 2000 Years in the Future",
"aired": "Apr 7, 2013", "filler": false, "recap": false,
"thumbnail": "https://media.kitsu.app/...", "thumbnailSource": "kitsu"
},
"log": ["..."]
}
Example: whole show (no ?ep=)
{
"malId": 16498, "title": "Attack on Titan", "count": 25,
"episodes": [{ "episode": 1, "title": "...", "thumbnail": "...", "thumbnailSource": "tmdb" }]
}
Error Codes
All errors return
{ "error": "message", "detail": "..." }
AniVault API · Built for educational use · Selectors require periodic maintenance after site updates
Megacloud keys may rotate — check aniwatch-api for updates
Megacloud keys may rotate — check aniwatch-api for updates