{"id":50980036,"url":"https://github.com/shineii86/miruroapi","last_synced_at":"2026-06-19T13:02:11.178Z","repository":{"id":363527621,"uuid":"1263744121","full_name":"Shineii86/MiruroAPI","owner":"Shineii86","description":"Free RESTful API for anime streaming data - AniList GraphQL + Miruro providers + M3U8","archived":false,"fork":false,"pushed_at":"2026-06-09T10:14:28.000Z","size":46,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T10:15:46.907Z","etag":null,"topics":["anilist","anime","api","express","hls","m3u8","miruro","nodejs","rest-api","streaming"],"latest_commit_sha":null,"homepage":"https://mirurotvapi.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Shineii86.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-09T08:21:55.000Z","updated_at":"2026-06-09T09:54:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Shineii86/MiruroAPI","commit_stats":null,"previous_names":["shineii86/miruroapi"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Shineii86/MiruroAPI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FMiruroAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FMiruroAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FMiruroAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FMiruroAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shineii86","download_url":"https://codeload.github.com/Shineii86/MiruroAPI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FMiruroAPI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34532260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anilist","anime","api","express","hls","m3u8","miruro","nodejs","rest-api","streaming"],"created_at":"2026-06-19T13:02:07.950Z","updated_at":"2026-06-19T13:02:11.164Z","avatar_url":"https://github.com/Shineii86.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \n  \u003cimg src=\"https://capsule-render.vercel.app/api?type=waving\u0026height=300\u0026color=gradient\u0026text=𝙈𝙞𝙧𝙪𝙧𝙤𝘼𝙋𝙄\u0026fontAlignY=30\u0026fontSize=100\u0026desc=𝖠%20𝖢𝗈𝗆𝗉𝗅𝖾𝗍𝖾%20𝖱𝖤𝖲𝖳𝖿𝗎𝗅%20𝖠𝖯𝖨%20𝖥𝗈𝗋%20𝖠𝗇𝗂𝗆𝖾%20𝖲𝗍𝗋𝖾𝖺𝗆𝗂𝗇𝗀\u0026descSize=25\" /\u003e\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=github\u0026color=f43f8e\u0026logoColor=white\" alt=\"Stars\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/network/members\"\u003e\u003cimg src=\"https://img.shields.io/github/forks/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=github\u0026color=a855f7\u0026logoColor=white\" alt=\"Forks\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/issues\"\u003e\u003cimg src=\"https://img.shields.io/github/issues/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=github\u0026color=7c3aed\u0026logoColor=white\" alt=\"Issues\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/pulls\"\u003e\u003cimg src=\"https://img.shields.io/github/issues-pr/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=github\u0026color=ec4899\u0026logoColor=white\" alt=\"Pull Requests\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/commits\"\u003e\u003cimg src=\"https://img.shields.io/github/last-commit/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=github\u0026color=6366f1\u0026logoColor=white\" alt=\"Last Commit\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/Shineii86/MiruroAPI?style=for-the-badge\u0026logo=mit\u0026color=22c55e\u0026logoColor=white\" alt=\"License\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Node.js-20-339933?style=flat-square\u0026logo=node.js\u0026logoColor=white\" alt=\"Node.js\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Express-4.21-000000?style=flat-square\u0026logo=express\u0026logoColor=white\" alt=\"Express\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/AniList-GraphQL-02A6E4?style=flat-square\u0026logo=graphql\u0026logoColor=white\" alt=\"AniList GraphQL\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Vercel-Serverless-000000?style=flat-square\u0026logo=vercel\u0026logoColor=white\" alt=\"Vercel\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-MIT-22c55e?style=flat-square\u0026logo=mit\u0026logoColor=white\" alt=\"License\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Version-1.2.0-f43f8e?style=flat-square\u0026logoColor=white\" alt=\"Version\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Endpoints-18-6366f1?style=flat-square\u0026logoColor=white\" alt=\"Endpoints\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Providers-12-a855f7?style=flat-square\u0026logoColor=white\" alt=\"Providers\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eA complete RESTful API for anime streaming data powered by AniList GraphQL and Miruro providers\u003c/b\u003e\u003cbr/\u003e\n  Search, browse, filter, watch — every endpoint returns fresh data with smart caching.\u003cbr/\u003e\n  18 endpoints, 12 streaming providers, M3U8 URLs with subtitles and skip timestamps.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#-table-of-contents\"\u003eTable of Contents\u003c/a\u003e \u0026bull;\n  \u003ca href=\"#-features\"\u003eFeatures\u003c/a\u003e \u0026bull;\n  \u003ca href=\"#-api-endpoints\"\u003eAPI Docs\u003c/a\u003e \u0026bull;\n  \u003ca href=\"#-quick-start\"\u003eQuick Start\u003c/a\u003e \u0026bull;\n  \u003ca href=\"#-deployment\"\u003eDeployment\u003c/a\u003e \u0026bull;\n  \u003ca href=\"#-contributing\"\u003eContributing\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e [!WARNING]\n\u003e 1. This `API` does not store any files — it only links to media hosted on 3rd party services.\n\u003e 2. This `API` is explicitly made for **educational purposes only** and not for commercial usage. This repo will not be responsible for any misuse of it.\n\u003e 3. All anime data, images, and content belong to their respective owners (AniList, Miruro). This project is not affiliated with miruro.tv.\n\n---\n\n## 📖 Table of Contents\n\n- [Overview](#-overview)\n- [Features](#-features)\n- [Data Sources](#-data-sources)\n- [Tech Stack](#-tech-stack)\n- [Architecture](#-architecture)\n- [Project Structure](#-project-structure)\n- [Quick Start](#-quick-start)\n- [Configuration](#-configuration)\n- [API Endpoints](#-api-endpoints)\n- [Streaming Flow](#-streaming-flow)\n- [API Response Schema](#-api-response-schema)\n- [Deployment](#-deployment)\n- [Available Scripts](#-available-scripts)\n- [Performance](#-performance)\n- [Changelog Highlights](#-changelog-highlights)\n- [Troubleshooting](#-troubleshooting)\n- [FAQ](#-faq)\n- [Roadmap](#-roadmap)\n- [Contributing](#-contributing)\n- [Acknowledgements](#-acknowledgements)\n- [License](#-license)\n- [Author](#-author)\n- [Star History](#-star-history)\n\n---\n\n## 🌸 Overview\n\n**MiruroAPI** is a serverless anime data API that fetches real-time information from **AniList GraphQL** and streaming data from **Miruro providers** — including anime details, episode lists, M3U8 streaming URLs with subtitles and skip timestamps, search, filtering, characters, and more — all through a clean REST API with zero database.\n\n\u003e 💡 No database, no auth, no complex setup. Just deploy to Vercel and you have a production API.\n\n### Why MiruroAPI?\n\n- 🎬 **18 Endpoints** — Complete anime data coverage\n- 🔍 **Full-Text Search** — Search anime by keyword with suggestions\n- 🎭 **Characters \u0026 Voice Actors** — Full character data from AniList\n- 🎯 **Advanced Filtering** — Genre, year, season, format, sort\n- 🏆 **Trending \u0026 Popular** — Discover what's hot right now\n- 📅 **Airing Schedule** — See what's airing on any date\n- 📡 **12 Streaming Providers** — M3U8 streaming sources\n- ⏭️ **Skip Timestamps** — OP/ED skip data\n- ⚡ **Smart Caching** — In-memory Map with configurable TTL\n- 🔒 **CORS Enabled** — Works from any frontend, no proxy needed\n- 🚀 **Zero-Config Deploy** — One click to Vercel, or run standalone with Express\n\n### How It Works\n\n```mermaid\nflowchart TD\n    A[\"🌐 Client Request\u003cbr/\u003e(Browser / App / curl)\"] --\u003e B[\"🛡️ Express Server\u003cbr/\u003eCORS · Security Headers · Rate Limiting\"]\n    B --\u003e C{\"💾 Cache Check\u003cbr/\u003e(In-Memory Map)\"}\n    C -- HIT --\u003e D[\"⚡ Return Cached Response\u003cbr/\u003e~50ms\"]\n    C -- MISS --\u003e E{\"🔍 Which Source?\"}\n\n    E -- Metadata --\u003e F[\"📡 AniList GraphQL\u003cbr/\u003egraphql.anilist.co\"]\n    E -- Streaming --\u003e G[\"📺 Miruro Pipe\u003cbr/\u003emiruro.tv/api/secure/pipe\"]\n\n    F --\u003e H[\"AniList Response\u003cbr/\u003eJSON\"]\n    G --\u003e I[\"Pipe Response\u003cbr/\u003ebase64url + gzip\"]\n\n    H --\u003e J[\"Cache + Respond\u003cbr/\u003eJSON\"]\n    I --\u003e J\n\n    style A fill:#1e1e2e,stroke:#a78bfa,color:#f1f5f9\n    style B fill:#1e1e2e,stroke:#6366f1,color:#f1f5f9\n    style C fill:#1e1e2e,stroke:#f43f8e,color:#f1f5f9\n    style D fill:#1e1e2e,stroke:#22c55e,color:#f1f5f9\n    style E fill:#1e1e2e,stroke:#a855f7,color:#f1f5f9\n    style F fill:#1e1e2e,stroke:#06b6d4,color:#f1f5f9\n    style G fill:#1e1e2e,stroke:#eab308,color:#f1f5f9\n    style H fill:#1e1e2e,stroke:#06b6d4,color:#f1f5f9\n    style I fill:#1e1e2e,stroke:#eab308,color:#f1f5f9\n    style J fill:#1e1e2e,stroke:#22c55e,color:#f1f5f9\n```\n\n---\n\n## ✨ Features\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n\n### ⚡ Core\n- **AniList GraphQL** for rich metadata\n- **Miruro pipe** for streaming sources\n- **Smart caching** with configurable TTL\n- **18 RESTful endpoints**\n- **Graceful error handling** per endpoint\n- **Rate limiting** (100 req/min per IP)\n\n    \u003c/td\u003e\n    \u003ctd\u003e\n\n### 🔍 Data\n- **Full-text search** with pagination\n- **Autocomplete suggestions** for search\n- **Advanced filtering** — genre, year, season, format, sort\n- **Characters** with voice actors\n- **Relations** and **Recommendations**\n- **Airing schedule** by date\n\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n\n### 📡 Streaming\n- **Episode lists** from 12 providers\n- **M3U8 streaming URLs** with resolution info\n- **Skip timestamps** (OP/ED)\n- **Download links** when available\n- **Sub/Dub** support per provider\n- **Codec and fansub** metadata\n\n    \u003c/td\u003e\n    \u003ctd\u003e\n\n### 🛡️ Reliability\n- **CORS enabled** — works from any frontend\n- **Error responses** with descriptive messages\n- **Input validation** — required params checked\n- **Timeout protection** — per request\n- **In-memory caching** — survives warm starts\n- **Zero database** — pure API + cache\n\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### 🌟 Feature Highlights\n\n| Feature | Description | Status |\n|:---|:---|:---:|\n| 🎬 18 API Endpoints | Complete anime data coverage | ✅ |\n| 🔍 Full-Text Search | Keyword search with pagination | ✅ |\n| 💡 Search Suggestions | Fast autocomplete | ✅ |\n| 🎯 Advanced Filtering | Genre, year, season, format, sort | ✅ |\n| 🎭 Characters + Voice Actors | Full character data from AniList | ✅ |\n| 🔗 Relations \u0026 Recommendations | Related anime discovery | ✅ |\n| ⏭️ Skip Timestamps | OP/ED skip data | ✅ |\n| 📡 12 Streaming Providers | M3U8 streaming sources | ✅ |\n| 🔄 Smart Caching | In-memory Map with TTL | ✅ |\n| 🚀 One-Click Deploy | Vercel button deployment | ✅ |\n| 🏗️ Express Mode | Standalone server with `npm start` | ✅ |\n| 🐳 Docker Support | Containerized deployment | ✅ |\n\n---\n\n## 🗞️ Data Sources\n\n### Metadata Source\n\n| Source | API | Data |\n|:---|:---|:---|\n| 🌸 **AniList** | `graphql.anilist.co` | Search, info, characters, relations, recommendations, filter, schedule |\n\n### Streaming Source\n\n| Source | Domain | Data |\n|:---|:---|:---|\n| 📺 **Miruro** | `miruro.tv` | Episodes, streaming sources (M3U8 URLs) |\n| 📺 **Miruro** | `miruro.to` | Mirror domain |\n| 📺 **Miruro** | `miruro.bz` | Mirror domain |\n| 📺 **Miruro** | `miruro.ru` | Mirror domain |\n\n### 🎬 Streaming Providers\n\n| Provider | Provider | Provider | Provider |\n|:---|:---|:---|:---|\n| 🥝 kiwi | 🐝 pewe | 🐻 bee | 🍯 bonk |\n| 🍌 bun | 🤝 ally | 🦄 nun | 👯 twin |\n| ⚙️ cog | 🐄 moo | 🐰 hop | 📺 telli |\n\n---\n\n## 🛠️ Tech Stack\n\n| Technology | Purpose | Version | Documentation |\n|:---|:---|:---|:---|\n| 🟢 [Node.js](https://nodejs.org/) | JavaScript runtime | \u003e= 20 | [Docs](https://nodejs.org/docs/) |\n| ⚡ [Express](https://expressjs.com/) | HTTP server framework | 4.21 | [Docs](https://expressjs.com/en/4x/api.html) |\n| ▲ [Vercel Functions](https://vercel.com/docs/functions) | Serverless deployment | — | [Docs](https://vercel.com/docs/functions) |\n| 🌸 [AniList GraphQL](https://anilist.gitbook.io/anilist-apiv2-docs/) | Anime metadata API | — | [Docs](https://anilist.gitbook.io/anilist-apiv2-docs/) |\n| 🌐 [Axios](https://axios-http.com/) | HTTP client | 1.8 | [Docs](https://axios-http.com/docs/intro) |\n| 🔧 [dotenv](https://github.com/motdotla/dotenv) | Environment variables | 16.4 | [Docs](https://github.com/motdotla/dotenv) |\n| 🔒 [cors](https://github.com/expressjs/cors) | CORS middleware | 2.8 | [Docs](https://github.com/expressjs/cors) |\n\n### 📦 Key Dependencies\n\n```json\n{\n  \"express\": \"^4.21.0\",        // HTTP server\n  \"axios\": \"^1.8.0\",         // HTTP client\n  \"cors\": \"^2.8.5\",           // CORS middleware\n  \"dotenv\": \"^16.4.0\"         // Environment variables\n}\n```\n\n---\n\n## 🏗️ Architecture\n\n### Request Flow\n\n| Stage | Component | Description |\n|:-----:|-----------|-------------|\n| 1 | **Client** | Browser, app, or `curl` sends request |\n| 2 | **Express Server** | Routes request, applies CORS + security headers + rate limiting |\n| 3 | **Cache Check** | In-memory Map with TTL — hit = instant response |\n| 4 | **Fetch Data** | AniList GraphQL or Miruro pipe endpoint |\n| 5 | **Decode** | Pipe responses decoded: base64url → gunzip → JSON |\n| 6 | **Cache + Respond** | Store in cache, return JSON response |\n\n### Caching Architecture\n\n```mermaid\nflowchart TD\n    A[\"📥 Request\"] --\u003e B{\"🧠 Memory Cache\u003cbr/\u003e(Map + TTL)\"}\n    B -- HIT --\u003e C[\"⚡ Return Cached\u003cbr/\u003e~50ms\"]\n    B -- MISS --\u003e D[\"📡 Fetch from\u003cbr/\u003eAniList / Miruro\"]\n    D --\u003e E[\"🔍 Decode\u003cbr/\u003ebase64url + gzip\"]\n    E --\u003e F[\"💾 Cache Result\u003cbr/\u003e(1-5 min TTL)\"]\n    F --\u003e G[\"📤 Return Fresh\"]\n\n    style A fill:#1e1e2e,stroke:#a78bfa,color:#f1f5f9\n    style B fill:#1e1e2e,stroke:#f43f8e,color:#f1f5f9\n    style C fill:#1e1e2e,stroke:#22c55e,color:#f1f5f9\n    style D fill:#1e1e2e,stroke:#6366f1,color:#f1f5f9\n    style E fill:#1e1e2e,stroke:#06b6d4,color:#f1f5f9\n    style F fill:#1e1e2e,stroke:#a855f7,color:#f1f5f9\n    style G fill:#1e1e2e,stroke:#22c55e,color:#f1f5f9\n```\n\n\u003e 💡 Serverless functions have read-only filesystems except `/tmp`. The cache uses in-memory `Map` which survives across warm invocations.\n\n---\n\n## 📁 Project Structure\n\n```\nMiruroAPI/\n├── 📂 public/                              # 🌐 Static files\n│   ├── 📄 index.html                       #    📖 Premium landing page (real Miruro icons)\n│   ├── 📄 docs.html                        #    📘 Swagger UI interactive documentation\n│   ├── 📄 openapi.json                     #    📋 OpenAPI 3.0 spec\n│   ├── 📄 icon-dark.svg                    #    🌙 Miruro dark mode favicon\n│   ├── 📄 icon-light.svg                   #    ☀️ Miruro light mode favicon\n│   ├── 📄 icon-512x512.png                 #    📱 Miruro app icon\n│   ├── 📄 favicon.ico                      #    🔖 Classic favicon\n│   ├── 📄 apple-touch-icon-180x180.png     #    🍎 iOS home screen icon\n│   └── 📄 og-image.png                     #    🖼️ OG/Twitter share image\n│\n├── 📂 assets/                              # 🎨 Scraped Miruro assets\n│   ├── 📂 favicons/                        #    🔖 All favicon variants\n│   ├── 📂 logos/                           #    🏷️ Status page logo\n│   ├── 📂 fonts/                           #    🔤 Inter + FontAwesome\n│   └── 📂 media/                           #    🖼️ Testimonial avatars\n│\n├── 📂 src/                                 # ⚙️ Core logic\n│   ├── 📂 helpers/                         #    🛠️ Integration modules\n│   │   ├── 📄 anilist.js                   #       🌸 AniList GraphQL integration\n│   │   ├── 📄 pipe.js                      #       📺 Miruro pipe integration\n│   │   └── 📄 cache.js                     #       💾 In-memory cache with TTL\n│   │\n│   └── 📂 routes/                          #    🛤️ Express routes\n│       └── 📄 apiRoutes.js                 #       🌐 Main API routes (18 endpoints)\n│\n├── 📄 server.js                            # 🚀 Express server entry point\n├── 📄 package.json                         # 📦 Dependencies \u0026 scripts\n├── 📄 vercel.json                          # ▲ Vercel routing config\n├── 📄 Dockerfile                           # 🐳 Docker support\n├── 📄 .dockerignore                        # 🐳 Docker ignore\n├── 📄 CHANGELOG.md                         # 📝 Version history\n└── 📄 README.md                            # 📖 This file\n```\n\n---\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n| Requirement | Minimum | Recommended |\n|:---|:---|:---|\n| 📦 Node.js | 20.x | 20.x LTS |\n| 📦 npm | 9.0+ | 10.x |\n| 💻 OS | Windows, macOS, Linux | Any |\n\n### 🔧 Installation\n\n```bash\n# 1️⃣ Clone the repository\ngit clone https://github.com/Shineii86/MiruroAPI.git\ncd MiruroAPI\n\n# 2️⃣ Install dependencies\nnpm install\n\n# 3️⃣ Start development server\nnpm run dev\n```\n\n\u003e 🌐 Open [http://localhost:3000](http://localhost:3000) in your browser.\n\n### 🏗️ Build for Production\n\n```bash\n# Start production server\nnpm start\n```\n\n### 🐳 Alternative Package Managers\n\n```bash\n# Using yarn\nyarn install\nyarn dev\n\n# Using pnpm\npnpm install\npnpm dev\n\n# Using bun\nbun install\nbun dev\n```\n\n---\n\n## ⚙️ Configuration\n\n### Environment Variables\n\n| Variable | Default | Description |\n|:---|:---|:---|\n| `PORT` | `3000` | Server port (Express mode only) |\n| `ALLOWED_ORIGINS` | `*` | Comma-separated allowed origins |\n\n### Vercel Configuration\n\nThe `vercel.json` file handles:\n- **Builds** — Maps `server.js` to `@vercel/node`\n- **Routes** — All requests forwarded to Express\n\n---\n\n## 📡 API Endpoints\n\n### Base URL\n```\nhttps://mirurotvapi.vercel.app/api\n```\n\n### Response Format\n\nAll endpoints return:\n```json\n{\n  \"success\": true,\n  \"results\": { ... }\n}\n```\n\n### Streaming Flow\n\nTo get a stream URL, follow these 3 steps:\n\n```bash\n# Step 1: Get episodes (returns provider slugs)\ncurl \"https://mirurotvapi.vercel.app/api/episodes/20\"\n\n# Step 2: Get streaming sources (pass provider + anilistId + category + slug)\ncurl \"https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1\"\n\n# Step 3: Play M3U8 in any HLS player\n# Use hls.js, video.js, or native \u003cvideo\u003e with hls support\n```\n\n### Sub \u0026 Dub Switch\n\nProviders return both `sub` and `dub` episode lists:\n\n```javascript\nconst eps = await fetch(\"/api/episodes/20\").then(r =\u003e r.json());\nconst kiwi = eps.results.providers.kiwi.episodes;\n\n// Pick sub or dub\nconst subEps = kiwi.sub;  // [{ id: \"watch/kiwi/20/sub/anikoto-1\", ... }]\nconst dubEps = kiwi.dub;  // [{ id: \"watch/kiwi/20/dub/...\", ... }]\n\n// Get stream URL\nconst stream = await fetch(`/api/watch/kiwi/20/sub/animepahe-1`).then(r =\u003e r.json());\n// stream.results.streams[0].url = \"https://...m3u8\"\n```\n\n---\n\n\u003e ## 🏥 GET Health Check\n\n### Endpoint\n\n```bash\n/health\n```\n\n#### Parameters\n\n\u003e No parameters required.\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/health\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/health\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"status\": \"healthy\",\n    \"version\": \"1.2.0\",\n    \"uptime\": \"0h 0m 34s\",\n    \"uptimeSeconds\": 34,\n    \"timestamp\": \"2026-06-09T09:55:00.884Z\",\n    \"node\": \"v24.14.1\",\n    \"memory\": { \"used\": \"13MB\", \"total\": \"15MB\" },\n    \"endpoints\": 16,\n    \"providers\": [\"kiwi\",\"pewe\",\"bee\",\"bonk\",\"bun\",\"ally\",\"nun\",\"twin\",\"cog\",\"moo\",\"hop\",\"telli\"]\n  }\n}\n```\n\n---\n\n\u003e ## 📊 GET Stats\n\n### Endpoint\n\n```bash\n/stats\n```\n\n#### Parameters\n\n\u003e No parameters required.\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/stats\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/stats\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"uptime\": \"0h 0m 34s\",\n    \"requests\": { \"total\": 156, \"errors\": 3, \"successRate\": \"98.1%\" },\n    \"cache\": { \"size\": 12, \"maxSize\": 100, \"ttl\": \"1 min\" },\n    \"endpoints\": 16,\n    \"timestamp\": \"2026-06-09T09:55:00.884Z\"\n  }\n}\n```\n\n---\n\n\u003e ## 🔍 GET Search\n\n### Endpoint\n\n```bash\n/search\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `query` | `string` | Yes ✔️ | — | Search keyword |\n| `page` | `number` | No | `1` | Page number |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/search?query=naruto\u0026per_page=2\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/search\", {\n  params: { query: \"naruto\", per_page: 2 }\n});\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"page\": 1,\n    \"perPage\": 2,\n    \"total\": 5000,\n    \"hasNextPage\": true,\n    \"results\": [\n      {\n        \"id\": 20,\n        \"title\": { \"romaji\": \"NARUTO\", \"english\": \"Naruto\", \"native\": \"NARUTO -ナルト-\" },\n        \"coverImage\": { \"large\": \"https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx20-dE6UHbFFg1A5.jpg\" },\n        \"format\": \"TV\",\n        \"season\": \"FALL\",\n        \"seasonYear\": 2002,\n        \"episodes\": 220,\n        \"status\": \"FINISHED\",\n        \"averageScore\": 80,\n        \"genres\": [\"Action\",\"Adventure\",\"Comedy\",\"Drama\",\"Fantasy\",\"Supernatural\"]\n      }\n    ]\n  }\n}\n```\n\n---\n\n\u003e ## 💡 GET Search Suggestions\n\n### Endpoint\n\n```bash\n/suggestions\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `query` | `string` | Yes ✔️ | — | Search keyword |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/suggestions?query=naruto\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/suggestions\", {\n  params: { query: \"naruto\" }\n});\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": [\n    { \"id\": 20, \"title\": \"Naruto\", \"title_romaji\": \"NARUTO\", \"poster\": \"https://s4.anilist.co/file/...\", \"format\": \"TV\", \"status\": \"FINISHED\", \"year\": 2002, \"episodes\": 220 },\n    { \"id\": 1735, \"title\": \"Naruto: Shippuden\", \"title_romaji\": \"NARUTO: Shippuuden\", \"poster\": \"https://s4.anilist.co/file/...\", \"format\": \"TV\", \"status\": \"FINISHED\", \"year\": 2007, \"episodes\": 500 }\n  ]\n}\n```\n\n---\n\n\u003e ## 🎯 GET Filter\n\n### Endpoint\n\n```bash\n/filter\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `genre` | `string` | No | — | Genre name (e.g. \"Action\") |\n| `tag` | `string` | No | — | Tag name |\n| `year` | `number` | No | — | Release year |\n| `season` | `string` | No | — | FALL, WINTER, SPRING, SUMMER |\n| `format` | `string` | No | — | TV, MOVIE, OVA, ONA, SPECIAL, MUSIC |\n| `status` | `string` | No | — | RELEASING, FINISHED, NOT_YET_RELEASED, CANCELLED |\n| `sort` | `string` | No | POPULARITY_DESC | Sort order |\n| `page` | `number` | No | `1` | Page number |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/filter?genre=Action\u0026year=2024\u0026season=WINTER\u0026per_page=3\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/filter\", {\n  params: { genre: \"Action\", year: 2024, season: \"WINTER\", per_page: 3 }\n});\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"page\": 1,\n    \"perPage\": 3,\n    \"total\": 5000,\n    \"hasNextPage\": true,\n    \"results\": [\n      {\n        \"id\": 21,\n        \"title\": { \"romaji\": \"ONE PIECE\", \"english\": \"One Piece\" },\n        \"coverImage\": { \"large\": \"https://...\" },\n        \"format\": \"TV\",\n        \"status\": \"RELEASING\",\n        \"averageScore\": 85\n      }\n    ]\n  }\n}\n```\n\n---\n\n\u003e ## 📈 GET Trending\n\n### Endpoint\n\n```bash\n/trending\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/trending?per_page=3\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/trending\", {\n  params: { per_page: 3 }\n});\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"page\": 1,\n    \"perPage\": 3,\n    \"total\": 5000,\n    \"hasNextPage\": true,\n    \"results\": [\n      {\n        \"id\": 21,\n        \"title\": { \"romaji\": \"ONE PIECE\", \"english\": \"One Piece\" },\n        \"coverImage\": { \"large\": \"https://...\" },\n        \"format\": \"TV\",\n        \"status\": \"RELEASING\",\n        \"averageScore\": 85\n      }\n    ]\n  }\n}\n```\n\n---\n\n\u003e ## 🏆 GET Popular\n\n### Endpoint\n\n```bash\n/popular\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/popular?per_page=3\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/popular\", {\n  params: { per_page: 3 }\n});\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## 📅 GET Upcoming\n\n### Endpoint\n\n```bash\n/upcoming\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/upcoming?per_page=3\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/upcoming\", {\n  params: { per_page: 3 }\n});\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## 🆕 GET Recent\n\n### Endpoint\n\n```bash\n/recent\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `per_page` | `number` | No | `20` | Results per page |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/recent?per_page=3\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/recent\", {\n  params: { per_page: 3 }\n});\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## ⭐ GET Spotlight\n\n### Endpoint\n\n```bash\n/spotlight\n```\n\n#### Parameters\n\n\u003e No parameters required.\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/spotlight\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/spotlight\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": [\n    {\n      \"id\": 21,\n      \"title\": { \"romaji\": \"ONE PIECE\", \"english\": \"One Piece\" },\n      \"coverImage\": { \"large\": \"https://...\" },\n      \"bannerImage\": \"https://...\",\n      \"format\": \"TV\",\n      \"episodes\": null,\n      \"status\": \"RELEASING\",\n      \"averageScore\": 85,\n      \"genres\": [\"Action\",\"Adventure\",\"Comedy\",\"Fantasy\"],\n      \"description\": \"Gol D. Roger was known as the Pirate King...\"\n    }\n  ]\n}\n```\n\n---\n\n\u003e ## 📅 GET Schedule\n\n### Endpoint\n\n```bash\n/schedule\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `date` | `string` | No | today | Date in `YYYY-MM-DD` format |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/schedule?date=2026-06-09\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/schedule\", {\n  params: { date: \"2026-06-09\" }\n});\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## ℹ️ GET Anime Info\n\n### Endpoint\n\n```bash\n/info/:id\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `id` | `number` | Yes ✔️ | — | AniList anime ID |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/info/20\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/info/20\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"id\": 20,\n    \"idMal\": 20,\n    \"title\": { \"romaji\": \"NARUTO\", \"english\": \"Naruto\", \"native\": \"NARUTO -ナルト-\" },\n    \"description\": \"Naruto Uzumaki, a hyperactive and knuckle-headed ninja...\",\n    \"coverImage\": { \"large\": \"https://s4.anilist.co/file/...\" },\n    \"bannerImage\": \"https://s4.anilist.co/file/...\",\n    \"format\": \"TV\",\n    \"season\": \"FALL\",\n    \"seasonYear\": 2002,\n    \"episodes\": 220,\n    \"duration\": 23,\n    \"status\": \"FINISHED\",\n    \"averageScore\": 80,\n    \"popularity\": 694959,\n    \"genres\": [\"Action\",\"Adventure\",\"Comedy\",\"Drama\",\"Fantasy\",\"Supernatural\"],\n    \"studios\": [{ \"name\": \"Studio Pierrot\", \"isAnimationStudio\": true }],\n    \"startDate\": { \"year\": 2002, \"month\": 10, \"day\": 3 },\n    \"endDate\": { \"year\": 2007, \"month\": 2, \"day\": 8 }\n  }\n}\n```\n\n---\n\n\u003e ## 🎭 GET Characters\n\n### Endpoint\n\n```bash\n/anime/:id/characters\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `id` | `number` | Yes ✔️ | — | AniList anime ID |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/anime/20/characters\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/anime/20/characters\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"edges\": [\n      {\n        \"role\": \"MAIN\",\n        \"node\": {\n          \"id\": 17,\n          \"name\": { \"full\": \"Naruto Uzumaki\", \"native\": \"うずまきナルト\" },\n          \"image\": { \"large\": \"https://s4.anilist.co/file/...\" }\n        },\n        \"voiceActors\": [\n          {\n            \"id\": 95015,\n            \"name\": { \"full\": \"Junko Takeuchi\", \"native\": \"竹内順子\" },\n            \"languageV2\": \"Japanese\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n---\n\n\u003e ## 🔗 GET Relations\n\n### Endpoint\n\n```bash\n/anime/:id/relations\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `id` | `number` | Yes ✔️ | — | AniList anime ID |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/anime/20/relations\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/anime/20/relations\");\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## 💡 GET Recommendations\n\n### Endpoint\n\n```bash\n/anime/:id/recommendations\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `id` | `number` | Yes ✔️ | — | AniList anime ID |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/anime/20/recommendations\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/anime/20/recommendations\");\nconsole.log(resp.data);\n```\n\n---\n\n\u003e ## 📺 GET Episodes\n\n### Endpoint\n\n```bash\n/episodes/:id\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `id` | `number` | Yes ✔️ | — | AniList anime ID |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/episodes/20\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/episodes/20\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"providers\": {\n      \"kiwi\": {\n        \"meta\": { \"id\": \"1571\", \"title\": \"Naruto\", \"type\": \"TV\" },\n        \"episodes\": {\n          \"sub\": [\n            {\n              \"id\": \"watch/kiwi/20/sub/anikoto-1\",\n              \"number\": 1,\n              \"title\": \"Enter: Naruto Uzumaki!\",\n              \"image\": \"https://image.tmdb.org/t/p/original/...\",\n              \"airDate\": \"2002-10-03\",\n              \"audio\": \"sub\",\n              \"filler\": false,\n              \"fillerType\": \"manga_canon\"\n            }\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\n---\n\n\u003e ## 📡 GET Watch (Streaming Sources)\n\n### Endpoint\n\n```bash\n/watch/:provider/:anilistId/:category/:slug\n```\n\n#### Parameters\n\n| Parameter | Type | Mandatory | Default | Description |\n| :-------: | :--: | :-------: | :-----: | :---------: |\n| `provider` | `string` | Yes ✔️ | — | Provider name (kiwi, pewe, etc.) |\n| `anilistId` | `number` | Yes ✔️ | — | AniList anime ID |\n| `category` | `string` | Yes ✔️ | — | sub or dub |\n| `slug` | `string` | Yes ✔️ | — | Episode slug from episodes response |\n\n#### Example of request\n\n```bash\ncurl \"https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1\"\n```\n\n```javascript\nimport axios from \"axios\";\nconst resp = await axios.get(\"https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1\");\nconsole.log(resp.data);\n```\n\n#### Sample Response\n\n```json\n{\n  \"success\": true,\n  \"results\": {\n    \"streams\": [\n      {\n        \"url\": \"https://vault-01.uwucdn.top/stream/.../uwu.m3u8\",\n        \"type\": \"hls\",\n        \"quality\": \"360p\",\n        \"resolution\": { \"width\": 640, \"height\": 360 },\n        \"codec\": \"h264\",\n        \"audio\": \"sub\",\n        \"fansub\": \"df68\",\n        \"isActive\": false,\n        \"referer\": \"https://kwik.cx/e/...\"\n      },\n      {\n        \"url\": \"https://kwik.cx/e/...\",\n        \"type\": \"embed\",\n        \"quality\": \"360p\",\n        \"codec\": \"h264\",\n        \"audio\": \"sub\",\n        \"fansub\": \"df68\",\n        \"isActive\": false\n      }\n    ],\n    \"download\": \"https://pahe.win/LJmbA\"\n  }\n}\n```\n\n---\n\n## 🎬 Streaming Flow\n\nTo get a stream URL, follow these 3 steps:\n\n```bash\n# Step 1: Get episodes (returns provider slugs)\ncurl \"https://mirurotvapi.vercel.app/api/episodes/20\"\n# =\u003e providers.kiwi.episodes.sub[0].id = \"watch/kiwi/20/sub/anikoto-1\"\n\n# Step 2: Get streaming sources\ncurl \"https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1\"\n# =\u003e streams[0].url = \"https://...m3u8\"\n\n# Step 3: Play M3U8 in any HLS player\n# Use hls.js, video.js, or native \u003cvideo\u003e with hls support\n```\n\n### 📺 Sub \u0026 Dub\n\nProviders return both `sub` and `dub` episode lists:\n\n```javascript\nconst eps = await fetch(\"/api/episodes/20\").then(r =\u003e r.json());\nconst providers = eps.results.providers;\n\n// Pick provider\nconst kiwi = providers.kiwi.episodes;\n\n// Get sub episodes\nconst subEps = kiwi.sub; // [{ id: \"watch/kiwi/20/sub/anikoto-1\", ... }]\n\n// Get dub episodes (if available)\nconst dubEps = kiwi.dub || []; // [{ id: \"watch/kiwi/20/dub/...\", ... }]\n```\n\n### 🎥 HLS Player Example\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/hls.js@latest\"\u003e\u003c/script\u003e\n\u003cvideo id=\"player\" controls\u003e\u003c/video\u003e\n\u003cscript\u003e\n  const video = document.getElementById('player');\n  const streamUrl = 'https://...m3u8'; // From /api/watch response\n  \n  if (Hls.isSupported()) {\n    const hls = new Hls();\n    hls.loadSource(streamUrl);\n    hls.attachMedia(video);\n  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {\n    video.src = streamUrl; // Native HLS (Safari)\n  }\n\u003c/script\u003e\n```\n\n---\n\n## 📋 API Response Schema\n\n### Success Response\n```json\n{\n  \"success\": true,\n  \"results\": { ... }\n}\n```\n\n### Error Response\n```json\n{\n  \"success\": false,\n  \"message\": \"Error description\"\n}\n```\n\n### Anime Item Object\n\n| Field | Type | Description | Example |\n|:---|:---|:---|:---|\n| `id` | `number` | AniList ID | `20` |\n| `title` | `object` | `{ romaji, english, native }` | `{ \"romaji\": \"NARUTO\" }` |\n| `coverImage` | `object` | `{ large }` | `{ \"large\": \"https://...\" }` |\n| `format` | `string` | Anime format | `\"TV\"` |\n| `status` | `string` | Release status | `\"FINISHED\"` |\n| `episodes` | `number` | Total episodes | `220` |\n| `averageScore` | `number` | AniList score | `80` |\n| `genres` | `string[]` | Genre list | `[\"Action\",\"Adventure\"]` |\n\n### Episode Object\n\n| Field | Type | Description | Example |\n|:---|:---|:---|:---|\n| `id` | `string` | Watch slug | `\"watch/kiwi/20/sub/anikoto-1\"` |\n| `number` | `number` | Episode number | `1` |\n| `title` | `string` | Episode title | `\"Enter: Naruto Uzumaki!\"` |\n| `image` | `string` | Thumbnail URL | `\"https://...\"` |\n| `airDate` | `string` | Air date | `\"2002-10-03\"` |\n| `audio` | `string` | `sub` or `dub` | `\"sub\"` |\n| `filler` | `boolean` | Is filler episode | `false` |\n\n### Stream Object\n\n| Field | Type | Description | Example |\n|:---|:---|:---|:---|\n| `url` | `string` | M3U8 or embed URL | `\"https://...m3u8\"` |\n| `type` | `string` | `hls` or `embed` | `\"hls\"` |\n| `quality` | `string` | Video quality | `\"720p\"` |\n| `resolution` | `object` | `{ width, height }` | `{ \"width\": 1280, \"height\": 720 }` |\n| `codec` | `string` | Video codec | `\"h264\"` |\n| `audio` | `string` | `sub` or `dub` | `\"sub\"` |\n| `fansub` | `string` | Fansub group | `\"df68\"` |\n| `isActive` | `boolean` | Is active stream | `false` |\n| `referer` | `string` | Referer URL | `\"https://kwik.cx/e/...\"` |\n\n---\n\n## 🌐 Deployment\n\n### ▲ Vercel (Recommended)\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Shineii86/MiruroAPI)\n\n1. Click the button above (or import manually on vercel.com)\n2. Vercel auto-detects the project — **no config needed**\n3. Your API is live! 🎉\n\n```bash\n# Or use Vercel CLI\nnpx vercel --prod\n```\n\n### 🖥️ Standalone Server\n\n```bash\n# Clone and install\ngit clone https://github.com/Shineii86/MiruroAPI.git\ncd MiruroAPI \u0026\u0026 npm install\n\n# Start production server\nnpm start\n# → http://localhost:3000\n```\n\n### 🐳 Docker\n\n```bash\n# Build\ndocker build -t miruroapi .\n\n# Run\ndocker run -p 3000:3000 miruroapi\n```\n\n---\n\n## 📜 Available Scripts\n\n| Command | Description | Details |\n|:---|:---|:---|\n| `npm run dev` | 🔥 Start development server | Runs on `localhost:3000` |\n| `npm start` | 🚀 Start production server | `node server.js` |\n\n---\n\n## ⚡ Performance\n\n| Metric | Value |\n|:---|:---|\n| ⚡ Cold start | ~500ms |\n| 🔄 Warm response | ~50-200ms |\n| 💾 Cache hit | ~10ms |\n| 💾 Cache TTL | 1-5 minutes |\n| ⏱️ Rate limit | 100 req/min/IP |\n| 💻 Memory usage | ~15MB |\n| 📦 Cache max size | 100 entries |\n\n### Optimization Features\n\n- 💾 **In-memory cache** — Map-based with TTL expiration\n- ⚡ **Pipe decoding** — Efficient base64url + gzip decompression\n- 🎯 **Selective fetching** — Only AniList GraphQL or Miruro pipe\n- 📁 **Minimal deps** — Only 4 production dependencies\n- 🔄 **Graceful fallback** — Empty arrays on error, never crashes\n\n---\n\n## 📝 Changelog Highlights\n\n| Version | Date | Key Changes |\n|:---|:---|:---|\n| **1.2.0** | 2026-06-09 | Critical response format fix, full endpoint diagnostic, 18/18 passing |\n| **1.1.0** | 2026-06-09 | Swagger UI docs, OpenAPI spec, mappings field, Docker, landing page |\n| **1.0.0** | 2026-06-09 | Initial release — 16 endpoints, AniList GraphQL + Miruro pipe, caching |\n\n\u003e 📝 See [CHANGELOG.md](./CHANGELOG.md) for the full version history.\n\n---\n\n## 🔧 Troubleshooting\n\n| Problem | Cause | Solution |\n|:---|:---|:---|\n| ❌ `npm install` fails | Node.js version too old | Upgrade to Node.js 20+ (`node -v`) |\n| ❌ CORS errors | Frontend domain blocked | CORS is `*` — check browser extension |\n| ❌ 404 on API routes | Wrong URL format | Use `/api/` prefix, not just `/` |\n| ❌ Empty episodes | Provider not available | Check which providers return data for the anime |\n| ❌ Deploy fails on Vercel | Build error | Check `node server.js` locally first |\n| ❌ Slow first request | Serverless cold start | Normal — first request after idle takes ~500ms |\n| ❌ Rate limited | Too many requests | Cache reduces this — wait for TTL expiry |\n\n### 🐛 Debug Mode\n\n```bash\n# Run with verbose logging\nNODE_ENV=development npm run dev\n\n# Test specific endpoint\ncurl http://localhost:3000/api/health\ncurl http://localhost:3000/api/search?query=naruto\ncurl http://localhost:3000/api/episodes/20\n```\n\n---\n\n## ❓ FAQ\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🔍 How do I search for anime?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nUse \u003ccode\u003e/api/search?query=your+search\u003c/code\u003e. Results include title, cover, format, status, episodes, and score. For autocomplete suggestions, use \u003ccode\u003e/api/suggestions?query=your+search\u003c/code\u003e which returns fast suggestions.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e📺 How do I get episode lists?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nUse \u003ccode\u003e/api/episodes/:id\u003c/code\u003e where \u003ccode\u003e:id\u003c/code\u003e is the AniList anime ID (e.g., \u003ccode\u003e20\u003c/code\u003e for Naruto). The response includes all providers with sub/dub episode lists.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🎯 How does filtering work?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nUse \u003ccode\u003e/api/filter\u003c/code\u003e with query params. Combine \u003ccode\u003egenre\u003c/code\u003e, \u003ccode\u003eyear\u003c/code\u003e, \u003ccode\u003eseason\u003c/code\u003e, \u003ccode\u003eformat\u003c/code\u003e, \u003ccode\u003estatus\u003c/code\u003e, and \u003ccode\u003esort\u003c/code\u003e for advanced filtering. All params are optional.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e📡 Can I use this in my frontend app?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nYes! CORS is enabled for all origins (\u003ccode\u003e*\u003c/code\u003e). Just make fetch requests to the API endpoints. No API key needed. Example: \u003ccode\u003efetch('https://mirurotvapi.vercel.app/api/search?query=naruto')\u003c/code\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🔄 How often does the data refresh?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nThe cache TTL is 1-5 minutes depending on the endpoint. After that, the next request triggers a fresh fetch from AniList/Miruro.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🌐 Can I self-host this?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\nYes! Use \u003ccode\u003enpm start\u003c/code\u003e to run the Express server on any VPS, Docker container, or PaaS. The Vercel serverless functions are optional — \u003ccode\u003eserver.js\u003c/code\u003e handles everything.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🎬 Which streaming providers are available?\u003c/b\u003e\u003c/summary\u003e\n\u003cbr/\u003e\n12 providers: kiwi, pewe, bee, bonk, bun, ally, nun, twin, cog, moo, hop, telli. Not all anime are available on every provider.\n\u003c/details\u003e\n\n---\n\n## 🗺️ Roadmap\n\n### 🎯 Planned Features\n\n- [ ] 🔐 **API key authentication** — Per-user rate limits\n- [ ] 📊 **Analytics endpoint** — Usage statistics\n- [ ] 🌙 **Dark/light mode** — Theme toggle for landing page\n- [ ] 📱 **PWA support** — Install as app on mobile\n- [ ] 🔔 **Webhook notifications** — Push new episodes to Discord\n- [ ] 🗄️ **Redis cache** — Persistent caching for serverless\n- [ ] 🌐 **Multi-language** — Sub/dub language metadata\n- [ ] 📦 **NPM package** — Client SDK for easy integration\n\n### ✅ Completed\n\n- [x] 🎬 18 API endpoints covering all data\n- [x] 🔍 Full-text search with pagination\n- [x] 💡 Search suggestions for autocomplete\n- [x] 🎯 Advanced filtering (genre, year, season, format, sort)\n- [x] 🎭 Characters + voice actors from AniList\n- [x] 🔗 Relations and recommendations\n- [x] ⏭️ Skip timestamps (OP/ED)\n- [x] 📡 12 streaming providers with M3U8 URLs\n- [x] 🔄 Smart caching with configurable TTL\n- [x] 🚀 One-click Vercel deployment\n- [x] 🐳 Docker support\n- [x] 📘 Swagger UI interactive docs\n- [x] 📖 Comprehensive documentation with real API data\n\n---\n\n## 🤝 Contributing\n\n*Contributions are welcome and appreciated! Here's how you can help:*\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\n### 🐛 Report Bugs\nFound something broken?\n\n[Open an Issue](https://github.com/Shineii86/MiruroAPI/issues)\n\n\u003c/td\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\n### 💡 Suggest Features\nHave an idea?\n\n[Start a Discussion](https://github.com/Shineii86/MiruroAPI/issues)\n\n\u003c/td\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\n### 🔀 Submit PRs\nReady to contribute code?\n\n[Fork \u0026 Submit](https://github.com/Shineii86/MiruroAPI/fork)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n### 🔄 How to Contribute\n\n```bash\n# 1️⃣ Fork the repository\n# Click the \"Fork\" button on GitHub\n\n# 2️⃣ Clone your fork\ngit clone https://github.com/YOUR_USERNAME/MiruroAPI.git\ncd MiruroAPI\n\n# 3️⃣ Create a feature branch\ngit checkout -b feature/amazing-feature\n\n# 4️⃣ Make your changes\n# Edit files, add features, fix bugs...\n\n# 5️⃣ Commit your changes\ngit commit -m 'feat: add amazing feature'\n\n# 6️⃣ Push to your fork\ngit push origin feature/amazing-feature\n\n# 7️⃣ Open a Pull Request\n# Go to GitHub and create a PR\n```\n\n### 📋 Guidelines\n\n- ✅ Follow the existing code style and documentation conventions\n- ✅ Write meaningful commit messages (use [conventional commits](https://www.conventionalcommits.org/))\n- ✅ Update CHANGELOG.md with your changes\n- ✅ Keep PRs focused — one feature or fix per PR\n- ✅ Add JSDoc comments for new functions\n- ❎ Don't commit `node_modules` or cache files\n- ❎ Don't add unrelated changes to a single PR\n\n---\n\n## 🙏 Acknowledgements\n\n### 🎬 Data Sources\n\n| Source | About |\n|:---|:---|\n| [AniList](https://anilist.co) | Anime metadata API (GraphQL) |\n| [Miruro](https://miruro.tv) | Anime streaming site — source for episodes and streaming |\n| [Miruro TO](https://miruro.to) | Mirror domain |\n| [Miruro BZ](https://miruro.bz) | Mirror domain |\n| [Miruro RU](https://miruro.ru) | Mirror domain |\n\n### 🛠️ Technologies\n\n- **[Express](https://expressjs.com/)** — Fast, unopinionated web framework\n- **[AniList GraphQL](https://anilist.gitbook.io/anilist-apiv2-docs/)** — Rich anime metadata\n- **[Axios](https://axios-http.com/)** — Promise-based HTTP client\n- **[Vercel](https://vercel.com/)** — Serverless deployment platform\n\n### 📝 Resources\n\n- [Shields.io](https://shields.io/) — Badges for README\n- [Star History](https://star-history.com/) — GitHub star history charts\n- [Capsule Render](https://github.com/kyechan99/capsule-render) — Header banner generator\n\n---\n\n## 📄 License\n\n\u003cdiv align=\"center\"\u003e\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-22c55e?style=for-the-badge\u0026logo=mit\u0026logoColor=white)](./LICENSE)\n\nThis project is licensed under the **MIT License**.\n\nFree to use, modify, and distribute — see the [LICENSE](LICENSE) file for details.\n\n\u003c/div\u003e\n\n---\n\n## 👤 Author\n\n\u003cdiv align=\"center\"\u003e\n\n  \u003ca href=\"https://github.com/Shineii86/MiruroAPI\"\u003e\n  \u003cimg src=\"https://github.com/AniWaifuBot/Waifus/blob/main/Source/Banner.png\" alt=\"Banner\" width=\"100%\" /\u003e\n  \u003c/a\u003e\n  \n\u003c/div\u003e\n  \n\u003cp align=\"center\"\u003e\n  \u003cb style=\"font-size: 5.5em;\"\u003eShinei Nouzen\u003c/b\u003e\n  \u003cbr/\u003e\n  \u003csub\u003eFull-Stack Developer \u0026 Anime Enthusiast\u003c/sub\u003e\n  \u003cbr/\u003e\u003cbr/\u003e\n  \u003ca href=\"https://github.com/Shineii86\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-100000?style=for-the-badge\u0026logo=github\u0026logoColor=white\" alt=\"GitHub\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://telegram.me/Shineii86\"\u003e\u003cimg src=\"https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge\u0026logo=telegram\u0026logoColor=white\" alt=\"Telegram\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://instagram.com/ikx7.a\"\u003e\u003cimg src=\"https://img.shields.io/badge/Instagram-C13584?style=for-the-badge\u0026logo=instagram\u0026logoColor=white\" alt=\"Instagram\"/\u003e\u003c/a\u003e\n  \u003ca href=\"mailto:ikx7a@hotmail.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/Email-D14836?style=for-the-badge\u0026logo=gmail\u0026logoColor=white\" alt=\"Email\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## ⭐ Star History\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://star-history.com/#Shineii86/MiruroAPI\u0026Date\"\u003e\n    \u003cimg src=\"https://api.star-history.com/svg?repos=Shineii86/MiruroAPI\u0026type=Date\" alt=\"Star History Chart\" width=\"100%\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003e ⭐ If you found this project useful, please consider giving it a star!\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cb\u003eMade With ❤️ For The Anime Community\u003c/b\u003e\n    \u003cbr/\u003e\u003cbr/\u003e\n    \u003csub\u003e© Shinei Nouzen. All Rights Reserved.\u003c/sub\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshineii86%2Fmiruroapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshineii86%2Fmiruroapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshineii86%2Fmiruroapi/lists"}