v1.0.0 API Live
Animetsu API Logo

ANIMETSU API

The ultimate high-performance anime and manga data aggregator. Stream episodes, get schedules, and build amazing apps instantly.

Lightning Fast

Edge-ready architecture deployed on Cloudflare Workers or Vercel Edge.

Comprehensive Data

Access huge anime/manga datasets, schedules, and top lists in milliseconds.

Built-in Proxy

Seamless streaming with built-in HLS proxy bypassing CORS constraints.

Global CDN

Cached responses distributed globally to ensure low latency for users.

Live API Playground

Test endpoints and view live HLS streams directly from your browser.

Live Request Playground

localhost:3000
cURL Equivalent
curl -X GET "http://localhost:3000/api/trending" -H "Accept: application/json"
Response Output (JSON)
Awaiting request...

HLS Demo Showcase

Interact with the API and see how easy it is to implement proxy streaming.

No servers found or checking... (Try clicking one below)
Select a server to play

Using the API from your app

The killer feature is proxy_url in every /api/watch source — a fully absolute URL on your own host that any media player can hit without custom headers and without CORS hoops.

1. Fetch Data & Init HLS.js

const res = await fetch(`/api/watch?id=6989bf2429cf95f4eb040650&ep=1&server=pahe`);
const json = await res.json();

const hls = new Hls();
hls.loadSource(json.data.sources[0].proxy_url);
hls.attachMedia(document.querySelector('video'));

2. Realtime Quality Switcher

// Read available qualities from the proxy stream
hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
const qualities = data.levels; // [1080p, 720p, 480p]
});

// Instantly change quality seamlessly
document.getElementById('btn-1080p').onclick = () => {
hls.currentLevel = 0; // Array index of quality
};

3. Injecting Subtitles (Soft Subs)

json.data.subtitles.forEach(sub => {
const track = document.createElement("track");
track.kind = "subtitles";
track.label = sub.label;
track.src = sub.url;
video.appendChild(track);
});

// Toggle on/off via custom CC button
video.textTracks[0].mode = "showing"; // or "hidden"
<div align="center"> <img src="./public/logo.png" alt="Animetsu Logo" width="600" style="border-radius: 12px; margin-bottom: 20px; box-shadow: 0 4px 14px rgba(0,0,0,0.5);" /> <h1>🌟 Animetsu API 🌟</h1> <p><strong>The Ultimate, High-Performance Anime Streaming API & Proxy Layer</strong></p> <p> <img src="https://img.shields.io/badge/Next.js-14-black?style=for-the-badge&logo=next.js" /> <img src="https://img.shields.io/badge/TypeScript-Pro-blue?style=for-the-badge&logo=typescript" /> <img src="https://img.shields.io/badge/HLS.js-Streaming-red?style=for-the-badge" /> <img src="https://img.shields.io/badge/JWPlayer-Supported-ff0055?style=for-the-badge" /> </p> </div> <br/>

📖 Table of Contents


✨ Features

  • Built-in HLS Proxy: Direct playback of Cloudflare-protected .m3u8 playlists without passing custom headers in your client.
  • Subtitle Parsing: Soft-subs are extracted, proxied, and parsed cleanly.
  • Edge Optimized: Built on Next.js Edge runtime for massive concurrency.
  • Cross-Origin Ready: Bypasses CORS effortlessly.

🚀 Quick Start

  1. Clone & Install
    git clone https://github.com/your-username/animetsu-api.git
    cd animetsu-api
    npm install
    
  2. Run Development Server
    npm run dev
    

    Server runs on http://localhost:3000


☁️ Deployment

This project is optimized for the Edge and deploys seamlessly to Cloudflare Pages using @cloudflare/next-on-pages.

  1. Go to your Cloudflare Dashboard.
  2. Navigate to Workers & Pages -> Create application -> Pages -> Connect to Git.
  3. Select your repository and use the following build settings:
    • Framework preset: Next.js
    • Build command: npx @cloudflare/next-on-pages
    • Build output directory: .vercel/output/static

Manual Deployment Guide

  1. Install Wrangler CLI globally (if not already)

    npm install -g wrangler
    
  2. Login to Cloudflare

    wrangler login
    
  3. Build the Project for Cloudflare Pages

    npx @cloudflare/next-on-pages
    
  4. Deploy to Cloudflare Pages

    npx wrangler pages deploy .vercel/output/static --project-name animetsu-api
    

🎮 Player Integration

JWPlayer handles .m3u8 qualities natively and parses subtitles perfectly.

