mirror of
https://github.com/Shineii86/AniKotoAPI.git
synced 2026-10-22 10:55:10 +00:00
docs: complete API documentation folder
docs/index.md — Overview, quick start, features docs/endpoints.md — Full API reference (27 endpoints) docs/streaming.md — Streaming flow guide (3-step) docs/examples.md — cURL, JavaScript, Python, Node.js examples docs/architecture.md — Project structure, tech stack, design Also fixes streaming endpoints: - episodeList: Parse AJAX JSON, extract server_ids/timestamp/mal_id - streamInfo: Parse server list HTML into structured objects - streamInfo: Parse stream URL from JSON response
This commit is contained in:
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [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/architecture.md` — Project structure, tech stack, design decisions
|
||||
|
||||
### Fixed
|
||||
- `episodeList.extractor.js` — Parse AJAX JSON response, extract `server_ids`, `timestamp`, `mal_id`
|
||||
- `streamInfo.extractor.js` — Parse server list HTML into structured objects
|
||||
- `streamInfo.extractor.js` — Parse stream URL from JSON response properly
|
||||
- Added cheerio import to streamInfo extractor for HTML parsing
|
||||
|
||||
## [1.7.1] - 2026-06-08
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
# Architecture
|
||||
|
||||
> Project structure, tech stack, and design decisions.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Runtime | Node.js |
|
||||
| Framework | Express.js |
|
||||
| Scraper | 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
|
||||
```
|
||||
|
||||
## 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
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
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..."
|
||||
```
|
||||
|
||||
**Characteristics:**
|
||||
- Stored in a JavaScript `Map`
|
||||
- TTL: 5 minutes (300,000 ms)
|
||||
- Reset on server restart (serverless = every cold start)
|
||||
- Key format: `{type}_{identifier}`
|
||||
|
||||
## Source Site Structure
|
||||
|
||||
The API scrapes data from `anikototv.to`:
|
||||
|
||||
| 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 |
|
||||
|
||||
**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
|
||||
}
|
||||
```
|
||||
|
||||
## Vercel Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "server.js",
|
||||
"use": "@vercel/node"
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"src": "/api/(.*)",
|
||||
"dest": "server.js",
|
||||
"headers": { "Access-Control-Allow-Origin": "*" }
|
||||
},
|
||||
{
|
||||
"src": "/(.*)",
|
||||
"dest": "server.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All errors follow this format:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Error description"
|
||||
}
|
||||
```
|
||||
|
||||
Common errors:
|
||||
|
||||
| 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 |
|
||||
@@ -0,0 +1,857 @@
|
||||
# API Endpoints Reference
|
||||
|
||||
> Complete documentation for all AniKotoAPI endpoints.
|
||||
|
||||
**Base URL:** `https://anikototvapi.vercel.app/api`
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [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()
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"spotlight": [...],
|
||||
"trending": [...],
|
||||
"popular": [...],
|
||||
"topAiring": [...],
|
||||
"genres": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Search
|
||||
|
||||
Search for anime by keyword with pagination.
|
||||
|
||||
```
|
||||
GET /api/search
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
|-----------|------|----------|---------|-------------|
|
||||
| `keyword` | string | Yes | — | Search query |
|
||||
| `page` | number | No | 1 | Page number |
|
||||
|
||||
**Example:**
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"totalPages": 10,
|
||||
"data": [
|
||||
{
|
||||
"title": "Naruto",
|
||||
"id": "naruto-xxxxx",
|
||||
"slug": "naruto-xxxxx/ep-1",
|
||||
"image": "https://...",
|
||||
"type": "TV",
|
||||
"genres": ["Action", "Adventure"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Search Suggestions
|
||||
|
||||
Get autocomplete suggestions for search queries.
|
||||
|
||||
```
|
||||
GET /api/search/suggest
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `keyword` | string | Yes | Partial search query |
|
||||
|
||||
**Example:**
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"title": "Naruto: Shippuuden",
|
||||
"japaneseTitle": "ナルト- 疾風伝",
|
||||
"image": "https://...",
|
||||
"synopsis": "...",
|
||||
"type": "TV",
|
||||
"status": "Finished Airing",
|
||||
"totalEpisodes": 500,
|
||||
"genres": ["Action", "Adventure"],
|
||||
"malId": 1735,
|
||||
"relations": [...],
|
||||
"recommendations": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Episodes
|
||||
|
||||
Get the episode list for an anime.
|
||||
|
||||
```
|
||||
GET /api/episodes/:id
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `id` | string | Yes | Anime slug (path parameter) |
|
||||
|
||||
**Example:**
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"animeId": 12345,
|
||||
"slug": "naruto-shippuden",
|
||||
"totalEpisodes": 500,
|
||||
"episodes": [
|
||||
{
|
||||
"id": "110289",
|
||||
"episode_no": 1,
|
||||
"slug": "1",
|
||||
"title": "",
|
||||
"active": true,
|
||||
"href": "#",
|
||||
"server_ids": "SlNVT25...",
|
||||
"timestamp": "1729249503",
|
||||
"mal_id": "1735"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Watch Page
|
||||
|
||||
Get watch page data for a specific episode.
|
||||
|
||||
```
|
||||
GET /api/watch
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `id` | string | Yes | Anime slug |
|
||||
| `ep` | number | No | Episode number |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/watch?id=naruto-shippuden&ep=1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stream Info
|
||||
|
||||
Get the streaming URL and metadata for an episode server.
|
||||
|
||||
```
|
||||
GET /api/stream
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `id` | string | Yes | Server link ID (from servers response) |
|
||||
|
||||
**Example:**
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"linkId": "MTF1dkFtaW9...",
|
||||
"url": "https://megaplay.buzz/stream/s-5/94736/sub",
|
||||
"skipData": {
|
||||
"intro": [0, 0],
|
||||
"outro": [0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mapper Servers
|
||||
|
||||
Get alternative streaming servers from the nekostream mapper API.
|
||||
|
||||
```
|
||||
GET /api/mapper-servers
|
||||
```
|
||||
|
||||
**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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/suggestions?keyword=naruto"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Trending Sidebar
|
||||
|
||||
Get trending sidebar widget data.
|
||||
|
||||
```
|
||||
GET /api/trending-sidebar
|
||||
```
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/trending-sidebar"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Seasons
|
||||
|
||||
Get season information for an anime.
|
||||
|
||||
```
|
||||
GET /api/seasons/:id
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `id` | number | Yes | Anime ID (path parameter) |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/seasons/12345"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Watch Order
|
||||
|
||||
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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/watch-order/12345"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## A-Z List
|
||||
|
||||
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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/az-list/a"
|
||||
curl "https://anikototvapi.vercel.app/api/az-list/other"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Genre
|
||||
|
||||
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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/genre/action"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Type
|
||||
|
||||
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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/type/tv"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
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:**
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/status/currently-airing"
|
||||
```
|
||||
@@ -0,0 +1,291 @@
|
||||
# Code Examples
|
||||
|
||||
> Working examples in cURL, JavaScript, and Python.
|
||||
|
||||
## cURL
|
||||
|
||||
### Get Homepage
|
||||
|
||||
```bash
|
||||
curl https://anikototvapi.vercel.app/api
|
||||
```
|
||||
|
||||
### Search Anime
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/search?keyword=naruto&page=1"
|
||||
```
|
||||
|
||||
### Get Anime Info
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuden"
|
||||
```
|
||||
|
||||
### Get Episodes
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
|
||||
```
|
||||
|
||||
### Get Servers
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25..."
|
||||
```
|
||||
|
||||
### Get Stream URL
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9..."
|
||||
```
|
||||
|
||||
### Get Schedule
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/schedule"
|
||||
curl "https://anikototvapi.vercel.app/api/schedule?date=2026-06-08"
|
||||
```
|
||||
|
||||
### 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"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JavaScript (Fetch API)
|
||||
|
||||
### Get Homepage
|
||||
|
||||
```javascript
|
||||
const res = await fetch("https://anikototvapi.vercel.app/api");
|
||||
const data = await res.json();
|
||||
console.log(data.results);
|
||||
```
|
||||
|
||||
### Search Anime
|
||||
|
||||
```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);
|
||||
});
|
||||
```
|
||||
|
||||
### Get 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);
|
||||
```
|
||||
|
||||
### 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}`);
|
||||
});
|
||||
```
|
||||
|
||||
### 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);
|
||||
|
||||
// 2. Get servers
|
||||
const srvRes = await fetch(`${BASE}/servers?ids=${ep.server_ids}`);
|
||||
const srvs = await srvRes.json();
|
||||
const server = srvs.results[0];
|
||||
|
||||
// 3. Get stream
|
||||
const streamRes = await fetch(`${BASE}/stream?id=${server.link_id}`);
|
||||
const stream = await streamRes.json();
|
||||
|
||||
return stream.results;
|
||||
}
|
||||
|
||||
// Usage
|
||||
getStream("naruto-shippuden", 1).then(stream => {
|
||||
console.log("URL:", stream.url);
|
||||
videoPlayer.src = stream.url;
|
||||
});
|
||||
```
|
||||
|
||||
### Search with Suggestions
|
||||
|
||||
```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));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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']}")
|
||||
```
|
||||
|
||||
### Filter by Genre
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
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()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Node.js (axios)
|
||||
|
||||
### Search Anime
|
||||
|
||||
```javascript
|
||||
const axios = require("axios");
|
||||
|
||||
const { data } = await axios.get("https://anikototvapi.vercel.app/api/search", {
|
||||
params: { keyword: "naruto" }
|
||||
});
|
||||
console.log(data.results.data);
|
||||
```
|
||||
|
||||
### Full Streaming Flow
|
||||
|
||||
```javascript
|
||||
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);
|
||||
|
||||
const { data: srvs } = await axios.get(`${BASE}/servers`, { params: { ids: ep.server_ids } });
|
||||
const server = srvs.results[0];
|
||||
|
||||
const { data: stream } = await axios.get(`${BASE}/stream`, { params: { id: server.link_id } });
|
||||
|
||||
return stream.results;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## cURL (with jq)
|
||||
|
||||
### Pretty Print Homepage
|
||||
|
||||
```bash
|
||||
curl -s https://anikototvapi.vercel.app/api | jq '.results.trending[:3]'
|
||||
```
|
||||
|
||||
### Search and Extract Titles
|
||||
|
||||
```bash
|
||||
curl -s "https://anikototvapi.vercel.app/api/search?keyword=naruto" | jq '.results.data[].title'
|
||||
```
|
||||
|
||||
### Get Stream URL Only
|
||||
|
||||
```bash
|
||||
curl -s "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9..." | jq -r '.results.url'
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
# AniKotoAPI Documentation
|
||||
|
||||
> Free REST API for anime data. Browse, search, stream — no API key required.
|
||||
|
||||
## Overview
|
||||
|
||||
AniKotoAPI is a free, open-source REST API that provides anime data scraped from [anikototv.to](https://anikototv.to). It's built with Node.js, Express, and Cheerio, and deployed on Vercel.
|
||||
|
||||
**Base URL:** `https://anikototvapi.vercel.app/api`
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Get homepage data
|
||||
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"
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- **24+ 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
|
||||
- **JSON Responses** — Standardized `{success, results}` format
|
||||
|
||||
## 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
|
||||
|
||||
## Response Format
|
||||
|
||||
All endpoints return JSON in this format:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
Error responses:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Error description"
|
||||
}
|
||||
```
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
There are no explicit rate limits, but the API uses a 5-minute in-memory cache. Repeated requests for the same data will be served from cache.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This API is for **educational purposes only**. It scrapes publicly available data from anikototv.to. We are not affiliated with or endorsed by AniKoto. All content belongs to its respective owners.
|
||||
@@ -0,0 +1,213 @@
|
||||
# Streaming Flow Guide
|
||||
|
||||
> How to get streaming URLs from AniKotoAPI.
|
||||
|
||||
## Overview
|
||||
|
||||
The streaming flow involves 3 steps:
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/episodes/naruto-shippuden"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"animeId": 12345,
|
||||
"slug": "naruto-shippuden",
|
||||
"totalEpisodes": 500,
|
||||
"episodes": [
|
||||
{
|
||||
"id": "110289",
|
||||
"episode_no": 1,
|
||||
"server_ids": "SlNVT25JaFlCMnZOeXZ2aG5t...",
|
||||
"timestamp": "1729249503",
|
||||
"mal_id": "1735"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**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
|
||||
|
||||
## Step 2: Get Servers
|
||||
|
||||
Use the `server_ids` from step 1 to get available streaming servers.
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5t..."
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": [
|
||||
{
|
||||
"type": "sub",
|
||||
"ep_id": "110289",
|
||||
"link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
|
||||
"cmid": "animixplay-xxxxx",
|
||||
"sv_id": "323",
|
||||
"name": "HD-1"
|
||||
},
|
||||
{
|
||||
"type": "sub",
|
||||
"ep_id": "110289",
|
||||
"link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
|
||||
"cmid": "animixplay-xxxxx",
|
||||
"sv_id": "e54",
|
||||
"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.)
|
||||
|
||||
## Step 3: Get Stream URL
|
||||
|
||||
Use the `link_id` from step 2 to get the actual streaming URL.
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr..."
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"results": {
|
||||
"linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...",
|
||||
"url": "https://megaplay.buzz/stream/s-5/94736/sub",
|
||||
"skipData": {
|
||||
"intro": [0, 0],
|
||||
"outro": [0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key fields:**
|
||||
- `url` — Direct streaming URL (m3u8 or mp4)
|
||||
- `skipData` — Intro/outro timestamps for skipping
|
||||
|
||||
## Complete Example (JavaScript)
|
||||
|
||||
```javascript
|
||||
const BASE = "https://anikototvapi.vercel.app/api";
|
||||
|
||||
async function getStreamUrl(animeSlug, episodeNumber) {
|
||||
// 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
|
||||
);
|
||||
|
||||
if (!episode) throw new Error("Episode not found");
|
||||
|
||||
// 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];
|
||||
|
||||
if (!server) throw new Error("No servers available");
|
||||
|
||||
// Step 3: Get stream URL
|
||||
const streamRes = await fetch(`${BASE}/stream?id=${server.link_id}`);
|
||||
const streamData = await streamRes.json();
|
||||
|
||||
return streamData.results;
|
||||
}
|
||||
|
||||
// Usage
|
||||
getStreamUrl("naruto-shippuden", 1)
|
||||
.then(stream => {
|
||||
console.log("Stream URL:", stream.url);
|
||||
console.log("Skip intro at:", stream.skipData.intro[0]);
|
||||
});
|
||||
```
|
||||
|
||||
## Complete Example (Python)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
BASE = "https://anikototvapi.vercel.app/api"
|
||||
|
||||
def get_stream_url(anime_slug, episode_number):
|
||||
# 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
|
||||
)
|
||||
|
||||
# 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]
|
||||
)
|
||||
|
||||
# Step 3: Get stream URL
|
||||
stream_res = requests.get(f"{BASE}/stream", params={"id": server["link_id"]})
|
||||
stream_data = stream_res.json()
|
||||
|
||||
return stream_data["results"]
|
||||
|
||||
# Usage
|
||||
stream = get_stream_url("naruto-shippuden", 1)
|
||||
print(f"Stream URL: {stream['url']}")
|
||||
print(f"Skip intro at: {stream['skipData']['intro'][0]}")
|
||||
```
|
||||
|
||||
## Alternative: Mapper Servers
|
||||
|
||||
For additional streaming sources, use the mapper API with `malId`, `slug`, and `timestamp` from the episodes response.
|
||||
|
||||
```bash
|
||||
curl "https://anikototvapi.vercel.app/api/mapper-servers?malId=1735&slug=naruto-shippuden×tamp=1729249503"
|
||||
```
|
||||
|
||||
This returns alternative providers like VidStreaming, Gogoanime, etc.
|
||||
|
||||
## Notes
|
||||
|
||||
- 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
|
||||
Reference in New Issue
Block a user