Stars Forks Issues Pull Requests Last Commit License

Node.js Express AniList GraphQL Vercel License Version Endpoints Providers

Free RESTful API for anime streaming data powered by AniList GraphQL and Miruro providers.
Search, browse, filter, watch — every endpoint returns fresh data with smart caching.
18 endpoints, 12 streaming providers, M3U8 URLs with subtitles and skip timestamps.

Table of Contents • Features • API Docs • Quick Start • Deployment • Contributing

--- > ## Disclaimer > > 1. This `API` does not store any files — it only links to media hosted on 3rd party services. > 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. > 3. All anime data, images, and content belong to their respective owners (AniList, Miruro). This project is not affiliated with miruro.tv. --- ## Table of Contents - [Overview](#-overview) - [Features](#-features) - [Data Sources](#-data-sources) - [Tech Stack](#-tech-stack) - [Architecture](#-architecture) - [Project Structure](#-project-structure) - [Quick Start](#-quick-start) - [Configuration](#-configuration) - [API Endpoints](#-api-endpoints) - [Streaming Flow](#-streaming-flow) - [Response Schema](#-response-schema) - [Deployment](#-deployment) - [Performance](#-performance) - [FAQ](#-faq) - [Contributing](#-contributing) - [License](#-license) - [Author](#-author) --- ## Overview **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. > No database, no auth, no complex setup. Just deploy to Vercel and you have a production API. ### Why MiruroAPI? - **18 Endpoints** — Complete anime data coverage - **AniList GraphQL** — Rich metadata: scores, characters, relations, recommendations - **12 Streaming Providers** — kiwi, pewe, bee, bonk, bun, ally, nun, twin, cog, moo, hop, telli - **M3U8 URLs** — Direct streaming links with resolution, codec, fansub info - **Skip Timestamps** — OP/ED skip data for supported anime - **Smart Caching** — In-memory Map with TTL reduces API load - **CORS Enabled** — Works from any frontend, no proxy needed - **Swagger UI** — Interactive API documentation at `/docs` - **Docker Ready** — One-command containerized deployment ### How It Works ```mermaid flowchart TD A["Client Request
(Browser / App / curl)"] --> B["Express Server
CORS - Security Headers"] B --> C{"Cache Check
(In-Memory Map)"} C -- HIT --> D["Return Cached
~50ms"] C -- MISS --> E{"Which Source?"} E -- Metadata --> F["AniList GraphQL
graphql.anilist.co"] E -- Streaming --> G["Miruro Pipe
miruro.tv/api/secure/pipe"] F --> H["AniList Response
JSON"] G --> I["Pipe Response
base64url + gzip"] H --> J["Cache + Respond"] I --> J style A fill:#0f172a,stroke:#38bdf8,color:#e2e8f0 style B fill:#0f172a,stroke:#818cf8,color:#e2e8f0 style C fill:#0f172a,stroke:#f43f5e,color:#e2e8f0 style D fill:#0f172a,stroke:#22c55e,color:#e2e8f0 style E fill:#0f172a,stroke:#a855f7,color:#e2e8f0 style F fill:#0f172a,stroke:#02a6e4,color:#e2e8f0 style G fill:#0f172a,stroke:#eab308,color:#e2e8f0 style H fill:#0f172a,stroke:#06b6d4,color:#e2e8f0 style I fill:#0f172a,stroke:#eab308,color:#e2e8f0 style J fill:#0f172a,stroke:#22c55e,color:#e2e8f0 ``` --- ## Features
### Core - **AniList GraphQL** for rich metadata - **Miruro pipe** for streaming sources - **Smart caching** with configurable TTL - **18 RESTful endpoints** - **Graceful error handling** per endpoint - **Rate limiting** (100 req/min per IP) ### Data - **Full-text search** with pagination - **Autocomplete suggestions** for search - **Advanced filtering** — genre, year, season, format, sort - **Characters** with voice actors - **Relations** and **Recommendations** - **Airing schedule** by date
### Streaming - **Episode lists** from 12 providers - **M3U8 streaming URLs** with resolution info - **Skip timestamps** (OP/ED) - **Download links** when available - **Sub/Dub** support per provider - **Codec and fansub** metadata ### Reliability - **CORS enabled** — works from any frontend - **Error responses** with descriptive messages - **Input validation** — required params checked - **Timeout protection** — per request - **In-memory caching** — survives warm starts - **Zero database** — pure API + cache
### Feature Highlights | Feature | Description | Status | |:---|:---|:---:| | 18 API Endpoints | Complete anime data coverage | Done | | AniList GraphQL | Rich metadata from AniList | Done | | 12 Streaming Providers | M3U8 streaming sources | Done | | Full-Text Search | Keyword search with pagination | Done | | Autocomplete Suggestions | Fast search suggestions | Done | | Advanced Filtering | Genre, year, season, format, sort | Done | | Characters + Voice Actors | Full character data from AniList | Done | | Relations & Recommendations | Related anime discovery | Done | | Skip Timestamps | OP/ED skip data | Done | | Smart Caching | In-memory Map with TTL | Done | | Swagger UI Docs | Interactive API documentation | Done | | Docker Support | Containerized deployment | Done | --- ## Data Sources ### Metadata Source | Source | API | Data | |:---|:---|:---| | **AniList** | `graphql.anilist.co` | Search, info, characters, relations, recommendations, filter, schedule | ### Streaming Source | Source | Domain | Data | |:---|:---|:---| | **Miruro** | `miruro.tv` | Episodes, streaming sources (M3U8 URLs) | | **Miruro** | `miruro.to` | Mirror domain | | **Miruro** | `miruro.bz` | Mirror domain | | **Miruro** | `miruro.ru` | Mirror domain | ### Streaming Providers | Provider | Provider | Provider | Provider | |:---|:---|:---|:---| | kiwi | pewe | bee | bonk | | bun | ally | nun | twin | | cog | moo | hop | telli | --- ## Tech Stack | Technology | Purpose | Version | |:---|:---|:---| | [Node.js](https://nodejs.org/) | JavaScript runtime | >= 20 | | [Express](https://expressjs.com/) | HTTP server framework | 4.21 | | [AniList GraphQL](https://anilist.gitbook.io/anilist-apiv2-docs/) | Anime metadata API | — | | [Axios](https://axios-http.com/) | HTTP client | 1.8 | | [Vercel Functions](https://vercel.com/docs/functions) | Serverless deployment | — | | [cors](https://github.com/expressjs/cors) | CORS middleware | 2.8 | | [dotenv](https://github.com/motdotla/dotenv) | Environment variables | 16.4 | ### Dependencies ```json { "express": "^4.21.0", "axios": "^1.8.0", "cors": "^2.8.5", "dotenv": "^16.4.0" } ``` --- ## Architecture ### Request Flow | Stage | Component | Description | |:---:|-----------|-------------| | 1 | **Client** | Browser, app, or `curl` sends request | | 2 | **Express Server** | Routes request, applies CORS + security headers + rate limiting | | 3 | **Cache Check** | In-memory Map with TTL — hit = instant response | | 4 | **Fetch Data** | AniList GraphQL or Miruro pipe endpoint | | 5 | **Decode** | Pipe responses decoded: base64url -> gunzip -> JSON | | 6 | **Cache + Respond** | Store in cache, return JSON response | ### Caching Architecture | Cache Type | TTL | Max Size | Eviction | |:---|:---|:---|:---| | Search results | 1 min | 100 entries | FIFO | | Collection lists | 2-5 min | 100 entries | FIFO | | Episode lists | 2 min | 100 entries | FIFO | | Streaming sources | 1 min | 100 entries | FIFO | > Serverless functions have read-only filesystems except `/tmp`. The cache uses in-memory `Map` which survives across warm invocations. --- ## Project Structure ``` MiruroAPI/ ├── public/ # Static files │ ├── index.html # Premium landing page │ ├── docs.html # Swagger UI documentation │ ├── openapi.json # OpenAPI 3.0 spec │ ├── icon-dark.svg # Miruro dark mode favicon │ ├── icon-light.svg # Miruro light mode favicon │ ├── icon-512x512.png # Miruro app icon │ ├── favicon.ico # Classic favicon │ ├── apple-touch-icon-180x180.png # iOS home screen icon │ └── og-image.png # OG/Twitter share image │ ├── assets/ # Scraped Miruro assets │ ├── favicons/ # All favicon variants │ ├── logos/ # Status page logo │ ├── fonts/ # Inter + FontAwesome │ └── media/ # Testimonial avatars │ ├── src/ │ ├── helpers/ │ │ ├── anilist.js # AniList GraphQL integration │ │ ├── pipe.js # Miruro pipe integration │ │ └── cache.js # In-memory cache with TTL │ └── routes/ │ └── apiRoutes.js # All 18 route definitions │ ├── server.js # Express server entry point ├── package.json # Dependencies & scripts ├── vercel.json # Vercel routing config ├── Dockerfile # Docker support ├── CHANGELOG.md # Version history └── README.md # This file ``` --- ## Quick Start ### Prerequisites | Requirement | Minimum | Recommended | |:---|:---|:---| | Node.js | 20.x | 20.x LTS | | npm | 9.0+ | 10.x | ### Installation ```bash # 1. Clone the repository git clone https://github.com/Shineii86/MiruroAPI.git cd MiruroAPI # 2. Install dependencies npm install # 3. Start development server npm run dev ``` > Open [http://localhost:3000](http://localhost:3000) in your browser. ### Production ```bash npm start ``` ### Alternative Package Managers ```bash # yarn yarn install && yarn dev # pnpm pnpm install && pnpm dev # bun bun install && bun dev ``` --- ## Configuration ### Environment Variables | Variable | Default | Description | |:---|:---|:---| | `PORT` | `3000` | Server port | | `ALLOWED_ORIGINS` | `*` | Comma-separated allowed origins | ### Vercel Configuration The `vercel.json` handles: - **Builds** — Maps `server.js` to `@vercel/node` - **Routes** — All requests forwarded to Express --- ## API Endpoints ### Base URL ``` https://mirurotvapi.vercel.app/api ``` ### Response Format All endpoints return: ```json { "success": true, "results": { ... } } ``` --- ### Health Check ```bash GET /api/health ``` ```bash curl "https://mirurotvapi.vercel.app/api/health" ```
Response ```json { "success": true, "results": { "status": "healthy", "version": "1.2.0", "uptime": "0h 0m 34s", "uptimeSeconds": 34, "timestamp": "2026-06-09T09:55:00.884Z", "node": "v24.14.1", "memory": { "used": "13MB", "total": "15MB" }, "endpoints": 16, "providers": ["kiwi","pewe","bee","bonk","bun","ally","nun","twin","cog","moo","hop","telli"] } } ```
--- ### Search ```bash GET /api/search?query=naruto&per_page=2 ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `query` | string | **required** | Search keyword | | `page` | number | 1 | Page number | | `per_page` | number | 20 | Results per page | ```bash curl "https://mirurotvapi.vercel.app/api/search?query=naruto&per_page=2" ``` ```javascript const res = await fetch("https://mirurotvapi.vercel.app/api/search?query=naruto&per_page=2"); const data = await res.json(); console.log(data.results); // { page, perPage, total, hasNextPage, results: [...] } ```
Response ```json { "success": true, "results": { "page": 1, "perPage": 2, "total": 5000, "hasNextPage": true, "results": [ { "id": 20, "title": { "romaji": "NARUTO", "english": "Naruto", "native": "NARUTO -ナルト-" }, "coverImage": { "large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx20-dE6UHbFFg1A5.jpg" }, "format": "TV", "season": "FALL", "seasonYear": 2002, "episodes": 220, "status": "FINISHED", "averageScore": 80, "genres": ["Action","Adventure","Comedy","Drama","Fantasy","Supernatural"] } ] } } ```
--- ### Suggestions ```bash GET /api/suggestions?query=naruto ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `query` | string | **required** | Search keyword | ```bash curl "https://mirurotvapi.vercel.app/api/suggestions?query=naruto" ```
Response ```json { "success": true, "results": [ { "id": 20, "title": "Naruto", "title_romaji": "NARUTO", "poster": "...", "format": "TV", "status": "FINISHED", "year": 2002, "episodes": 220 }, { "id": 1735, "title": "Naruto: Shippuden", "title_romaji": "NARUTO: Shippuuden", "poster": "...", "format": "TV", "status": "FINISHED", "year": 2007, "episodes": 500 } ] } ```
--- ### Filter ```bash GET /api/filter?genre=Action&sort=POPULARITY_DESC&per_page=1 ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `genre` | string | — | Genre name (e.g. "Action") | | `tag` | string | — | Tag name | | `year` | number | — | Release year | | `season` | string | — | FALL, WINTER, SPRING, SUMMER | | `format` | string | — | TV, MOVIE, OVA, ONA, SPECIAL, MUSIC | | `status` | string | — | RELEASING, FINISHED, NOT_YET_RELEASED, CANCELLED | | `sort` | string | POPULARITY_DESC | Sort order | | `page` | number | 1 | Page number | | `per_page` | number | 20 | Results per page | ```bash curl "https://mirurotvapi.vercel.app/api/filter?genre=Action&year=2024&season=WINTER&per_page=3" ```
Response ```json { "success": true, "results": { "page": 1, "perPage": 3, "total": 5000, "hasNextPage": true, "results": [ ... ] } } ```
--- ### Trending ```bash GET /api/trending?per_page=10 ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `per_page` | number | 20 | Results per page | ```bash curl "https://mirurotvapi.vercel.app/api/trending?per_page=3" ``` --- ### Popular ```bash GET /api/popular?per_page=10 ``` --- ### Upcoming ```bash GET /api/upcoming?per_page=10 ``` --- ### Recent ```bash GET /api/recent?per_page=10 ``` --- ### Spotlight ```bash GET /api/spotlight ``` Returns featured/spotlight anime for the hero carousel.
Response ```json { "success": true, "results": [ { "id": 21, "title": { "romaji": "ONE PIECE", "english": "One Piece" }, "coverImage": { "large": "..." }, "bannerImage": "https://...", "format": "TV", "episodes": null, "status": "RELEASING", "averageScore": 85, "genres": ["Action","Adventure","Comedy","Fantasy"], "description": "Gol D. Roger was known as the Pirate King..." } ] } ```
--- ### Schedule ```bash GET /api/schedule?date=2026-06-09 ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `date` | string | today | Date in YYYY-MM-DD format | --- ### Anime Info ```bash GET /api/info/:id ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `id` | number | **required** | AniList anime ID | ```bash curl "https://mirurotvapi.vercel.app/api/info/20" ``` ```javascript const res = await fetch("https://mirurotvapi.vercel.app/api/info/20"); const data = await res.json(); console.log(data.results.title); // { romaji: "NARUTO", english: "Naruto" } ```
Response ```json { "success": true, "results": { "id": 20, "idMal": 20, "title": { "romaji": "NARUTO", "english": "Naruto", "native": "NARUTO -ナルト-" }, "description": "Naruto Uzumaki, a hyperactive and knuckle-headed ninja...", "coverImage": { "large": "https://s4.anilist.co/file/..." }, "bannerImage": "https://s4.anilist.co/file/...", "format": "TV", "season": "FALL", "seasonYear": 2002, "episodes": 220, "duration": 23, "status": "FINISHED", "averageScore": 80, "popularity": 694959, "genres": ["Action","Adventure","Comedy","Drama","Fantasy","Supernatural"], "studios": [{ "name": "Studio Pierrot", "isAnimationStudio": true }], "startDate": { "year": 2002, "month": 10, "day": 3 }, "endDate": { "year": 2007, "month": 2, "day": 8 } } } ```
--- ### Characters ```bash GET /api/anime/:id/characters ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `id` | number | **required** | AniList anime ID | ```bash curl "https://mirurotvapi.vercel.app/api/anime/20/characters" ```
Response ```json { "success": true, "results": { "edges": [ { "role": "MAIN", "node": { "id": 17, "name": { "full": "Naruto Uzumaki", "native": "うずまきナルト" }, "image": { "large": "https://s4.anilist.co/file/..." } }, "voiceActors": [ { "id": 95015, "name": { "full": "Junko Takeuchi", "native": "竹内順子" }, "languageV2": "Japanese" } ] } ] } } ```
--- ### Relations ```bash GET /api/anime/:id/relations ``` Returns related anime (sequels, prequels, side stories, etc.). --- ### Recommendations ```bash GET /api/anime/:id/recommendations ``` Returns recommended anime based on the given ID. --- ### Episodes ```bash GET /api/episodes/:id ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `id` | number | **required** | AniList anime ID | ```bash curl "https://mirurotvapi.vercel.app/api/episodes/20" ```
Response ```json { "success": true, "results": { "providers": { "kiwi": { "meta": { "id": "1571", "title": "Naruto", "type": "TV" }, "episodes": { "sub": [ { "id": "watch/kiwi/20/sub/anikoto-1", "number": 1, "title": "Enter: Naruto Uzumaki!", "image": "https://image.tmdb.org/t/p/original/...", "airDate": "2002-10-03", "audio": "sub", "filler": false, "fillerType": "manga_canon" } ] } } } } } ```
--- ### Watch (Streaming Sources) ```bash GET /api/watch/:provider/:anilistId/:category/:slug ``` | Param | Type | Default | Description | |:---|:---|:---|:---| | `provider` | string | **required** | Provider name (kiwi, pewe, etc.) | | `anilistId` | number | **required** | AniList anime ID | | `category` | string | **required** | sub or dub | | `slug` | string | **required** | Episode slug from episodes response | ```bash curl "https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1" ``` ```javascript const res = await fetch("https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1"); const data = await res.json(); const streams = data.results.streams; // streams[0].url = "https://vault-01.uwucdn.top/stream/.../uwu.m3u8" // streams[0].quality = "360p" // streams[0].type = "hls" ```
Response ```json { "success": true, "results": { "streams": [ { "url": "https://vault-01.uwucdn.top/stream/.../uwu.m3u8", "type": "hls", "quality": "360p", "resolution": { "width": 640, "height": 360 }, "codec": "h264", "audio": "sub", "fansub": "df68", "isActive": false, "referer": "https://kwik.cx/e/..." }, { "url": "https://kwik.cx/e/...", "type": "embed", "quality": "360p", "codec": "h264", "audio": "sub", "fansub": "df68", "isActive": false } ], "download": "https://pahe.win/LJmbA" } } ```
--- ## Streaming Flow To get a stream URL, follow these 3 steps: ```bash # Step 1: Get episodes (returns provider slugs) curl "https://mirurotvapi.vercel.app/api/episodes/20" # => providers.kiwi.episodes.sub[0].id = "watch/kiwi/20/sub/anikoto-1" # Step 2: Get streaming sources curl "https://mirurotvapi.vercel.app/api/watch/kiwi/20/sub/animepahe-1" # => streams[0].url = "https://...m3u8" # Step 3: Play M3U8 in any HLS player # Use hls.js, video.js, or native