mirror of
https://github.com/Shineii86/AniKotoAPI.git
synced 2026-10-22 02:45:10 +00:00
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
6.9 KiB
6.9 KiB
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:
// 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):
{
action: 1,
adventure: 2,
comedy: 4,
demons: 5,
drama: 8,
fantasy: 10,
isekai: 19,
romance: 22,
shounen: 27,
supernatural: 37
}
Type IDs:
{
movie: 1,
music: 2,
ona: 3,
ova: 4,
special: 5,
tv: 6
}
Status IDs:
{
"currently-airing": 1,
"finished-airing": 2,
"not-yet-aired": 3
}
Vercel Configuration
{
"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:
{
"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 |