mirror of
https://github.com/Shineii86/AniKotoAPI.git
synced 2026-10-22 02:45:10 +00:00
v1.9.0: Full diagnostic sweep - 42 issues fixed
Critical fixes (7): - Added global Express error handler (returns JSON instead of HTML) - Removed caching from random endpoint (defeated purpose) - Renamed share.jpg to share.png (MIME type mismatch) - Fixed OG image dimensions (630 → 601) - Fixed manifest.json icon sizes (192x192 → 512x512) - Fixed implicit global event variable in console - Added 9 missing endpoints to docs/endpoints.md High fixes (12): - Imported version from package.json (no hardcoded drift) - Added dynamic endpoint count in stats - Added input sanitization for mapper API (SSRF prevention) - Added homepage caching (reduced 5 duplicate HTTP requests) - Added rate limiting (100 requests/minute per IP) - Added rel="noopener noreferrer" to all target="_blank" links - Fixed trailing slash inconsistency in console - Added noindex meta to 404.html - Fixed docs/architecture.md controller filenames and dependency versions - Fixed README.md dependency versions - Added 12 missing endpoint tests Medium fixes (22): - Added escapeHtml helper for error messages - Consistent favicon across all pages - Added meta descriptions to privacy.html and tos.html - Added OG/Twitter meta tags to privacy.html and tos.html - Added aria-label to playground inputs - Added aria-hidden to decorative SVGs - Synced Twitter description with OG description - Fixed robots.txt to disallow /api - Added PWA fields to manifest.json - Removed 5 unused imports - Removed unused cookie-parser dependency - Fixed inconsistent error handling in extractors - Fixed resolvedSlug returning numeric ID - Added /watch endpoint to streaming docs - Improved test assertions and status code validation - Deleted orphaned og-image.svg and logo.png Low fixes (11): - Removed redundant try/catch from extractPages - Added max size eviction to cache - Added cache key sorting in filter controller - Added author meta tag - Fixed favicon.svg font Version bumped to 1.9.0
This commit is contained in:
+55
-53
@@ -9,16 +9,16 @@
|
||||
<meta property="og:title" content="AniKotoAPI — Free Anime Data API" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://anikototvapi.vercel.app" />
|
||||
<meta property="og:image" content="https://anikototvapi.vercel.app/share.jpg" />
|
||||
<meta property="og:image" content="https://anikototvapi.vercel.app/share.png" />
|
||||
<meta property="og:description" content="Free REST API for anime data. Browse, search, stream episodes. 30+ endpoints, no API key required." />
|
||||
<meta property="og:site_name" content="AniKotoAPI" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
|
||||
<!-- ──────────────── Image Optimization ──────────────── -->
|
||||
<meta property="og:image:secure_url" content="https://anikototvapi.vercel.app/share.jpg" />
|
||||
<meta property="og:image:secure_url" content="https://anikototvapi.vercel.app/share.png" />
|
||||
<meta property="og:image:type" content="image/jpeg" />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta property="og:image:height" content="601" />
|
||||
<meta property="og:image:alt" content="AniKotoAPI - Free Anime Data REST API" />
|
||||
|
||||
<!-- ──────────────── Twitter Card Tags ──────────────── -->
|
||||
@@ -26,13 +26,14 @@
|
||||
<meta name="twitter:site" content="@Shineii86" />
|
||||
<meta name="twitter:creator" content="@Shineii86" />
|
||||
<meta name="twitter:title" content="AniKotoAPI — Free Anime Data API" />
|
||||
<meta name="twitter:description" content="Free REST API for anime data. Browse, search, stream episodes. 30+ endpoints." />
|
||||
<meta name="twitter:image" content="https://anikototvapi.vercel.app/share.jpg" />
|
||||
<meta name="twitter:description" content="Free REST API for anime data. Browse, search, stream episodes. 30+ endpoints, no API key required." />
|
||||
<meta name="twitter:image" content="https://anikototvapi.vercel.app/share.png" />
|
||||
<meta name="twitter:image:alt" content="AniKotoAPI - Free Anime Data REST API" />
|
||||
<meta name="twitter:domain" content="anikototvapi.vercel.app" />
|
||||
|
||||
<!-- ──────────────── Generic Meta ──────────────── -->
|
||||
<meta name="description" content="Free REST API for anime data. Browse, search, stream episodes. 30+ endpoints, no API key required. Built with Node.js, Express, Cheerio." />
|
||||
<meta name="author" content="Shinei Nouzen" />
|
||||
<meta name="keywords" content="anime api, free api, rest api, anime data, streaming, episode servers, nodejs, express, anime database, anime search" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta name="theme-color" content="#0A0A12" />
|
||||
@@ -277,7 +278,7 @@
|
||||
"name": "AniKotoAPI",
|
||||
"description": "Free REST API for anime data. Browse, search, stream episodes. 30+ endpoints, no API key required.",
|
||||
"url": "https://anikototvapi.vercel.app",
|
||||
"image": "https://anikototvapi.vercel.app/share.jpg",
|
||||
"image": "https://anikototvapi.vercel.app/share.png",
|
||||
"documentation": "https://github.com/Shineii86/AniKotoAPI",
|
||||
"provider": {
|
||||
"@type": "Organization",
|
||||
@@ -306,14 +307,14 @@
|
||||
<header id="header">
|
||||
<div class="header-inner">
|
||||
<a href="/" class="logo">
|
||||
<svg viewBox="0 0 32 32" fill="none"><circle cx="16" cy="16" r="14" stroke="url(#g1)" stroke-width="2"/><path d="M10 20c0-4 3-7 6-7s6 3 6 7" stroke="url(#g1)" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="12" r="2" fill="var(--purple)"/><circle cx="20" cy="12" r="2" fill="var(--pink)"/><defs><linearGradient id="g1" x1="0" y1="0" x2="32" y2="32"><stop stop-color="var(--purple)"/><stop offset="1" stop-color="var(--pink)"/></linearGradient></defs></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 32 32" fill="none"><circle cx="16" cy="16" r="14" stroke="url(#g1)" stroke-width="2"/><path d="M10 20c0-4 3-7 6-7s6 3 6 7" stroke="url(#g1)" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="12" r="2" fill="var(--purple)"/><circle cx="20" cy="12" r="2" fill="var(--pink)"/><defs><linearGradient id="g1" x1="0" y1="0" x2="32" y2="32"><stop stop-color="var(--purple)"/><stop offset="1" stop-color="var(--pink)"/></linearGradient></defs></svg>
|
||||
<span class="logo-text"><span>AniKoto</span>API</span>
|
||||
</a>
|
||||
<nav>
|
||||
<a href="#features">Features</a>
|
||||
<a href="#endpoints">Endpoints</a>
|
||||
<a href="#playground">Playground</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank">GitHub</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<a href="https://anikototvapi.vercel.app/api" target="_blank" class="nav-cta">Open API</a>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -326,11 +327,11 @@
|
||||
<p class="hero-sub">Browse, search, and stream anime data from AniKoto. Real-time scraping with 30+ endpoints, in-memory caching, and zero configuration.</p>
|
||||
<div class="hero-actions">
|
||||
<a href="#playground" class="btn btn-primary">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
Try It Live
|
||||
</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank" class="btn btn-ghost">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
Star on GitHub
|
||||
</a>
|
||||
</div>
|
||||
@@ -351,13 +352,13 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="console-output" id="consoleOutput"><span style="color:var(--text3)">// Click "Run" to see the response</span></div>
|
||||
</div>
|
||||
<div class="console-actions">
|
||||
<button class="console-btn active" onclick="setEndpoint('home')">Home</button>
|
||||
<button class="console-btn" onclick="setEndpoint('search')">Search</button>
|
||||
<button class="console-btn" onclick="setEndpoint('stream')">Stream</button>
|
||||
<button class="console-btn" onclick="setEndpoint('random')">Random</button>
|
||||
<button class="console-btn" onclick="setEndpoint('schedule')">Schedule</button>
|
||||
<button class="console-btn active" onclick="setEndpoint('home', event)">Home</button>
|
||||
<button class="console-btn" onclick="setEndpoint('search', event)">Search</button>
|
||||
<button class="console-btn" onclick="setEndpoint('stream', event)">Stream</button>
|
||||
<button class="console-btn" onclick="setEndpoint('random', event)">Random</button>
|
||||
<button class="console-btn" onclick="setEndpoint('schedule', event)">Schedule</button>
|
||||
<button class="console-send" onclick="runConsole()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px;display:inline"><polygon points="5 3 19 12 5 21 5 3"/></svg> Run
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px;display:inline"><polygon points="5 3 19 12 5 21 5 3"/></svg> Run
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -378,19 +379,19 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<!-- Marquee -->
|
||||
<div class="marquee">
|
||||
<div class="marquee-track">
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 5-min cache TTL</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg> Zero config</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> No auth needed</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8m-4-4v4"/></svg> Vercel deployed</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg> Cheerio scraper</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg> REST JSON</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg> CORS enabled</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg> Open source</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 5-min cache TTL</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg> Zero config</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> No auth needed</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8m-4-4v4"/></svg> Vercel deployed</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg> Cheerio scraper</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg> REST JSON</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg> CORS enabled</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg> Open source</div>
|
||||
<!-- duplicate for seamless loop -->
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 5-min cache TTL</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg> Zero config</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> No auth needed</div>
|
||||
<div class="marquee-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8m-4-4v4"/></svg> Vercel deployed</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 5-min cache TTL</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg> Zero config</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> No auth needed</div>
|
||||
<div class="marquee-item"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8m-4-4v4"/></svg> Vercel deployed</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -399,7 +400,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="container">
|
||||
<div class="reveal">
|
||||
<div class="section-label">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
||||
Features
|
||||
</div>
|
||||
<h2 class="section-title">Built for developers</h2>
|
||||
@@ -408,42 +409,42 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="features-grid">
|
||||
<div class="feature-card reveal">
|
||||
<div class="feature-icon fi-purple">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Full-text Search</div>
|
||||
<div class="feature-desc">Search by keyword, genre, type, status. Get autocomplete suggestions and paginated results.</div>
|
||||
</div>
|
||||
<div class="feature-card reveal reveal-delay-1">
|
||||
<div class="feature-icon fi-pink">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="2.18"/><path d="M7 2v20M17 2v20M2 12h20M2 7h5M2 17h5M17 7h5M17 17h5"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="2.18"/><path d="M7 2v20M17 2v20M2 12h20M2 7h5M2 17h5M17 7h5M17 17h5"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Episode Streaming</div>
|
||||
<div class="feature-desc">Retrieve streaming servers, source links, and m3u8 URLs for any episode via AJAX endpoints.</div>
|
||||
</div>
|
||||
<div class="feature-card reveal reveal-delay-2">
|
||||
<div class="feature-icon fi-green">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Rich Metadata</div>
|
||||
<div class="feature-desc">Synopsis, MAL score, genres, characters, relations, recommendations, and more.</div>
|
||||
</div>
|
||||
<div class="feature-card reveal">
|
||||
<div class="feature-icon fi-cyan">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Schedule & Calendar</div>
|
||||
<div class="feature-desc">View what's airing today or fetch the full weekly broadcast schedule.</div>
|
||||
</div>
|
||||
<div class="feature-card reveal reveal-delay-1">
|
||||
<div class="feature-icon fi-amber">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Advanced Filters</div>
|
||||
<div class="feature-desc">Filter by genre, type, status, season, sort order. Multi-select support.</div>
|
||||
</div>
|
||||
<div class="feature-card reveal reveal-delay-2">
|
||||
<div class="feature-icon fi-indigo">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||||
</div>
|
||||
<div class="feature-title">Fast & Cached</div>
|
||||
<div class="feature-desc">In-memory cache with 5-minute TTL for snappy responses and reduced scraping overhead.</div>
|
||||
@@ -457,7 +458,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="container">
|
||||
<div class="reveal">
|
||||
<div class="section-label">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
|
||||
API Reference
|
||||
</div>
|
||||
<h2 class="section-title">Endpoints</h2>
|
||||
@@ -476,7 +477,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="container">
|
||||
<div class="reveal">
|
||||
<div class="section-label">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
Interactive
|
||||
</div>
|
||||
<h2 class="section-title">Playground</h2>
|
||||
@@ -487,12 +488,12 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<!-- Search -->
|
||||
<div class="playground-card reveal">
|
||||
<div class="playground-header">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
|
||||
<h3>Search Anime</h3>
|
||||
</div>
|
||||
<div class="playground-body">
|
||||
<div class="playground-inputs">
|
||||
<input id="pgSearch" type="text" placeholder="e.g. naruto, one piece" />
|
||||
<input id="pgSearch" type="text" placeholder="e.g. naruto, one piece" aria-label="Search anime" />
|
||||
<button class="btn btn-primary" onclick="pgRun('search')" style="padding:10px 20px">Search</button>
|
||||
</div>
|
||||
<div class="playground-output" id="pgSearchOut"></div>
|
||||
@@ -501,7 +502,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<!-- Stream -->
|
||||
<div class="playground-card reveal reveal-delay-1">
|
||||
<div class="playground-header">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
<h3>Stream Servers</h3>
|
||||
</div>
|
||||
<div class="playground-body">
|
||||
@@ -515,7 +516,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<!-- Random -->
|
||||
<div class="playground-card reveal reveal-delay-2">
|
||||
<div class="playground-header">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.27 6.96L12 12.01l8.73-5.05M12 22.08V12"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.27 6.96L12 12.01l8.73-5.05M12 22.08V12"/></svg>
|
||||
<h3>Random Anime</h3>
|
||||
</div>
|
||||
<div class="playground-body">
|
||||
@@ -528,12 +529,12 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<!-- Schedule -->
|
||||
<div class="playground-card reveal reveal-delay-3">
|
||||
<div class="playground-header">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
<h3>Schedule</h3>
|
||||
</div>
|
||||
<div class="playground-body">
|
||||
<div class="playground-inputs">
|
||||
<input id="pgSchedule" type="date" />
|
||||
<input id="pgSchedule" type="date" aria-label="Schedule date" />
|
||||
<button class="btn btn-primary" onclick="pgRun('schedule')" style="padding:10px 20px">Get Schedule</button>
|
||||
</div>
|
||||
<div class="playground-output" id="pgScheduleOut"></div>
|
||||
@@ -551,11 +552,11 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<p class="cta-desc">Free, open source, no API key required. Deploy your own instance or use ours.</p>
|
||||
<div class="cta-actions">
|
||||
<a href="https://anikototvapi.vercel.app/api" target="_blank" class="btn btn-primary">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
||||
View API
|
||||
</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank" class="btn btn-ghost">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" style="width:16px;height:16px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor" style="width:16px;height:16px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
Source Code
|
||||
</a>
|
||||
</div>
|
||||
@@ -569,7 +570,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<div class="footer-grid">
|
||||
<div class="footer-brand">
|
||||
<a href="/" class="logo">
|
||||
<svg viewBox="0 0 32 32" fill="none" width="24" height="24"><circle cx="16" cy="16" r="14" stroke="url(#g2)" stroke-width="2"/><path d="M10 20c0-4 3-7 6-7s6 3 6 7" stroke="url(#g2)" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="12" r="2" fill="var(--purple)"/><circle cx="20" cy="12" r="2" fill="var(--pink)"/><defs><linearGradient id="g2" x1="0" y1="0" x2="32" y2="32"><stop stop-color="var(--purple)"/><stop offset="1" stop-color="var(--pink)"/></linearGradient></defs></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 32 32" fill="none" width="24" height="24"><circle cx="16" cy="16" r="14" stroke="url(#g2)" stroke-width="2"/><path d="M10 20c0-4 3-7 6-7s6 3 6 7" stroke="url(#g2)" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="12" r="2" fill="var(--purple)"/><circle cx="20" cy="12" r="2" fill="var(--pink)"/><defs><linearGradient id="g2" x1="0" y1="0" x2="32" y2="32"><stop stop-color="var(--purple)"/><stop offset="1" stop-color="var(--pink)"/></linearGradient></defs></svg>
|
||||
<span class="logo-text"><span>AniKoto</span>API</span>
|
||||
</a>
|
||||
<p>Free REST API for anime data. Browse, search, and stream from AniKoto. Built with Node.js and deployed on Vercel.</p>
|
||||
@@ -584,10 +585,10 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>Resources</h4>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank">GitHub</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI#readme" target="_blank">Documentation</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI/blob/main/CHANGELOG.md" target="_blank">Changelog</a>
|
||||
<a href="/api" target="_blank">API Status</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI#readme" target="_blank" rel="noopener noreferrer">Documentation</a>
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">Changelog</a>
|
||||
<a href="/api" target="_blank" rel="noopener noreferrer">API Status</a>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>Legal</h4>
|
||||
@@ -599,7 +600,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
<span>© 2026 AniKotoAPI. Educational use only.</span>
|
||||
<div class="footer-social">
|
||||
<a href="https://github.com/Shineii86/AniKotoAPI" target="_blank" aria-label="GitHub">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -685,7 +686,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
random: { url: '/random', label: 'Random' },
|
||||
schedule: { url: '/schedule', label: 'Schedule' }
|
||||
};
|
||||
function setEndpoint(key) {
|
||||
function setEndpoint(key, event) {
|
||||
const ep = endpoints[key];
|
||||
document.getElementById('consoleInput').value = `// ${ep.label}\nfetch("${BASE}${ep.url}")\n .then(r => r.json())\n .then(data => console.log(data));`;
|
||||
document.querySelectorAll('.console-btn').forEach(b => b.classList.remove('active'));
|
||||
@@ -702,6 +703,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
const data = await res.json();
|
||||
out.innerHTML = syntaxHighlight(JSON.stringify(data, null, 2));
|
||||
out.scrollTop = out.scrollHeight;
|
||||
function escapeHtml(s) { return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); }
|
||||
} catch (e) {
|
||||
out.innerHTML = `<span style="color:var(--red)">Error: ${e.message}</span>`;
|
||||
}
|
||||
@@ -762,7 +764,7 @@ fetch("https://anikototvapi.vercel.app/api")
|
||||
const btn = document.createElement('button');
|
||||
btn.className = `explorer-nav-btn ${i===0?'active':''}`;
|
||||
btn.dataset.id = ep.id;
|
||||
btn.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>${ep.title}`;
|
||||
btn.innerHTML = `<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>${ep.title}`;
|
||||
btn.onclick = () => {
|
||||
navEl.querySelectorAll('.explorer-nav-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
|
||||
Reference in New Issue
Block a user