<details> <summary><b>Show JWPlayer Code</b></summary>
<!-- Include JWPlayer Library -->
<script src="https://content.jwplatform.com/libraries/KB5zFt7A.js"></script>
<div id="player"></div>
// 1. Fetch Watch Data
const res = await fetch(`http://localhost:3000/api/watch?id=6989bf2429cf95f4eb040650&ep=1&server=pahe&source_type=sub`);
const json = await res.json();
const watchData = json.data;

// 2. Map subtitles to JWPlayer Track format
const tracks = watchData.subtitles?.map(sub => ({
  file: sub.url, // Proxied soft-subs!
  label: sub.label,
  kind: "captions",
  "default": sub.label.toLowerCase().includes("english")
})) || [];

// 3. Initialize JWPlayer
jwplayer("player").setup({
  playlist: [{
    file: watchData.sources[0].proxy_url, // Automatically detects 1080p, 720p, etc.
    tracks: tracks
  }],
  width: "100%",
  aspectratio: "16:9",
  autostart: true
});
</details>

2. Custom HTML5 Player Integration (Aniflix)

If you are building a highly customized UI (like Aniflix Player) from scratch using raw HTML/CSS, use hls.js.

<details> <summary><b>Show Custom Player Code</b></summary>
import Hls from "hls.js";

const videoElement = document.querySelector("#vid");
const res = await fetch(`http://localhost:3000/api/watch?id=6989bf2429cf95f4eb040650&ep=1&server=pahe&source_type=sub`);
const watchData = (await res.json()).data;
const streamUrl = watchData.sources[0].proxy_url;

if (Hls.isSupported()) {
  const hls = new Hls();
  hls.loadSource(streamUrl);
  hls.attachMedia(videoElement);

  // MANUALLY HOOKING UP QUALITY BUTTONS:
  hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
    // Force switch quality
    document.querySelector("#btn-1080p").onclick = () => {
      hls.currentLevel = data.levels.findIndex(l => l.height === 1080);
    };
  });
}

// INJECTING SUBTITLES
if (watchData.subtitles) {
  watchData.subtitles.forEach(sub => {
    const track = document.createElement("track");
    track.kind = "subtitles";
    track.label = sub.label;
    track.srclang = sub.lang.substring(0, 2).toLowerCase(); 
    track.src = sub.url; 
    if (sub.lang.toLowerCase().includes("english")) track.default = true;
    videoElement.appendChild(track);
  });
}
</details>

📚 API Reference

Here are the primary endpoints documented with exact schemas and cURL examples.

<details> <summary><b>1. Get Anime Info <code>/api/anime/[id]</code></b></summary>

Fetch detailed metadata about a specific anime.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | string | Yes | The Anime ID |

Example cURL:

curl -s "http://localhost:3000/api/anime/6989bf2429cf95f4eb040650"
</details> <details> <summary><b>1b. Get Anime Info via AniList ID <code>/api/anime/anilist/[id]</code></b></summary>

Fetch detailed anime metadata using a dynamic AniList ID.

This endpoint performs an automated background mapping:

  1. Queries the AniList GraphQL API to fetch anime titles (romaji, english, native, userPreferred), synonyms, release year, format, and episode count.
  2. Executes parallel search queries on the Animetsu API using Romaji and English titles.
  3. Applies a multi-factor scoring algorithm checking normalized title similarity, release year compatibility (exact year vs. ±1 year crossing season boundaries), format matches (TV, MOVIE, OVA, ONA, SPECIAL), and episode counts.
  4. Instantly resolves the target Animetsu ID and retrieves the detailed info, returning the payload as a drop-in replacement with additional mapping details.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | number | Yes | The AniList ID (e.g. 21 for One Piece, 16498 for Attack on Titan S4) |

Example cURL:

curl -s "http://localhost:3000/api/anime/anilist/21"

Additional Response Attributes: This endpoint automatically injects mapping metadata into the standard data object:

{
  "success": true,
  "data": {
    "id": "6989b8a429cf95f4eb03b52f",
    "title": {
      "romaji": "One Piece",
      "english": "One Piece",
      "native": "ONE PIECE"
    },
    "anilist_id": 21,
    "mapped_by": "anilist-to-animetsu-v1",
    "match_score": 125
  }
}
</details> <details> <summary><b>2. Home Feed <code>/api/home</code></b></summary>

Fetch the curated home feed containing spot-lighted animes, latest episodes, etc.

Example cURL:

curl -s "http://localhost:3000/api/home"
</details> <details> <summary><b>3. Popular Anime <code>/api/popular</code></b></summary>

Fetch the all-time popular animes.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | number | No | Page number (default: 1) |

Example cURL:

curl -s "http://localhost:3000/api/popular?page=1"
</details> <details> <summary><b>4. Recent Episodes <code>/api/recent</code></b></summary>

