Files
AniKotoAPI/docs/architecture.md
T
Shinei Nouzen 403b205625 docs: update all documentation with pagination and fixes
- Update CHANGELOG.md with pagination metadata and bug fixes
- Update README.md with pagination documentation and project structure
- Update docs/endpoints.md with pagination section
- Update docs/index.md with pagination feature
- Update docs/architecture.md with pagination helper
2026-07-04 16:25:48 +05:30

8.3 KiB

Architecture

Project Structure

AniKotoAPI/
├── server.js                          # Express entry point, port 4444
├── package.json                       # name: "AniKotoAPI"
├── vercel.json                        # Routes /api/* and /* to server.js
├── .env                               # Configuration (see .env.example)
│
├── 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 (/, /tos, /privacy, /api)
│   ├── og-image.svg                   # SVG Open Graph image
│   ├── privacy.html                   # Privacy policy (served at /privacy)
│   └── tos.html                       # Terms of service (served at /tos)
│
├── docs/                              # API documentation
│   ├── index.md                       # Overview, quick start, features
│   ├── endpoints.md                   # Full API reference (33 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 + OpenAPI spec
│   │   └── category.route.js          # genre/:name, type/:name, status/:name
│   │
│   ├── controllers/
│   │   ├── homeInfo.controller.js         # Homepage data
│   │   ├── search.controller.js       # Anime search
│   │   ├── animeInfo.controller.js         # Anime info
│   │   ├── episodeList.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 + Latest Updated
│   │   ├── popular.controller.js  # Most popular
│   │   ├── category.controller.js        # Genre filter
│   │   ├── category.controller.js         # Type filter
│   │   ├── category.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 + Latest Updated
│   │   ├── 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
│   │   ├── seasons.extractor.js       # Seasons/OVAs/movies
│   │   ├── watchOrder.extractor.js    # Watch order
│   │   └── download.extractor.js      # Download links
│   │
│   └── helper/
│       ├── cache.helper.js            # LRU cache with configurable TTL
│       ├── mirror.helper.js           # Multi-mirror fallback (5 domains)
│       ├── extractPages.helper.js     # Page fetching with mirror fallback
│       └── pagination.helper.js       # Pagination metadata generator
│
│   └── middleware/
│       └── creatorInfo.js             # Creator attribution injection
│
├── test.js                            # Test suite (27 tests)
├── agents/                            # AI agent prompts (6 agents)
└── CHANGELOG.md                       # Version history

Tech Stack

Component Technology
Runtime Node.js
Framework Express.js
Scraping Cheerio + Axios
Deployment Vercel (Serverless)
Caching LRU cache with configurable TTL
Compression gzip (level 6, 1024 byte threshold)
Mirror Fallback 5 mirror domains with health checks
Middleware Creator info attribution injection
Static Files Express static middleware

Request Flow

Client Request
    ↓
Vercel Routes (/api/* → server.js)
    ↓
Express Middleware
    ↓
├── CORS
├── Security Headers
├── Compression (gzip)
├── Rate Limiting
├── Creator Info Injection
    ↓
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 with Creator Attribution
    ↓
Client Response

Streaming Flow

/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)

Caching Strategy

  • 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

Anti-Bot Protection

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.

Solution: The API properly passes data-ids to the server list endpoint and parses the JSON response to extract the required attributes.

Vercel Configuration

{
  "version": 2,
  "builds": [
    {
      "src": "server.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "server.js"
    },
    {
      "src": "/(.*)",
      "dest": "server.js"
    }
  ]
}
  • /api/* routes to Express for API handling
  • /* routes to Express for static file serving
  • Static files served from process.cwd() (Vercel serverless compatible)

Environment Variables

Variable Description
ANIKOTO_CHECK_SERVER_TS Anti-bot check timestamp from source site

Response Format

All API responses follow this structure:

{
  "success": true,
  "results": { ... }
}

Error responses:

{
  "success": false,
  "message": "Error description"
}

Dependencies

Package Version Purpose
express ^4.21.0 Web framework
cheerio ^1.0.0-rc.12 HTML parsing
axios ^1.8.0 HTTP requests
cors ^2.8.5 CORS headers
cookie-parser ^1.4.7 Cookie parsing
dotenv ^16.4.0 Environment variables