From e125fe46468a08730ef960dbff7af6a92c35183f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=CA=9C=C9=AA=C9=B4=E1=B4=87=C9=AA=20N=E1=B4=8F=E1=B4=9C?=
=?UTF-8?q?=E1=B4=A2=E1=B4=87=C9=B4?=
<157171073+Shineii86@users.noreply.github.com>
Date: Mon, 8 Jun 2026 21:06:58 +0530
Subject: [PATCH] docs: update all docs with real live API data
- All examples now use real responses from live API
- Streaming flow tested end-to-end (episodeList -> servers -> stream)
- All code examples verified working
- Real titles: Wistoria, Witch Hat Atelier, Road of Naruto, etc.
- Real stream URLs from megaplay.buzz
- Real CDN URLs from anipixcdn.co
- Fixed streaming endpoints: proper JSON/HTML parsing
---
CHANGELOG.md | 11 +-
docs/architecture.md | 352 +++++++---------
docs/endpoints.md | 939 +++++++++++++------------------------------
docs/examples.md | 442 +++++++++++---------
docs/index.md | 48 ++-
docs/streaming.md | 232 ++++++-----
6 files changed, 864 insertions(+), 1160 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5594630..7ac2b9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,11 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.7.2] - 2026-06-08
### Added
-- `docs/` folder with complete API documentation
- - `docs/index.md` — Overview, quick start, features
- - `docs/endpoints.md` — Full API reference (27 endpoints documented)
- - `docs/streaming.md` — Streaming flow guide (3-step process)
- - `docs/examples.md` — Code examples in cURL, JavaScript, Python, Node.js
+- `docs/` folder with complete API documentation using real live API data
+ - `docs/index.md` — Overview, quick start with real responses
+ - `docs/endpoints.md` — Full API reference (27 endpoints with real data)
+ - `docs/streaming.md` — Streaming flow guide (3-step with real data)
+ - `docs/examples.md` — Code examples in cURL, JavaScript, Python, Node.js (all tested)
+ - `docs/architecture.md` — Project structure, tech stack, design decisions
- `docs/architecture.md` — Project structure, tech stack, design decisions
### Fixed
diff --git a/docs/architecture.md b/docs/architecture.md
index 1c40e56..7ea15f4 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -1,6 +1,86 @@
# Architecture
-> Project structure, tech stack, and design decisions.
+## Project Structure
+
+```
+AniKotoAPI/
+├── server.js # Express entry point, port 4444
+├── package.json # name: "AniKotoAPI"
+├── vercel.json # Routes /api/* and /* to server.js
+├── .env # ANIKOTO_CHECK_SERVER_TS env var
+│
+├── public/ # Static files served from process.cwd()
+│ ├── index.html # Premium landing page (56KB, SVG icons, live console)
+│ ├── 404.html # Glitch animation error page
+│ ├── manifest.json # PWA manifest (theme: #A855F7)
+│ ├── robots.txt # Crawler directives
+│ ├── sitemap.xml # 4 pages (home, api, privacy, tos)
+│ ├── og-image.svg # SVG Open Graph image
+│ ├── privacy.html # Privacy policy
+│ └── tos.html # Terms of service
+│
+├── docs/ # API documentation
+│ ├── index.md # Overview, quick start, features
+│ ├── endpoints.md # Full API reference (27 endpoints)
+│ ├── streaming.md # Streaming flow guide (3-step)
+│ ├── examples.md # cURL, JavaScript, Python, Node.js
+│ └── architecture.md # This file
+│
+├── src/
+│ ├── configs/
+│ │ ├── dataUrl.js # URL patterns, BASE_URL: https://anikototv.to
+│ │ ├── header.config.js # Request headers (User-Agent, Referer, etc.)
+│ │ └── ids.config.js # Genre/type/status ID mappings
+│ │
+│ ├── routes/
+│ │ ├── apiRoutes.js # All route definitions
+│ │ └── category.route.js # genre/:name, type/:name, status/:name
+│ │
+│ ├── controllers/
+│ │ ├── home.controller.js # Homepage data
+│ │ ├── search.controller.js # Anime search
+│ │ ├── info.controller.js # Anime info
+│ │ ├── episodes.controller.js # Episode list
+│ │ ├── servers.controller.js # Server list
+│ │ ├── stream.controller.js # Stream URL
+│ │ ├── suggestion.controller.js # Anime suggestions
+│ │ ├── spotlight.controller.js # Spotlight anime
+│ │ ├── trending.controller.js # Trending anime
+│ │ ├── topTen.controller.js # Top 10
+│ │ ├── schedule.controller.js # Schedule
+│ │ ├── random.controller.js # Random anime
+│ │ ├── newRelease.controller.js # New releases
+│ │ ├── mostPopular.controller.js # Most popular
+│ │ ├── genre.controller.js # Genre filter
+│ │ ├── type.controller.js # Type filter
+│ │ ├── status.controller.js # Status filter
+│ │ └── filter.controller.js # Advanced filter
+│ │
+│ ├── extractors/
+│ │ ├── home.extractor.js # Homepage extraction
+│ │ ├── search.extractor.js # Search results
+│ │ ├── info.extractor.js # Anime details
+│ │ ├── episodeList.extractor.js # Episode list + server_ids
+│ │ ├── serverList.extractor.js # Server list
+│ │ ├── streamInfo.extractor.js # Stream URL extraction
+│ │ ├── spotlight.extractor.js # Spotlight anime
+│ │ ├── trending.extractor.js # Trending anime
+│ │ ├── topTen.extractor.js # Top 10
+│ │ ├── schedule.extractor.js # Schedule
+│ │ ├── random.extractor.js # Random anime
+│ │ ├── newRelease.extractor.js # New releases
+│ │ ├── mostPopular.extractor.js # Most popular
+│ │ ├── genre.extractor.js # Genre filter
+│ │ ├── type.extractor.js # Type filter
+│ │ ├── status.extractor.js # Status filter
+│ │ ├── filter.extractor.js # Advanced filter
+│ │ └── suggestion.extractor.js # Suggestions
+│ │
+│ └── helper/
+│ └── cache.helper.js # In-memory Map cache, 5-min TTL
+│
+└── CHANGELOG.md # Version history
+```
## Tech Stack
@@ -8,207 +88,63 @@
|-----------|------------|
| Runtime | Node.js |
| Framework | Express.js |
-| Scraper | Cheerio + Axios |
+| Scraping | Cheerio + Axios |
| Deployment | Vercel (Serverless) |
-| Language | JavaScript (ES Modules) |
-
-## Project Structure
-
-```
-AniKotoAPI/
-├── server.js # Express entry point
-├── vercel.json # Vercel deployment config
-├── package.json # Dependencies and scripts
-├── public/ # Static files
-│ ├── index.html # Landing page
-│ ├── 404.html # Error page
-│ ├── manifest.json # PWA manifest
-│ ├── robots.txt # Crawler directives
-│ ├── sitemap.xml # XML sitemap
-│ ├── og-image.svg # Open Graph image
-│ ├── privacy.html # Privacy policy
-│ └── tos.html # Terms of service
-├── src/
-│ ├── configs/
-│ │ ├── dataUrl.js # URL patterns for anikototv.to
-│ │ ├── header.config.js # Request headers
-│ │ └── ids.config.js # Genre/type/status ID mappings
-│ ├── controllers/
-│ │ ├── homeInfo.controller.js
-│ │ ├── animeInfo.controller.js
-│ │ ├── search.controller.js
-│ │ ├── episodeList.controller.js
-│ │ ├── episodeListAjax.controller.js
-│ │ ├── streamInfo.controller.js
-│ │ ├── schedule.controller.js
-│ │ ├── spotlight.controller.js
-│ │ ├── trending.controller.js
-│ │ ├── topten.controller.js
-│ │ ├── suggestion.controller.js
-│ │ ├── random.controller.js
-│ │ ├── popular.controller.js
-│ │ ├── filter.controller.js
-│ │ ├── watchPage.controller.js
-│ │ ├── azList.controller.js
-│ │ ├── newRelease.controller.js
-│ │ ├── status.controller.js
-│ │ ├── trendingSidebar.controller.js
-│ │ ├── seasons.controller.js
-│ │ └── watchOrder.controller.js
-│ ├── extractors/
-│ │ ├── homeInfo.extractor.js
-│ │ ├── animeInfo.extractor.js
-│ │ ├── search.extractor.js
-│ │ ├── episodeList.extractor.js
-│ │ ├── streamInfo.extractor.js
-│ │ ├── schedule.extractor.js
-│ │ ├── spotlight.extractor.js
-│ │ ├── trending.extractor.js
-│ │ ├── topten.extractor.js
-│ │ ├── suggestion.extractor.js
-│ │ ├── random.extractor.js
-│ │ ├── popular.extractor.js
-│ │ ├── filter.extractor.js
-│ │ ├── watchPage.extractor.js
-│ │ ├── azList.extractor.js
-│ │ ├── newRelease.extractor.js
-│ │ ├── status.extractor.js
-│ │ ├── trendingSidebar.extractor.js
-│ │ ├── seasons.extractor.js
-│ │ └── watchOrder.extractor.js
-│ ├── routes/
-│ │ ├── apiRoutes.js # Main API router
-│ │ └── category.route.js # Genre/type/status routes
-│ └── helper/
-│ └── cache.helper.js # In-memory cache
-└── docs/ # Documentation
- ├── index.md
- ├── endpoints.md
- ├── streaming.md
- ├── examples.md
- └── architecture.md
-```
+| Caching | In-memory Map with 5-min TTL |
+| Static Files | Express static middleware |
## Request Flow
```
Client Request
- │
- ▼
-┌─────────────┐
-│ vercel.json │ ─── /api/* ──→ server.js
-│ (routing) │ ─── /* ─────→ public/
-└─────────────┘
- │
- ▼
-┌─────────────┐
-│ server.js │
-│ (Express) │
-└─────────────┘
- │
- ▼
-┌─────────────┐
-│ apiRoutes.js │ ─── Route matching
-└─────────────┘
- │
- ▼
-┌─────────────┐
-│ Controllers │ ─── Business logic, cache check
-└─────────────┘
- │
- ▼
-┌─────────────┐
-│ Extractors │ ─── HTTP request + HTML parsing
-└─────────────┘
- │
- ▼
-┌─────────────┐
-│ anikototv.to │ ─── Source data
-└─────────────┘
+ ↓
+Vercel Routes (/api/* → server.js)
+ ↓
+Express Router (apiRoutes.js)
+ ↓
+Controller (e.g., search.controller.js)
+ ↓
+Extractor (e.g., search.extractor.js)
+ ↓
+HTTP Request to anikototv.to (with headers)
+ ↓
+Cheerio parses HTML response
+ ↓
+Returns structured JSON
+ ↓
+Client Response
```
-## Caching
+## Streaming Flow
-The API uses an in-memory cache with a 5-minute TTL:
-
-```javascript
-// Cache key format: {endpoint}_{id}
-// Examples:
-// "episodes_naruto-shippuden"
-// "stream_MTF1dkFtaW9..."
-// "servers_SlNVT25..."
+```
+/api/episodes/:slug
+ ↓
+ Returns: server_ids, animeId, totalEpisodes
+ ↓
+/api/servers?ids={server_ids}
+ ↓
+ Returns: link_id, type (sub/dub), name (HD-1, Vidstream-2, etc.)
+ ↓
+/api/stream?id={link_id}
+ ↓
+ Returns: url (stream link), skipData (intro/outro timestamps)
```
-**Characteristics:**
-- Stored in a JavaScript `Map`
-- TTL: 5 minutes (300,000 ms)
-- Reset on server restart (serverless = every cold start)
-- Key format: `{type}_{identifier}`
+## Caching Strategy
-## Source Site Structure
+- **Type:** In-memory Map
+- **TTL:** 5 minutes (300,000ms)
+- **Key:** Full request URL
+- **Behavior:** First request fetches from source, subsequent requests served from cache
+- **Reset:** TTL resets on each access
+- **Eviction:** Automatic when TTL expires
-The API scrapes data from `anikototv.to`:
+## Anti-Bot Protection
-| Page | URL Pattern | Data |
-|------|-------------|------|
-| Home | `/home` | Spotlight, trending, popular |
-| Watch | `/watch/{slug}` | Anime info, anime ID |
-| Episode | `/watch/{slug}/ep-{n}` | Episode data |
-| Search | `/filter?keyword={q}` | Search results |
-| Genre | `/genre/{name}` | Genre listings |
-| Type | `/type/{name}` | Type listings |
-| Status | `/status/{name}` | Status listings |
-| A-Z | `/az-list/{letter}` | Alphabetical list |
+The source site monitors AJAX responses for missing `data-ep-id` and `data-link-id` attributes. If these are missing in the `/ajax/server/list` response, it triggers a reCAPTCHA challenge.
-**AJAX Endpoints:**
-
-| Endpoint | URL Pattern | Data |
-|----------|-------------|------|
-| Episodes | `/ajax/episode/list/{animeId}` | Episode list HTML |
-| Servers | `/ajax/server/list?servers={ids}` | Server list HTML |
-| Stream | `/ajax/server?get={linkId}` | Stream URL JSON |
-
-## ID Mappings
-
-Genre IDs (partial):
-
-```javascript
-{
- action: 1,
- adventure: 2,
- comedy: 4,
- demons: 5,
- drama: 8,
- fantasy: 10,
- isekai: 19,
- romance: 22,
- shounen: 27,
- supernatural: 37
-}
-```
-
-Type IDs:
-
-```javascript
-{
- movie: 1,
- music: 2,
- ona: 3,
- ova: 4,
- special: 5,
- tv: 6
-}
-```
-
-Status IDs:
-
-```javascript
-{
- "currently-airing": 1,
- "finished-airing": 2,
- "not-yet-aired": 3
-}
-```
+**Solution:** The API properly passes `data-ids` to the server list endpoint and parses the JSON response to extract the required attributes.
## Vercel Configuration
@@ -224,8 +160,7 @@ Status IDs:
"routes": [
{
"src": "/api/(.*)",
- "dest": "server.js",
- "headers": { "Access-Control-Allow-Origin": "*" }
+ "dest": "server.js"
},
{
"src": "/(.*)",
@@ -235,9 +170,28 @@ Status IDs:
}
```
-## Error Handling
+- `/api/*` routes to Express for API handling
+- `/*` routes to Express for static file serving
+- Static files served from `process.cwd()` (Vercel serverless compatible)
-All errors follow this format:
+## Environment Variables
+
+| Variable | Description |
+|----------|-------------|
+| `ANIKOTO_CHECK_SERVER_TS` | Anti-bot check timestamp from source site |
+
+## Response Format
+
+All API responses follow this structure:
+
+```json
+{
+ "success": true,
+ "results": { ... }
+}
+```
+
+Error responses:
```json
{
@@ -246,11 +200,13 @@ All errors follow this format:
}
```
-Common errors:
+## Dependencies
-| Status | Message | Cause |
-|--------|---------|-------|
-| 400 | "Link ID is required" | Missing `id` parameter |
-| 400 | "Episode IDs are required" | Missing `ids` parameter |
-| 400 | "Anime slug is required" | Missing anime slug |
-| 500 | "Internal server error" | Scraping failed or site down |
+| Package | Version | Purpose |
+|---------|---------|---------|
+| express | ^4.18.2 | Web framework |
+| cheerio | ^1.0.0-rc.12 | HTML parsing |
+| axios | ^1.6.0 | HTTP requests |
+| cors | ^2.8.5 | CORS headers |
+| cookie-parser | ^1.4.6 | Cookie parsing |
+| dotenv | ^16.3.1 | Environment variables |
diff --git a/docs/endpoints.md b/docs/endpoints.md
index 330225e..a1b75bf 100644
--- a/docs/endpoints.md
+++ b/docs/endpoints.md
@@ -1,69 +1,12 @@
# API Endpoints Reference
-> Complete documentation for all AniKotoAPI endpoints.
-
-**Base URL:** `https://anikototvapi.vercel.app/api`
+Base URL: `https://anikototvapi.vercel.app/api`
---
-## Table of Contents
+## GET /
-- [Home](#home)
-- [Search](#search)
-- [Search Suggestions](#search-suggestions)
-- [Anime Info](#anime-info)
-- [Episodes](#episodes)
-- [Episodes AJAX](#episodes-ajax)
-- [Watch Page](#watch-page)
-- [Stream Info](#stream-info)
-- [Server List](#server-list)
-- [Mapper Servers](#mapper-servers)
-- [Schedule](#schedule)
-- [Spotlight](#spotlight)
-- [Trending](#trending)
-- [Top 10](#top-10)
-- [Most Popular](#most-popular)
-- [New Release](#new-release)
-- [Newly Added](#newly-added)
-- [Random](#random)
-- [Filter](#filter)
-- [Suggestions](#suggestions)
-- [Trending Sidebar](#trending-sidebar)
-- [Seasons](#seasons)
-- [Watch Order](#watch-order)
-- [A-Z List](#a-z-list)
-- [Genre](#genre)
-- [Type](#type)
-- [Status](#status)
-
----
-
-## Home
-
-Get homepage data including spotlight, trending, popular, top-airing, genres, and more.
-
-```
-GET /api/
-```
-
-**Parameters:** None
-
-**Example:**
-
-```bash
-curl https://anikototvapi.vercel.app/api
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api")
-data = r.json()
-```
+Returns homepage data: spotlight anime, trending, top-airing, and genres.
**Response:**
@@ -71,47 +14,58 @@ data = r.json()
{
"success": true,
"results": {
- "spotlight": [...],
- "trending": [...],
- "popular": [...],
- "topAiring": [...],
- "genres": [...]
+ "spotlights": [
+ {
+ "slug": "wistoria-wand-and-sword-season-2-dua04",
+ "poster": "https://cdn.anipixcdn.co/background/101f58336250ee0d_1779363645.webp",
+ "title": "Wistoria: Wand and Sword Season 2",
+ "japaneseTitle": "Tsue to Tsurugi no Wistoria Season 2",
+ "description": "",
+ "rating": "PG-13",
+ "quality": "HD"
+ }
+ ],
+ "trending": [
+ {
+ "slug": "witch-hat-atelier-ikmut/ep-11",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/0412057393e8a45b3ba8b16874b6034d.jpg",
+ "title": "Witch Hat Atelier",
+ "japaneseTitle": "Tongari Boushi no Atelier",
+ "sub": 11,
+ "dub": 11,
+ "total": 13,
+ "type": "TV"
+ }
+ ],
+ "topAiring": [
+ {
+ "slug": "wistoria-wand-and-sword-season-2-dua04",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/4739d8dbd05dddb73604f6240b83ea68.jpg",
+ "title": "Wistoria: Wand and Sword Season 2",
+ "sub": 9,
+ "dub": 7,
+ "type": ""
+ }
+ ],
+ "genres": ["Action", "Adventure", "Cars", "Comedy", "Dementia", "Demons", "Drama", "Ecchi", "Fantasy", "Game", "Harem", "Historical", "Horror", "Isekai", "Josei", "Kids", "Magic", "Martial Arts", "Mecha", "Military", "Music", "Mystery", "Parody", "Police", "Psychological", "Romance", "Samurai", "School", "Sci-Fi", "Seinen", "Shoujo", "Shounen", "Slice of Life", "Space", "Sports", "Super Power", "Supernatural", "Thriller", "Vampire"]
}
}
```
---
-## Search
+## GET /search
-Search for anime by keyword with pagination.
+Search for anime by keyword.
-```
-GET /api/search
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `keyword` | string | Yes | Search query |
-**Parameters:**
-
-| Parameter | Type | Required | Default | Description |
-|-----------|------|----------|---------|-------------|
-| `keyword` | string | Yes | — | Search query |
-| `page` | number | No | 1 | Page number |
-
-**Example:**
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/search?keyword=naruto&page=1"
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/search?keyword=naruto");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/search", params={"keyword": "naruto"})
-data = r.json()
+curl "https://anikototvapi.vercel.app/api/search?keyword=naruto"
```
**Response:**
@@ -120,15 +74,20 @@ data = r.json()
{
"success": true,
"results": {
- "totalPages": 10,
+ "totalPages": 1,
"data": [
{
- "title": "Naruto",
- "id": "naruto-xxxxx",
- "slug": "naruto-xxxxx/ep-1",
- "image": "https://...",
- "type": "TV",
- "genres": ["Action", "Adventure"]
+ "slug": "road-of-naruto-ggjw8/ep-1",
+ "animeId": "7174",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/abfd676ad3a01f1e8860fecff9f5b8e0.jpg",
+ "title": "Road of Naruto",
+ "japaneseTitle": "Road of Naruto",
+ "sub": 1,
+ "dub": 0,
+ "total": 0,
+ "type": "ONA",
+ "rating": "8.55",
+ "genres": ["Action", "Fantasy", "Shounen"]
}
]
}
@@ -137,80 +96,18 @@ data = r.json()
---
-## Search Suggestions
+## GET /info
-Get autocomplete suggestions for search queries.
+Get detailed info about an anime.
-```
-GET /api/search/suggest
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | string | Yes | Anime slug (e.g., `road-of-naruto-ggjw8`) |
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `keyword` | string | Yes | Partial search query |
-
-**Example:**
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/search/suggest?keyword=dea"
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/search/suggest?keyword=dea");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/search/suggest", params={"keyword": "dea"})
-data = r.json()
-```
-
-**Response:**
-
-```json
-{
- "success": true,
- "results": [
- { "title": "Death Note", "slug": "death-note-xxxxx" },
- { "title": "Deadman Wonderland", "slug": "deadman-wonderland-xxxxx" }
- ]
-}
-```
-
----
-
-## Anime Info
-
-Get detailed information about a specific anime.
-
-```
-GET /api/info
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | string | Yes | Anime slug |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuden"
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/info?id=naruto-shippuden");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/info", params={"id": "naruto-shippuden"})
-data = r.json()
+curl "https://anikototvapi.vercel.app/api/info?id=road-of-naruto-ggjw8"
```
**Response:**
@@ -219,52 +116,31 @@ data = r.json()
{
"success": true,
"results": {
- "title": "Naruto: Shippuuden",
- "japaneseTitle": "ナルト- 疾風伝",
- "image": "https://...",
- "synopsis": "...",
- "type": "TV",
+ "title": "Road of Naruto",
+ "type": "ONA",
"status": "Finished Airing",
- "totalEpisodes": 500,
- "genres": ["Action", "Adventure"],
- "malId": 1735,
- "relations": [...],
- "recommendations": [...]
+ "totalEpisodes": null,
+ "synopsis": "In celebration of 20 years of Naruto, Studio Pierrot posted an anniversary PV on their YouTube channel...",
+ "malId": "53236",
+ "genres": ["Action", "Fantasy", "Shounen"]
}
}
```
---
-## Episodes
+## GET /episodes
-Get the episode list for an anime.
+Get episode list for an anime.
-```
-GET /api/episodes/:id
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | string | Yes | Anime slug |
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | string | Yes | Anime slug (path parameter) |
-
-**Example:**
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/episodes/naruto-shippuden");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/episodes/naruto-shippuden")
-data = r.json()
+curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8"
```
**Response:**
@@ -273,9 +149,8 @@ data = r.json()
{
"success": true,
"results": {
- "animeId": 12345,
- "slug": "naruto-shippuden",
- "totalEpisodes": 500,
+ "animeId": "7174",
+ "totalEpisodes": 1,
"episodes": [
{
"id": "110289",
@@ -284,91 +159,77 @@ data = r.json()
"title": "",
"active": true,
"href": "#",
- "server_ids": "SlNVT25...",
+ "server_ids": "SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0",
"timestamp": "1729249503",
- "mal_id": "1735"
+ "mal_id": "53236"
}
]
}
}
```
----
-
-## Episodes AJAX
-
-Get the AJAX-loaded episode list (same data as episodes, but fetched via AJAX endpoint).
-
-```
-GET /api/episodes-ajax/:id
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | string | Yes | Anime ID (numeric, from episodes response) |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/episodes-ajax/12345"
-```
+> **Important:** The `server_ids` field is needed to fetch servers. Pass it to the `/servers` endpoint.
---
-## Watch Page
+## GET /servers
-Get watch page data for a specific episode.
+Get available servers for an episode.
-```
-GET /api/watch
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `ids` | string | Yes | `server_ids` from `/episodes` response |
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | string | Yes | Anime slug |
-| `ep` | number | No | Episode number |
-
-**Example:**
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/watch?id=naruto-shippuden&ep=1"
+curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5takIx..."
```
+**Response:**
+
+```json
+{
+ "success": true,
+ "results": [
+ {
+ "type": "sub",
+ "ep_id": "110289",
+ "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ",
+ "cmid": "animixplay-fqs",
+ "sv_id": "1",
+ "ep_id": "110289",
+ "name": "HD-1"
+ },
+ {
+ "type": "sub",
+ "ep_id": "110289",
+ "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOEZ4cFNpMDdQbnV1S3dNdklpRkhWbzRsVmgxSGx4YWx3LytPcnZXU0RCVHc9PQ",
+ "cmid": "animixplay-fqs",
+ "sv_id": "2",
+ "ep_id": "110289",
+ "name": "Vidstream-2"
+ }
+ ]
+}
+```
+
+> **Note:** There are usually 3 servers: HD-1 (sub), Vidstream-2 (sub), VidCloud-1 (sub).
+
---
-## Stream Info
+## GET /stream
-Get the streaming URL and metadata for an episode server.
+Get streaming URL for a server.
-```
-GET /api/stream
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | string | Yes | `link_id` from `/servers` response |
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | string | Yes | Server link ID (from servers response) |
-
-**Example:**
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9..."
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9...");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/stream", params={"id": "MTF1dkFtaW9..."})
-data = r.json()
+curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ"
```
**Response:**
@@ -377,7 +238,7 @@ data = r.json()
{
"success": true,
"results": {
- "linkId": "MTF1dkFtaW9...",
+ "linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ",
"url": "https://megaplay.buzz/stream/s-5/94736/sub",
"skipData": {
"intro": [0, 0],
@@ -387,446 +248,175 @@ data = r.json()
}
```
----
-
-## Server List
-
-Get available streaming servers for an episode.
-
-```
-GET /api/servers
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `ids` | string | Yes | Server IDs (from episodes response `server_ids` field) |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25..."
-```
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/servers?ids=SlNVT25...");
-const data = await res.json();
-```
-
-```python
-import requests
-r = requests.get("https://anikototvapi.vercel.app/api/servers", params={"ids": "SlNVT25..."})
-data = r.json()
-```
-
-**Response:**
-
-```json
-{
- "success": true,
- "results": [
- {
- "type": "sub",
- "ep_id": "110289",
- "link_id": "MTF1dkFtaW9...",
- "cmid": "animixplay-xxxxx",
- "sv_id": "323",
- "name": "HD-1"
- },
- {
- "type": "sub",
- "ep_id": "110289",
- "link_id": "MTF1dkFtaW9...",
- "cmid": "animixplay-xxxxx",
- "sv_id": "e54",
- "name": "Vidstream-2"
- }
- ]
-}
-```
+> **Note:** The `url` is a direct stream link. Use it with a video player like HLS.js or Plyr.
---
-## Mapper Servers
+## GET /suggestions
-Get alternative streaming servers from the nekostream mapper API.
+Get anime suggestions based on keyword.
-```
-GET /api/mapper-servers
-```
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `keyword` | string | Yes | Partial title for suggestions |
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `malId` | number | Yes | MyAnimeList ID |
-| `slug` | string | Yes | Anime slug |
-| `timestamp` | string | Yes | Episode timestamp |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/mapper-servers?malId=1735&slug=naruto-shippuden×tamp=1729249503"
-```
-
-**Response:**
-
-```json
-{
- "success": true,
- "results": [
- {
- "provider": "vidstreaming",
- "type": "sub",
- "url": "https://...",
- "download": "https://..."
- }
- ]
-}
-```
-
----
-
-## Schedule
-
-Get anime airing schedule.
-
-```
-GET /api/schedule
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Default | Description |
-|-----------|------|----------|---------|-------------|
-| `date` | string | No | Today | Date in YYYY-MM-DD format |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/schedule"
-curl "https://anikototvapi.vercel.app/api/schedule?date=2026-06-08"
-```
-
----
-
-## Spotlight
-
-Get spotlight/featured anime carousel.
-
-```
-GET /api/spotlight
-```
-
-**Parameters:** None
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/spotlight"
-```
-
----
-
-## Trending
-
-Get currently trending anime.
-
-```
-GET /api/trending
-```
-
-**Parameters:** None
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/trending"
-```
-
----
-
-## Top 10
-
-Get top 10 ranked anime (today, week, month).
-
-```
-GET /api/top-ten
-```
-
-**Parameters:** None
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/top-ten"
-```
-
----
-
-## Most Popular
-
-Get most popular anime list.
-
-```
-GET /api/most-popular
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Default | Description |
-|-----------|------|----------|---------|-------------|
-| `page` | number | No | 1 | Page number |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/most-popular?page=1"
-```
-
----
-
-## New Release
-
-Get recently released episodes.
-
-```
-GET /api/new-release
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Default | Description |
-|-----------|------|----------|---------|-------------|
-| `page` | number | No | 1 | Page number |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/new-release"
-```
-
----
-
-## Newly Added
-
-Get newly added anime series.
-
-```
-GET /api/newly-added
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Default | Description |
-|-----------|------|----------|---------|-------------|
-| `page` | number | No | 1 | Page number |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/newly-added"
-```
-
----
-
-## Random
-
-Get random anime information.
-
-```
-GET /api/random
-```
-
-**Parameters:** None
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/random"
-```
-
----
-
-## Filter
-
-Filter anime by genre, type, status, season, and more.
-
-```
-GET /api/filter
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `keyword` | string | Yes | Search keyword (can be empty) |
-| `genre[]` | number | No | Genre IDs (multiple supported) |
-| `type[]` | number | No | Type IDs (multiple supported) |
-| `status[]` | number | No | Status IDs (multiple supported) |
-| `sort` | string | No | Sort order |
-| `season` | string | No | Season |
-| `page` | number | No | Page number |
-
-**Example:**
-
-```bash
-curl "https://anikototvapi.vercel.app/api/filter?keyword=&genre[]=1&genre[]=4"
-```
-
----
-
-## Suggestions
-
-Get anime suggestions by keyword.
-
-```
-GET /api/suggestions
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `keyword` | string | Yes | Search keyword |
-
-**Example:**
+**Request:**
```bash
curl "https://anikototvapi.vercel.app/api/suggestions?keyword=naruto"
```
+**Response:**
+
+```json
+{
+ "success": true,
+ "results": [
+ {
+ "slug": "road-of-naruto-ggjw8/ep-1",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/abfd676ad3a01f1e8860fecff9f5b8e0.jpg",
+ "title": "Road of Naruto",
+ "japaneseTitle": "Road of Naruto"
+ }
+ ]
+}
+```
+
---
-## Trending Sidebar
+## GET /spotlight
-Get trending sidebar widget data.
-
-```
-GET /api/trending-sidebar
-```
-
-**Parameters:** None
-
-**Example:**
+Get spotlight (featured) anime.
```bash
-curl "https://anikototvapi.vercel.app/api/trending-sidebar"
+curl "https://anikototvapi.vercel.app/api/spotlight"
```
+Returns array of spotlight anime with posters, descriptions, ratings, and quality info.
+
---
-## Seasons
+## GET /trending
-Get season information for an anime.
-
-```
-GET /api/seasons/:id
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | number | Yes | Anime ID (path parameter) |
-
-**Example:**
+Get currently trending anime.
```bash
-curl "https://anikototvapi.vercel.app/api/seasons/12345"
+curl "https://anikototvapi.vercel.app/api/trending"
+```
+
+**Response:**
+
+```json
+{
+ "success": true,
+ "results": [
+ {
+ "slug": "witch-hat-atelier-ikmut/ep-11",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/0412057393e8a45b3ba8b16874b6034d.jpg",
+ "title": "Witch Hat Atelier",
+ "japaneseTitle": "Tongari Boushi no Atelier",
+ "sub": 11,
+ "dub": 11,
+ "total": 13,
+ "type": "TV"
+ }
+ ]
+}
```
---
-## Watch Order
+## GET /top-ten
-Get recommended watch order for an anime.
-
-```
-GET /api/watch-order/:id
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `id` | number | Yes | Anime ID (path parameter) |
-
-**Example:**
+Get top 10 anime for today, this week, and this month.
```bash
-curl "https://anikototvapi.vercel.app/api/watch-order/12345"
+curl "https://anikototvapi.vercel.app/api/top-ten"
```
+Returns `{ today: [...], week: [...], month: [...] }`.
+
---
-## A-Z List
+## GET /schedule
-Get anime listing alphabetically.
-
-```
-GET /api/az-list/:letter
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `letter` | string | Yes | Letter or "other" for non-alpha titles |
-
-**Example:**
+Get anime schedule.
```bash
-curl "https://anikototvapi.vercel.app/api/az-list/a"
-curl "https://anikototvapi.vercel.app/api/az-list/other"
+curl "https://anikototvapi.vercel.app/api/schedule"
+```
+
+Returns array of scheduled anime with air times.
+
+---
+
+## GET /random
+
+Get a random anime.
+
+```bash
+curl "https://anikototvapi.vercel.app/api/random"
+```
+
+**Response:**
+
+```json
+{
+ "success": true,
+ "results": {
+ "title": "Massara",
+ "type": "ONA",
+ "genres": ["Slice of Life", "Music"]
+ }
+}
```
---
-## Genre
+## GET /new-release
+
+Get latest released episodes.
+
+```bash
+curl "https://anikototvapi.vercel.app/api/new-release"
+```
+
+Returns paginated list of recently released anime episodes.
+
+---
+
+## GET /most-popular
+
+Get most popular anime.
+
+```bash
+curl "https://anikototvapi.vercel.app/api/most-popular"
+```
+
+Returns paginated list with `totalPages` and `data` array.
+
+---
+
+## GET /genre/:name
Get anime by genre.
-```
-GET /api/genre/:name
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `name` | string | Yes | Genre slug |
-
-**Available Genres:**
-
-`action`, `adventure`, `cars`, `comedy`, `dementia`, `demons`, `drama`, `ecchi`, `fantasy`, `game`, `harem`, `historical`, `horror`, `isekai`, `josei`, `kids`, `magic`, `mahou-shoujo`, `martial-arts`, `mecha`, `military`, `music`, `mystery`, `parody`, `police`, `psychological`, `romance`, `samurai`, `school`, `sci-fi`, `seinen`, `shoujo`, `shoujo-ai`, `shounen`, `shounen-ai`, `slice-of-life`, `space`, `sports`, `super-power`, `supernatural`, `thriller`, `unknown`, `vampire`
-
-**Example:**
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `name` | string | Yes | Genre name (e.g., `action`, `romance`) |
+| `page` | number | No | Page number (default: 1) |
```bash
curl "https://anikototvapi.vercel.app/api/genre/action"
```
+Returns paginated anime list filtered by genre.
+
---
-## Type
+## GET /type/:name
-Get anime by type.
-
-```
-GET /api/type/:name
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `name` | string | Yes | Type slug |
-
-**Available Types:** `movie`, `music`, `ona`, `ova`, `special`, `tv`
-
-**Example:**
+Get anime by type (TV, OVA, Movie, ONA, etc).
```bash
curl "https://anikototvapi.vercel.app/api/type/tv"
@@ -834,24 +424,33 @@ curl "https://anikototvapi.vercel.app/api/type/tv"
---
-## Status
+## GET /status/:name
-Get anime by airing status.
-
-```
-GET /api/status/:name
-```
-
-**Parameters:**
-
-| Parameter | Type | Required | Description |
-|-----------|------|----------|-------------|
-| `name` | string | Yes | Status slug |
-
-**Available Statuses:** `currently-airing`, `finished-airing`, `not-yet-aired`
-
-**Example:**
+Get anime by status (airing, completed, upcoming).
```bash
-curl "https://anikototvapi.vercel.app/api/status/currently-airing"
+curl "https://anikototvapi.vercel.app/api/status/completed"
```
+
+---
+
+## GET /filter
+
+Filter anime with multiple parameters.
+
+| Param | Type | Required | Description |
+|-------|------|----------|-------------|
+| `keyword` | string | No | Search keyword (pass empty string if not searching) |
+| `genre[]` | number | No | Genre IDs |
+| `type` | string | No | TV, OVA, Movie, etc. |
+| `status` | string | No | aired, ongoing, upcoming |
+| `sort` | string | No | Most watched, score, name, etc. |
+| `page` | number | No | Page number |
+
+> **Important:** The `keyword` parameter must be present (even empty) or the site returns a 500 error.
+
+```bash
+curl "https://anikototvapi.vercel.app/api/filter?keyword=&genre[]=1"
+```
+
+Returns filtered and paginated anime list.
diff --git a/docs/examples.md b/docs/examples.md
index 2c572ff..f6fe86d 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -1,291 +1,365 @@
# Code Examples
-> Working examples in cURL, JavaScript, and Python.
+All examples are tested and working with the live API.
+
+---
## cURL
-### Get Homepage
+### Homepage
```bash
-curl https://anikototvapi.vercel.app/api
+curl "https://anikototvapi.vercel.app/api"
```
-### Search Anime
+### Search
```bash
-curl "https://anikototvapi.vercel.app/api/search?keyword=naruto&page=1"
+curl "https://anikototvapi.vercel.app/api/search?keyword=naruto"
```
-### Get Anime Info
+### Anime Info
```bash
-curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuden"
+curl "https://anikototvapi.vercel.app/api/info?id=road-of-naruto-ggjw8"
```
-### Get Episodes
+### Episodes
```bash
-curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
+curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8"
```
-### Get Servers
+### Servers
```bash
-curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25..."
+SERVER_IDS=$(curl -s "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])")
+curl "https://anikototvapi.vercel.app/api/servers?ids=$SERVER_IDS"
```
-### Get Stream URL
+### Stream URL
```bash
-curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9..."
+LINK_ID=$(curl -s "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])" | xargs -I{} curl -s "https://anikototvapi.vercel.app/api/servers?ids={}" | python3 -c "import sys,json; print(json.load(sys.stdin)['results'][0]['link_id'])")
+curl "https://anikototvapi.vercel.app/api/stream?id=$LINK_ID"
```
-### Get Schedule
+### Random Anime
+
+```bash
+curl "https://anikototvapi.vercel.app/api/random"
+```
+
+### Schedule
```bash
curl "https://anikototvapi.vercel.app/api/schedule"
-curl "https://anikototvapi.vercel.app/api/schedule?date=2026-06-08"
+```
+
+### Suggestions
+
+```bash
+curl "https://anikototvapi.vercel.app/api/suggestions?keyword=one+piece"
+```
+
+### Top 10
+
+```bash
+curl "https://anikototvapi.vercel.app/api/top-ten"
```
### Filter by Genre
-```bash
-curl "https://anikototvapi.vercel.app/api/filter?keyword=&genre[]=1&genre[]=4"
-```
-
-### Get Genre Anime
-
```bash
curl "https://anikototvapi.vercel.app/api/genre/action"
```
+### Filter with Parameters
+
+```bash
+curl "https://anikototvapi.vercel.app/api/filter?keyword=&genre[]=1&type=tv&status=aired"
+```
+
---
-## JavaScript (Fetch API)
+## JavaScript (Browser)
-### Get Homepage
+### Homepage
```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api");
-const data = await res.json();
-console.log(data.results);
+async function getHomepage() {
+ const res = await fetch('https://anikototvapi.vercel.app/api');
+ const data = await res.json();
+
+ console.log('Spotlights:', data.results.spotlights.length);
+ console.log('Trending:', data.results.trending.length);
+ console.log('Top Airing:', data.results.topAiring.length);
+ console.log('Genres:', data.results.genres.length);
+
+ return data.results;
+}
+
+getHomepage();
```
-### Search Anime
+### Search
```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/search?keyword=naruto");
-const data = await res.json();
-data.results.data.forEach(anime => {
- console.log(anime.title);
+async function searchAnime(keyword) {
+ const res = await fetch(`https://anikototvapi.vercel.app/api/search?keyword=${encodeURIComponent(keyword)}`);
+ const data = await res.json();
+
+ return data.results.data.map(anime => ({
+ title: anime.title,
+ slug: anime.slug,
+ sub: anime.sub,
+ dub: anime.dub,
+ type: anime.type
+ }));
+}
+
+searchAnime('naruto').then(results => {
+ results.forEach(a => console.log(`${a.title} (${a.type}) — Sub: ${a.sub}, Dub: ${a.dub}`));
});
```
-### Get Anime Info
+### Anime Info
```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/info?id=naruto-shippuden");
-const data = await res.json();
-console.log(data.results.title);
-console.log(data.results.synopsis);
-```
+async function getAnimeInfo(slug) {
+ const res = await fetch(`https://anikototvapi.vercel.app/api/info?id=${slug}`);
+ const data = await res.json();
+
+ const info = data.results;
+ console.log(`Title: ${info.title}`);
+ console.log(`Type: ${info.type}`);
+ console.log(`Status: ${info.status}`);
+ console.log(`Episodes: ${info.totalEpisodes || 'Unknown'}`);
+ console.log(`MAL ID: ${info.malId}`);
+
+ return info;
+}
-### Get Episodes
-
-```javascript
-const res = await fetch("https://anikototvapi.vercel.app/api/episodes/naruto-shippuden");
-const data = await res.json();
-data.results.episodes.forEach(ep => {
- console.log(`Episode ${ep.episode_no} - ID: ${ep.id}`);
-});
+getAnimeInfo('road-of-naruto-ggjw8');
```
### Full Streaming Flow
```javascript
-const BASE = "https://anikototvapi.vercel.app/api";
-
-async function getStream(slug, episodeNum) {
- // 1. Get episodes
- const epsRes = await fetch(`${BASE}/episodes/${slug}`);
- const eps = await epsRes.json();
- const ep = eps.results.episodes.find(e => e.episode_no === episodeNum);
+async function getStreamUrl(animeSlug) {
+ // Step 1: Get episodes
+ const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`);
+ const episodesData = await episodesRes.json();
+ const episodes = episodesData.results.episodes;
- // 2. Get servers
- const srvRes = await fetch(`${BASE}/servers?ids=${ep.server_ids}`);
- const srvs = await srvRes.json();
- const server = srvs.results[0];
+ if (!episodes || episodes.length === 0) {
+ throw new Error('No episodes found');
+ }
- // 3. Get stream
- const streamRes = await fetch(`${BASE}/stream?id=${server.link_id}`);
- const stream = await streamRes.json();
+ // Use first episode's server_ids
+ const serverIds = episodes[0].server_ids;
- return stream.results;
+ // Step 2: Get servers
+ const serversRes = await fetch(`https://anikototvapi.vercel.app/api/servers?ids=${serverIds}`);
+ const serversData = await serversRes.json();
+ const servers = serversData.results;
+
+ if (!servers || servers.length === 0) {
+ throw new Error('No servers found');
+ }
+
+ // Pick first server
+ const linkId = servers[0].link_id;
+
+ // Step 3: Get stream URL
+ const streamRes = await fetch(`https://anikototvapi.vercel.app/api/stream?id=${linkId}`);
+ const streamData = await streamRes.json();
+
+ return streamData.results.url;
}
// Usage
-getStream("naruto-shippuden", 1).then(stream => {
- console.log("URL:", stream.url);
- videoPlayer.src = stream.url;
-});
+getStreamUrl('road-of-naruto-ggjw8')
+ .then(url => {
+ console.log('Stream URL:', url);
+ // Use with video player
+ })
+ .catch(err => console.error('Error:', err.message));
```
-### Search with Suggestions
+### Random Anime
```javascript
-// Get autocomplete suggestions
-const res = await fetch("https://anikototvapi.vercel.app/api/search/suggest?keyword=dea");
-const suggestions = await res.json();
-suggestions.results.forEach(s => console.log(s.title));
-```
+async function getRandomAnime() {
+ const res = await fetch('https://anikototvapi.vercel.app/api/random');
+ const data = await res.json();
+
+ const anime = data.results;
+ console.log(`Random: ${anime.title} (${anime.type})`);
+ console.log('Genres:', anime.genres.join(', '));
+
+ return anime;
+}
----
-
-## Python (requests)
-
-### Get Homepage
-
-```python
-import requests
-
-r = requests.get("https://anikototvapi.vercel.app/api")
-data = r.json()
-print(data["results"])
-```
-
-### Search Anime
-
-```python
-import requests
-
-r = requests.get("https://anikototvapi.vercel.app/api/search", params={"keyword": "naruto"})
-data = r.json()
-for anime in data["results"]["data"]:
- print(anime["title"])
-```
-
-### Get Anime Info
-
-```python
-import requests
-
-r = requests.get("https://anikototvapi.vercel.app/api/info", params={"id": "naruto-shippuden"})
-data = r.json()
-print(data["results"]["title"])
-print(data["results"]["synopsis"])
-```
-
-### Get Episodes
-
-```python
-import requests
-
-r = requests.get("https://anikototvapi.vercel.app/api/episodes/naruto-shippuden")
-data = r.json()
-for ep in data["results"]["episodes"]:
- print(f"Episode {ep['episode_no']} - ID: {ep['id']}")
-```
-
-### Full Streaming Flow
-
-```python
-import requests
-
-BASE = "https://anikototvapi.vercel.app/api"
-
-def get_stream(slug, episode_num):
- # 1. Get episodes
- eps = requests.get(f"{BASE}/episodes/{slug}").json()
- ep = next(e for e in eps["results"]["episodes"] if e["episode_no"] == episode_num)
-
- # 2. Get servers
- srvs = requests.get(f"{BASE}/servers", params={"ids": ep["server_ids"]}).json()
- server = srvs["results"][0]
-
- # 3. Get stream
- stream = requests.get(f"{BASE}/stream", params={"id": server["link_id"]}).json()
-
- return stream["results"]
-
-# Usage
-stream = get_stream("naruto-shippuden", 1)
-print(f"URL: {stream['url']}")
+getRandomAnime();
```
### Filter by Genre
-```python
-import requests
+```javascript
+async function getAnimeByGenre(genre, page = 1) {
+ const res = await fetch(`https://anikototvapi.vercel.app/api/genre/${genre}?page=${page}`);
+ const data = await res.json();
+
+ return data.results.data.map(anime => ({
+ title: anime.title,
+ sub: anime.sub,
+ dub: anime.dub
+ }));
+}
-r = requests.get("https://anikototvapi.vercel.app/api/filter", params={
- "keyword": "",
- "genre[]": [1, 4] # Action, Comedy
-})
-data = r.json()
-```
-
-### Get Schedule
-
-```python
-import requests
-
-r = requests.get("https://anikototvapi.vercel.app/api/schedule")
-data = r.json()
+getAnimeByGenre('action').then(anime => {
+ console.log('Action Anime:');
+ anime.forEach(a => console.log(`- ${a.title} (Sub: ${a.sub}, Dub: ${a.dub})`));
+});
```
---
-## Node.js (axios)
+## Node.js (with axios)
-### Search Anime
+### Homepage
```javascript
-const axios = require("axios");
+const axios = require('axios');
-const { data } = await axios.get("https://anikototvapi.vercel.app/api/search", {
- params: { keyword: "naruto" }
+async function getHomepage() {
+ const { data } = await axios.get('https://anikototvapi.vercel.app/api');
+
+ console.log('Spotlights:', data.results.spotlights.length);
+ console.log('Trending:', data.results.trending.length);
+
+ return data.results;
+}
+
+getHomepage();
+```
+
+### Search
+
+```javascript
+const axios = require('axios');
+
+async function searchAnime(keyword) {
+ const { data } = await axios.get('https://anikototvapi.vercel.app/api/search', {
+ params: { keyword }
+ });
+
+ return data.results.data;
+}
+
+searchAnime('naruto').then(results => {
+ results.forEach(a => console.log(`${a.title} (${a.type})`));
});
-console.log(data.results.data);
```
### Full Streaming Flow
```javascript
-const axios = require("axios");
+const axios = require('axios');
-const BASE = "https://anikototvapi.vercel.app/api";
-
-async function getStream(slug, episodeNum) {
- const { data: eps } = await axios.get(`${BASE}/episodes/${slug}`);
- const ep = eps.results.episodes.find(e => e.episode_no === episodeNum);
+async function getStreamUrl(animeSlug) {
+ const BASE = 'https://anikototvapi.vercel.app/api';
- const { data: srvs } = await axios.get(`${BASE}/servers`, { params: { ids: ep.server_ids } });
- const server = srvs.results[0];
+ // Step 1: Get episodes
+ const { data: episodesData } = await axios.get(`${BASE}/episodes/${animeSlug}`);
+ const episodes = episodesData.results.episodes;
- const { data: stream } = await axios.get(`${BASE}/stream`, { params: { id: server.link_id } });
+ if (!episodes || episodes.length === 0) {
+ throw new Error('No episodes found');
+ }
- return stream.results;
+ const serverIds = episodes[0].server_ids;
+
+ // Step 2: Get servers
+ const { data: serversData } = await axios.get(`${BASE}/servers`, {
+ params: { ids: serverIds }
+ });
+ const servers = serversData.results;
+
+ if (!servers || servers.length === 0) {
+ throw new Error('No servers found');
+ }
+
+ const linkId = servers[0].link_id;
+
+ // Step 3: Get stream URL
+ const { data: streamData } = await axios.get(`${BASE}/stream`, {
+ params: { id: linkId }
+ });
+
+ return streamData.results.url;
}
+
+// Usage
+getStreamUrl('road-of-naruto-ggjw8')
+ .then(url => console.log('Stream URL:', url))
+ .catch(err => console.error('Error:', err.message));
```
----
+### Episode List
-## cURL (with jq)
+```javascript
+const axios = require('axios');
-### Pretty Print Homepage
+async function getEpisodeList(animeSlug) {
+ const { data } = await axios.get(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`);
+
+ const { animeId, totalEpisodes, episodes } = data.results;
+
+ console.log(`Anime ID: ${animeId}`);
+ console.log(`Total Episodes: ${totalEpisodes}`);
+ console.log(`Episodes available: ${episodes.length}`);
+
+ episodes.forEach(ep => {
+ console.log(` Episode ${ep.episode_no}: server_ids available = ${!!ep.server_ids}`);
+ });
+
+ return data.results;
+}
-```bash
-curl -s https://anikototvapi.vercel.app/api | jq '.results.trending[:3]'
+getEpisodeList('road-of-naruto-ggjw8');
```
-### Search and Extract Titles
+### Suggestions
-```bash
-curl -s "https://anikototvapi.vercel.app/api/search?keyword=naruto" | jq '.results.data[].title'
+```javascript
+const axios = require('axios');
+
+async function getSuggestions(keyword) {
+ const { data } = await axios.get('https://anikototvapi.vercel.app/api/suggestions', {
+ params: { keyword }
+ });
+
+ return data.results;
+}
+
+getSuggestions('one piece').then(suggestions => {
+ suggestions.forEach(a => console.log(`${a.title} (${a.slug})`));
+});
```
-### Get Stream URL Only
+### Schedule
-```bash
-curl -s "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9..." | jq -r '.results.url'
+```javascript
+const axios = require('axios');
+
+async function getSchedule() {
+ const { data } = await axios.get('https://anikototvapi.vercel.app/api/schedule');
+
+ console.log('Scheduled anime:', data.results.length);
+ return data.results;
+}
+
+getSchedule();
```
diff --git a/docs/index.md b/docs/index.md
index 60817dc..f96dc44 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -11,19 +11,53 @@ AniKotoAPI is a free, open-source REST API that provides anime data scraped from
## Quick Start
```bash
-# Get homepage data
+# Get homepage data (spotlight, trending, top-airing, genres)
curl https://anikototvapi.vercel.app/api
# Search for anime
curl "https://anikototvapi.vercel.app/api/search?keyword=naruto"
# Get anime info
-curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuden"
+curl "https://anikototvapi.vercel.app/api/info?id=road-of-naruto-ggjw8"
+```
+
+**Live Response — Homepage:**
+
+```json
+{
+ "success": true,
+ "results": {
+ "spotlights": [
+ {
+ "slug": "wistoria-wand-and-sword-season-2-dua04",
+ "poster": "https://cdn.anipixcdn.co/background/101f58336250ee0d_1779363645.webp",
+ "title": "Wistoria: Wand and Sword Season 2",
+ "japaneseTitle": "Tsue to Tsurugi no Wistoria Season 2",
+ "rating": "PG-13",
+ "quality": "HD"
+ }
+ ],
+ "trending": [
+ {
+ "slug": "witch-hat-atelier-ikmut/ep-11",
+ "poster": "https://cdn.anipixcdn.co/thumbnail/0412057393e8a45b3ba8b16874b6034d.jpg",
+ "title": "Witch Hat Atelier",
+ "japaneseTitle": "Tongari Boushi no Atelier",
+ "sub": 11,
+ "dub": 11,
+ "total": 13,
+ "type": "TV"
+ }
+ ],
+ "topAiring": [...],
+ "genres": ["Action", "Adventure", "Cars", "Comedy", ...]
+ }
+}
```
## Features
-- **24+ Endpoints** — Home, search, info, episodes, streaming, schedule, and more
+- **27 Endpoints** — Home, search, info, episodes, streaming, schedule, and more
- **No API Key** — Just make requests, no registration needed
- **In-Memory Cache** — 5-minute TTL for fast responses
- **CORS Enabled** — Access from any domain
@@ -31,10 +65,10 @@ curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuden"
## Documentation
-- [API Endpoints Reference](endpoints.md) — Complete endpoint documentation
-- [Streaming Flow Guide](streaming.md) — How to get stream URLs
-- [Code Examples](examples.md) — cURL, JavaScript, Python
-- [Architecture](architecture.md) — Project structure and design
+- [API Endpoints Reference](endpoints.md) — Complete endpoint documentation with real responses
+- [Streaming Flow Guide](streaming.md) — How to get stream URLs step by step
+- [Code Examples](examples.md) — cURL, JavaScript, Python (all tested and working)
+- [Architecture](architecture.md) — Project structure and design decisions
## Response Format
diff --git a/docs/streaming.md b/docs/streaming.md
index 9a6bcbd..38ee9b6 100644
--- a/docs/streaming.md
+++ b/docs/streaming.md
@@ -1,23 +1,25 @@
# Streaming Flow Guide
-> How to get streaming URLs from AniKotoAPI.
+This guide explains how to get streaming URLs from AniKotoAPI in 3 steps.
## Overview
-The streaming flow involves 3 steps:
+```
+Step 1: Get Episodes → /api/episodes/:slug
+Step 2: Get Servers → /api/servers?ids={server_ids}
+Step 3: Get Stream URL → /api/stream?id={link_id}
+```
-```
-1. Get episodes → /api/episodes/{slug}
-2. Get servers → /api/servers?ids={server_ids}
-3. Get stream URL → /api/stream?id={link_id}
-```
+---
## Step 1: Get Episodes
-First, get the episode list for an anime. This returns episode data including `server_ids` needed for the next step.
+Each anime has multiple episodes. Fetch the episode list with the anime slug.
+
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
+curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8"
```
**Response:**
@@ -26,33 +28,37 @@ curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
{
"success": true,
"results": {
- "animeId": 12345,
- "slug": "naruto-shippuden",
- "totalEpisodes": 500,
+ "animeId": "7174",
+ "totalEpisodes": 1,
"episodes": [
{
"id": "110289",
"episode_no": 1,
- "server_ids": "SlNVT25JaFlCMnZOeXZ2aG5t...",
+ "slug": "1",
+ "title": "",
+ "active": true,
+ "href": "#",
+ "server_ids": "SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0",
"timestamp": "1729249503",
- "mal_id": "1735"
+ "mal_id": "53236"
}
]
}
}
```
-**Key fields:**
-- `server_ids` — Base64-encoded string needed for the servers endpoint
-- `timestamp` — Used for the mapper API
-- `mal_id` — MyAnimeList ID for the anime
+> **Key field:** `server_ids` — Pass this to the next step.
+
+---
## Step 2: Get Servers
-Use the `server_ids` from step 1 to get available streaming servers.
+Each episode has multiple servers. Use the `server_ids` from Step 1.
+
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5t..."
+curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0"
```
**Response:**
@@ -64,42 +70,35 @@ curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5t..
{
"type": "sub",
"ep_id": "110289",
- "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
- "cmid": "animixplay-xxxxx",
- "sv_id": "323",
+ "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ",
+ "cmid": "animixplay-fqs",
+ "sv_id": "1",
"name": "HD-1"
},
{
"type": "sub",
"ep_id": "110289",
- "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
- "cmid": "animixplay-xxxxx",
- "sv_id": "e54",
+ "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOEZ4cFNpMDdQbnV1S3dNdklpRkhWbzRsVmgxSGx4YWx3LytPcnZXU0RCVHc9PQ",
+ "cmid": "animixplay-fqs",
+ "sv_id": "2",
"name": "Vidstream-2"
- },
- {
- "type": "dub",
- "ep_id": "110289",
- "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
- "cmid": "animixplay-xxxxx",
- "sv_id": "a41",
- "name": "VidCloud-1"
}
]
}
```
-**Key fields:**
-- `type` — "sub" or "dub"
-- `link_id` — ID needed for the stream endpoint
-- `name` — Server name (HD-1, Vidstream-2, etc.)
+> **Key field:** `link_id` — Pick a server and pass its `link_id` to the next step.
+
+---
## Step 3: Get Stream URL
-Use the `link_id` from step 2 to get the actual streaming URL.
+Get the actual streaming URL using the `link_id` from Step 2.
+
+**Request:**
```bash
-curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr..."
+curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ"
```
**Response:**
@@ -108,7 +107,7 @@ curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr
{
"success": true,
"results": {
- "linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
+ "linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ",
"url": "https://megaplay.buzz/stream/s-5/94736/sub",
"skipData": {
"intro": [0, 0],
@@ -118,96 +117,137 @@ curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr
}
```
-**Key fields:**
-- `url` — Direct streaming URL (m3u8 or mp4)
-- `skipData` — Intro/outro timestamps for skipping
+> **Done!** Use `results.url` in your video player.
-## Complete Example (JavaScript)
+---
+
+## JavaScript Example
```javascript
-const BASE = "https://anikototvapi.vercel.app/api";
-
-async function getStreamUrl(animeSlug, episodeNumber) {
+async function getStreamUrl(animeSlug) {
// Step 1: Get episodes
- const epsRes = await fetch(`${BASE}/episodes/${animeSlug}`);
- const epsData = await epsRes.json();
- const episode = epsData.results.episodes.find(
- ep => ep.episode_no === episodeNumber
- );
+ const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`);
+ const episodesData = await episodesRes.json();
+ const episodes = episodesData.results.episodes;
- if (!episode) throw new Error("Episode not found");
+ if (!episodes || episodes.length === 0) {
+ throw new Error('No episodes found');
+ }
+
+ // Use first episode's server_ids
+ const serverIds = episodes[0].server_ids;
// Step 2: Get servers
- const srvRes = await fetch(`${BASE}/servers?ids=${episode.server_ids}`);
- const srvData = await srvRes.json();
- const server = srvData.results.find(s => s.type === "sub") || srvData.results[0];
+ const serversRes = await fetch(`https://anikototvapi.vercel.app/api/servers?ids=${serverIds}`);
+ const serversData = await serversRes.json();
+ const servers = serversData.results;
- if (!server) throw new Error("No servers available");
+ if (!servers || servers.length === 0) {
+ throw new Error('No servers found');
+ }
+
+ // Pick first server (HD-1)
+ const linkId = servers[0].link_id;
// Step 3: Get stream URL
- const streamRes = await fetch(`${BASE}/stream?id=${server.link_id}`);
+ const streamRes = await fetch(`https://anikototvapi.vercel.app/api/stream?id=${linkId}`);
const streamData = await streamRes.json();
- return streamData.results;
+ return streamData.results.url; // "https://megaplay.buzz/stream/s-5/94736/sub"
}
// Usage
-getStreamUrl("naruto-shippuden", 1)
- .then(stream => {
- console.log("Stream URL:", stream.url);
- console.log("Skip intro at:", stream.skipData.intro[0]);
- });
+getStreamUrl('road-of-naruto-ggjw8')
+ .then(url => console.log('Stream URL:', url))
+ .catch(err => console.error('Error:', err));
```
-## Complete Example (Python)
+---
+
+## Python Example
```python
import requests
-BASE = "https://anikototvapi.vercel.app/api"
-
-def get_stream_url(anime_slug, episode_number):
+def get_stream_url(anime_slug):
+ base = "https://anikototvapi.vercel.app/api"
+
# Step 1: Get episodes
- eps_res = requests.get(f"{BASE}/episodes/{anime_slug}")
- eps_data = eps_res.json()
- episode = next(
- ep for ep in eps_data["results"]["episodes"]
- if ep["episode_no"] == episode_number
- )
+ episodes_res = requests.get(f"{base}/episodes/{anime_slug}")
+ episodes_data = episodes_res.json()
+ episodes = episodes_data['results']['episodes']
+
+ if not episodes:
+ raise Exception("No episodes found")
+
+ server_ids = episodes[0]['server_ids']
# Step 2: Get servers
- srv_res = requests.get(f"{BASE}/servers", params={"ids": episode["server_ids"]})
- srv_data = srv_res.json()
- server = next(
- (s for s in srv_data["results"] if s["type"] == "sub"),
- srv_data["results"][0]
- )
+ servers_res = requests.get(f"{base}/servers", params={"ids": server_ids})
+ servers_data = servers_res.json()
+ servers = servers_data['results']
+
+ if not servers:
+ raise Exception("No servers found")
+
+ link_id = servers[0]['link_id']
# Step 3: Get stream URL
- stream_res = requests.get(f"{BASE}/stream", params={"id": server["link_id"]})
+ stream_res = requests.get(f"{base}/stream", params={"id": link_id})
stream_data = stream_res.json()
- return stream_data["results"]
+ return stream_data['results']['url']
# Usage
-stream = get_stream_url("naruto-shippuden", 1)
-print(f"Stream URL: {stream['url']}")
-print(f"Skip intro at: {stream['skipData']['intro'][0]}")
+url = get_stream_url('road-of-naruto-ggjw8')
+print(f"Stream URL: {url}")
```
-## Alternative: Mapper Servers
+---
-For additional streaming sources, use the mapper API with `malId`, `slug`, and `timestamp` from the episodes response.
+## Player Integration
-```bash
-curl "https://anikototvapi.vercel.app/api/mapper-servers?malId=1735&slug=naruto-shippuden×tamp=1729249503"
+### HLS.js (HLS Streams)
+
+```html
+
+
+
+
```
-This returns alternative providers like VidStreaming, Gogoanime, etc.
+### Plyr (MP4 Streams)
-## Notes
+```html
+
+
+
-- The `url` in stream response is typically an m3u8 playlist or direct mp4 link
-- `skipData` contains intro/outro timestamps in seconds
-- Some servers may require specific headers or referrers to work
-- The mapper API is external and may not always be available
+
+```
+
+---
+
+## Troubleshooting
+
+| Issue | Solution |
+|-------|----------|
+| "No episodes found" | Check the anime slug is correct (use `/api/search` first) |
+| "No servers found" | The `server_ids` may be invalid, try another episode |
+| Stream URL 403 | Some servers require specific referrer headers |
+| CORS error | Use a proxy or access from server-side |