Fetch recently updated anime episodes.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | number | No | Page number (default: 1) |

Example cURL:

curl -s "http://localhost:3000/api/recent?page=1"
</details> <details> <summary><b>5. Trending Anime <code>/api/trending</code></b></summary>

Fetch currently trending animes.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | number | No | Page number (default: 1) |

Example cURL:

curl -s "http://localhost:3000/api/trending?page=1"
</details> <details> <summary><b>6. Top Rated Anime <code>/api/top-rated</code></b></summary>

Fetch top-rated animes.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | number | No | Page number (default: 1) |

Example cURL:

curl -s "http://localhost:3000/api/top-rated?page=1"
</details> <details> <summary><b>7. Upcoming Anime <code>/api/upcoming</code></b></summary>

Fetch animes scheduled for upcoming release.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | number | No | Page number (default: 1) |

Example cURL:

curl -s "http://localhost:3000/api/upcoming?page=1"
</details> <details> <summary><b>8. Airing Schedule <code>/api/schedule</code></b></summary>

Fetch the airing schedule for current animes.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | date | string | No | Date format YYYY-MM-DD |

Example cURL:

curl -s "http://localhost:3000/api/schedule"
</details> <details> <summary><b>9. Random Anime <code>/api/random</code></b></summary>

Fetch a random anime suggestion.

Example cURL:

curl -s "http://localhost:3000/api/random"
</details> <details> <summary><b>10. Seasonal Anime <code>/api/season</code></b></summary>

Fetch animes for a specific season and year.

Example cURL:

curl -s "http://localhost:3000/api/season"
</details> <details> <summary><b>11. Search Anime <code>/api/search</code></b></summary>

Search for animes by query.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | Yes | The search query |

Example cURL:

curl -s "http://localhost:3000/api/search?q=naruto"

Response Schema:

{
  "success": true,
  "data": {
    "animes": [
      {
        "id": "12345",
        "name": { "english": "Naruto", "romaji": "Naruto" },
        "poster": "https://...",
        "episodes": { "sub": 220, "dub": 220 }
      }
    ]
  }
}
</details> <details> <summary><b>12. Get Episodes <code>/api/anime/[id]/episodes</code></b></summary>

Fetch all episodes for a specific anime ID.

[!TIP] AniList Dynamic Option: You can also use AniList ID via GET /api/anime/anilist/[id]/episodes (e.g. /api/anime/anilist/21/episodes). It dynamically resolves the AniList ID and returns the exact same format.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | string | Yes | The Anime ID (or AniList ID if hitting /anilist/[id]/episodes) |

Example cURL:

curl -s "http://localhost:3000/api/anime/6989bf2429cf95f4eb040650/episodes"
# Or using AniList ID:
curl -s "http://localhost:3000/api/anime/anilist/21/episodes"

Response Schema:

{
  "success": true,
  "data": [
    {
      "ep_num": 1,
      "name": "I'm Luffy! The Man Who's Gonna Be King of the Pirates!",
      "is_filler": false
    }
  ]
}
</details> <details> <summary><b>13. Get Servers <code>/api/anime/[id]/servers/[ep]</code></b></summary>

Fetch available streaming servers for a specific episode.

[!TIP] AniList Dynamic Option: You can also use AniList ID via GET /api/anime/anilist/[id]/servers/[ep] (e.g. /api/anime/anilist/21/servers/1). It dynamically maps the AniList ID and checks latency / stream health in real-time.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | string | Yes | The Anime ID (or AniList ID if hitting /anilist/[id]/servers/[ep]) | | ep | number | Yes | The Episode Number |

Example cURL:

curl -s "http://localhost:3000/api/anime/6989bf2429cf95f4eb040650/servers/1"
# Or using AniList ID:
curl -s "http://localhost:3000/api/anime/anilist/21/servers/1"

Response Schema:

{
  "success": true,
  "data": [
    {
      "id": "pahe",
      "default": true,
      "tip": "Multi-quality (1080p, 720p)",
      "working": true,
      "sources": 3,
      "latency_ms": 120
    }
  ]
}
</details> <details> <summary><b>14. Watch / Stream <code>/api/watch</code></b></summary>

Fetch proxy streaming URLs, subtitles, and metadata.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | Conditional | The native Anime ID (Required if anilistid is not provided) | | anilistid | string | Conditional | The AniList ID (Required if id is not provided) | | ep | number | Yes | The Episode Number | | server | string | No | The Server ID (default: pahe) | | source_type | string | No | sub or dub (default: sub) |

Example cURL:

