A single API that aggregates anime episode lists and streaming links from multiple providers. Give it an AniList ID, get back everything — episodes, sources, and stream URLs — all in one place.
It's the backbone powering Anivexa, a full anime streaming client built on top of this.
This API intentionally uses AniList as its catalog and identity layer. When AniList is unavailable, the API may be partially unavailable or unstable as well. If you do not want an AniList-backed catalog, this simply is not the API for your use case!. So dont bother using it.
| Provider | Status | Notes |
|---|---|---|
| MKissa | ✅ Active | Large Library, Note: it may still return 403 error, their backend is one of the trickiest, it works fine but sometimes return "Need Captcha" Error. It might be slow since it will retry if it gets captcha error while requesting |
| Reanime | ✅ Active | Solid source for a wide range of titles |
| AniKoto | ✅ Active | Good library, consistent |
| AnimeGG | ✅ Active | Fuzzy title matching + compact-query fix for sequels (e.g. Re:Zero S4) |
| AniNeko | ✅ Active | Reliable slug-based matching |
| AniDB App | ✅ Active | Language-aware, AniDB ID backed |
| AniZone | ✅ Active | HLS + subtitles, sub-only; year-based re-scoring prevents wrong-season matches |
| AniWaves | ✅ Active | Direct HLS from Vidplay, MyCloud, and BYFMS; DATASV quality MP4 sources; embed fallbacks |
| Anibd | ✅ Active | Uses Anilist ID internally; AniList ID used everywhere else |
| Kickassanime | ✅ Active | Fuzzy search, medium library |
| AnimeDunya | ✅ Active | HLS + subtitles, sub-only, MAL ID backed |
| AnimeOnsen | ✅ Active | DASH + subtitles, sub-only, AniList/MAL identity verified |
GET /map/:anilistId
Returns cross-platform ID mappings — MAL, TVDB, TMDB, Kitsu, AniDB, and more.
GET /episodes/:anilistId
GET /episodes/:provider[/:provider...]/:anilistId
Returns episode lists in a single response with smart background refresh. Pass one or more provider names in the path to filter results — e.g. /episodes/anizone/mkissa/16498 returns only those two. Omit providers to get all of them.
GET /watch/:provider/:anilistId/sub|dub/:provider-:ep
Returns stream URLs for a specific episode from a specific provider.
GET /stream/reanime/:id/sub|dub/:ep
302 redirect directly to the HLS stream.
Click to see playback/decryption guide
ReAnime uses FlixCloud for some streams. The returned url can be a signed HLS master URL, but FlixCloud may return the manifest as a Base64 + XOR payload instead of plaintext #EXTM3U.
For those streams, use the returned playlist_key or key field to decode the master playlist and any child playlists before handing them to an HLS player.
function decryptFlixManifest(bodyBuffer, playlistKey) {
const raw = Buffer.isBuffer(bodyBuffer) ? bodyBuffer : Buffer.from(bodyBuffer);
const trimmed = raw.toString("utf8").trim();
if (trimmed.startsWith("#EXTM3U")) return trimmed;
const key = Buffer.from(playlistKey, "base64");
let payload = Buffer.from(trimmed, "base64");
const out = Buffer.alloc(payload.length);
for (let i = 0; i < payload.length; i++) {
out[i] = payload[i] ^ key[i % key.length];
}
const text = out.toString("utf8").trim();
if (!text.startsWith("#EXTM3U")) throw new Error("FlixCloud manifest decrypt failed");
return text;
}
function getManifestUrls(m3u8Text) {
return m3u8Text
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line && !line.startsWith("#"));
}
async function fetchAndDecryptFlixManifest(manifestUrl, playlistKey) {
const res = await fetch(manifestUrl, {
headers: {
"User-Agent": "Mozilla/5.0",
"Referer": "https://flixcloud.cc/",
"Origin": "https://flixcloud.cc"
}
});
if (!res.ok) throw new Error(`manifest HTTP ${res.status}`);
const body = Buffer.from(await res.arrayBuffer());
return decryptFlixManifest(body, playlistKey);
}HD-1 commonly uses AES-keyed HLS playlists. HD-2 commonly uses image-wrapped .png/.webp segment URLs, so a custom proxy/player may need to unwrap those segment bytes before playback.
For HD-2 style image-wrapped segments, fetch the segment through your proxy, unwrap it, and return it as video/mp2t.
const flixImageSegmentXorKey = Uint8Array.from([
157, 42, 241, 71, 179, 142, 92, 112,
166, 25, 228, 59, 216, 98, 15, 197
]);
function unwrapFlixImageSegment(bodyBuffer) {
const body = Buffer.isBuffer(bodyBuffer) ? bodyBuffer : Buffer.from(bodyBuffer);
let offset = 0;
let needsXor = false;
const isWebp =
body.length > 12 &&
body[0] === 0x52 &&
body[1] === 0x49 &&
body[2] === 0x46 &&
body[3] === 0x46 &&
body[8] === 0x57 &&
body[9] === 0x45 &&
body[10] === 0x42 &&
body[11] === 0x50;
const isPng =
body.length > 8 &&
body[0] === 0x89 &&
body[1] === 0x50 &&
body[2] === 0x4e &&
body[3] === 0x47 &&
body[4] === 0x0d &&
body[5] === 0x0a &&
body[6] === 0x1a &&
body[7] === 0x0a;
if (isWebp) {
offset = 12;
needsXor = body[offset] !== 0x47;
} else if (isPng) {
offset = 8;
needsXor = body[offset] !== 0x47;
}
if (!offset) return { body, unwrapped: false };
const out = Buffer.from(body.subarray(offset));
if (needsXor) {
for (let i = 0; i < out.length; i++) {
out[i] ^= flixImageSegmentXorKey[i % flixImageSegmentXorKey.length];
}
}
return { body: out, unwrapped: true };
}The API does not expose a public ReAnime /proxy route. If you need direct custom-player playback, use the returned embed URL or implement the manifest decode/proxy flow above.
Removed the ReAnime /proxy endpoint since it was unnecessary and did not handle the Flixcloud playback flow anyway.
git clone https://github.com/walterwhite-69/Anivexa-API
cd Anivexa-API
npm install
cp .env.example .env
node server.jsRuns on Node.js. No build step needed.
Copy .env.example to .env and fill in the values.
| Variable | Default | Notes |
|---|---|---|
CACHE_ENABLED |
false |
Set to true to enable caching (memory + disk + Redis). |
UPSTASH_REDIS_REST_URL |
— | From upstash.com. Only used when CACHE_ENABLED=true. |
UPSTASH_REDIS_REST_TOKEN |
— | From upstash.com. Only used when CACHE_ENABLED=true. |
DEFAULT_REDIS_TTL |
900 |
Seconds. Fallback expiry for Redis writes when a per-item TTL isn't computed. Most cache entries use their own smart TTLs based on anime status (finished/airing/etc.) — this is just the safety-net default. |
PORT |
4000 |
Local dev server port (server.js only — ignored on Vercel/serverless). Change it if 4000 is already in use, then hit http://localhost:PORT. |
MKISSA_WREQ_BROWSER |
chrome_149 |
wreq-js browser TLS and HTTP/2 profile used for MKissa requests. |
MKISSA_WREQ_OS |
windows |
Operating-system profile paired with the MKissa browser profile. |
MKISSA_WREQ_REQUIRED |
false |
Set to 1 to return a wreq-js error instead of falling back to Node fetch when its native binding is unavailable. |
On Vercel (or Railway/Render), set these as regular project environment variables instead of committing .env.
⚠️ Not recommended. Vercel runs on shared datacenter IPs that are widely blocked by anime streaming sites. Most providers will fail silently or return errors — the API will technically run but you'll get little to no data back. Use a self-hosted VPS or use railway, render etc etc. The proxy file is for anidb app not for streams!
Only request providers that self-host their content. No scrapers of third-party sites.
Got a provider you'd like added? Open an issue or drop it in the Discord.
This project is community-kept-alive — if it helps you, please:
- ⭐ Star the repo so others can find it
- 💬 Join the Discord to discuss, report issues, or suggest providers
- 🛠️ Open a PR if you want to add or fix something