curl -s "http://localhost:3000/api/watch?id=6989bf2429cf95f4eb040650&ep=1&server=pahe&source_type=sub"
# Or using AniList ID:
curl -s "http://localhost:3000/api/watch?anilistid=21&ep=1&server=pahe&source_type=sub"

Response Schema:

{
  "success": true,
  "data": {
    "sources": [
      {
        "url": "https://upstream.m3u8",
        "proxy_url": "http://localhost:3000/api/proxy/hls?url=...",
        "isM3U8": true
      }
    ],
    "subtitles": [
      {
        "url": "http://localhost:3000/api/proxy/hls?url=...",
        "lang": "English",
        "label": "English"
      }
    ]
  }
}
</details> <details> <summary><b>15. Best-Quality Download <code>/api/anime/[id]/download/[ep]</code></b></summary>

Fetch the best-quality HLS stream url along with a suggested .mp4 filename and a ready-to-paste ffmpeg copy-mux command.

[!TIP] AniList Dynamic Option: You can also use AniList ID via GET /api/anime/anilist/[id]/download/[ep] (e.g. /api/anime/anilist/21/download/1). It dynamically maps the AniList ID.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | string | Yes | The native Anime ID (or numeric AniList ID) | | ep | number | Yes | The Episode Number |

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | quality | string | No | Quality preference (e.g. 1080p, 720p, 480p) |

Example cURL:

curl -s "http://localhost:3000/api/anime/6989bf2429cf95f4eb040650/download/1?quality=1080p"

Response Schema:

{
  "success": true,
  "data": {
    "id": "6989bf2429cf95f4eb040650",
    "episode": "1",
    "server": "pahe",
    "quality": "1080p",
    "type": "video/mpegurl",
    "url": "https://...",
    "proxy_url": "http://localhost:3000/api/proxy/hls?url=...",
    "filename": "6989bf2429cf95f4eb040650_ep1_1080p_sub.mp4",
    "subtitles": [],
    "hint": "HLS stream — mux to MP4 with: ffmpeg -i \"http://localhost:3000/api/proxy/hls?url=...\" -c copy 6989bf2429cf95f4eb040650_ep1_1080p_sub.mp4"
  }
}
</details> <details> <summary><b>16. Real Download Releases <code>/api/anime/[id]/downloads/[ep]</code></b></summary>

Get actual fansub download releases grouped by release group and quality.

[!TIP] AniList Dynamic Option: You can also use AniList ID via GET /api/anime/anilist/[id]/downloads/[ep] (e.g. /api/anime/anilist/21/downloads/1). It dynamically maps the AniList ID.

| Path Variable | Type | Required | Description | |---------------|------|----------|-------------| | id | string | Yes | The native Anime ID (or numeric AniList ID) | | ep | number | Yes | The Episode Number |

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | source | string | No | pahe (default: small per-episode direct DDL MP4s) or tosho (P2P magnets and direct download mirrors) | | quality | string | No | Filter by quality (e.g. 1080p, 720p) | | group | string | No | Filter by release group (e.g. SubsPlease) | | type | string | No | Filter by translation type (sub, dub, raw) | | limit | number | No | Limit the number of releases in the flat list |

Example cURL:

curl -s "http://localhost:3000/api/anime/6989bf2429cf95f4eb040650/downloads/1?source=pahe"

Response Schema:

{
  "success": true,
  "data": {
    "id": "6989bf2429cf95f4eb040650",
    "episode": "1",
    "title": "One Piece",
    "source": "animetosho",
    "query": "One Piece 01",
    "groups": [
      {
        "group": "SubsPlease",
        "type": "sub",
        "qualities": ["1080p", "720p", "480p"],
        "releases": [
          {
            "title": "[SubsPlease] One Piece - 01 (1080p).mkv",
            "group": "SubsPlease",
            "quality": "1080p",
            "container": "mkv",
            "type": "sub",
            "language": "English Sub",
            "size_bytes": 1395864371,
            "size_human": "1.3 GB",
            "seeders": 153,
            "leechers": 4,
            "p2p_url": "https://storage.animetosho.org/p2p/...",
            "magnet_uri": "magnet:?xt=urn:btih:...",
            "nzb_url": "https://storage.animetosho.org/nzbs/...",
            "view_page": "https://animetosho.org/view/...",
            "nyaa_url": "https://nyaa.si/view/1799935",
            "published_at": "2024-04-07T02:01:00Z",
            "info_hash": "d2321a12ac71730eef9bca99435c8abe3ab7453e"
          }
        ]
      }
    ],
    "flat": [ /* every release, sorted quality desc → seeders desc */ ]
  }
}
</details>

💖 Credits

A huge thank you to Aniflix.in for the original custom player design and inspiration!