diff --git a/CHANGELOG.md b/CHANGELOG.md index d023ad4..83f393e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ 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). +## [2.0.2] - 2026-07-05 + +### Fixed +- **Documentation**: Fixed streaming flow guide — `/api/episodes/:slug` corrected to `/api/episodes/:animeId` +- **Documentation**: Fixed all examples using `road-of-naruto-ggjw8` slug for episodes to use `958` animeId +- **Documentation**: Fixed JavaScript/Node.js streaming examples to use `animeId` parameter instead of `animeSlug` +- **Documentation**: Updated cURL examples to use correct animeId (958) for episodes endpoint +- **Documentation**: Updated architecture.md streaming flow diagram to reflect correct endpoint + ## [2.0.1] - 2026-07-05 ### Fixed diff --git a/README.md b/README.md index 7e79aa0..e5f4812 100644 --- a/README.md +++ b/README.md @@ -438,14 +438,14 @@ https://anikototvapi.vercel.app/api To get a stream URL, follow these 3 steps: ```bash -# Step 1: Get episodes (returns server_ids) -curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" +# Step 1: Get episodes by animeId (returns server_ids) +curl "https://anikototvapi.vercel.app/api/episodes/958" # Step 2: Get servers (pass server_ids from Step 1) -curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOe..." +curl "https://anikototvapi.vercel.app/api/servers?ids=dXNCT3hNQzk3THhSTW8ySnM5..." # Step 3: Get stream URL (pass link_id from Step 2) -curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbz..." +curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr..." ``` ### Dub & Sub Switch @@ -796,17 +796,17 @@ console.log(resp.data); | Parameter | Type | Mandatory | Default | Description | | :-------: | :--: | :-------: | :-----: | :---------: | -| `id` | `string` | Yes ✔️ | — | Anime slug | +| `id` | `string` | Yes ✔️ | — | Anime slug or animeId | #### Example of request ```bash -curl "https://anikototvapi.vercel.app/api/episodes/one-piece-odmau" +curl "https://anikototvapi.vercel.app/api/episodes/958" ``` ```javascript import axios from "axios"; -const resp = await axios.get("https://anikototvapi.vercel.app/api/episodes/one-piece-odmau"); +const resp = await axios.get("https://anikototvapi.vercel.app/api/episodes/958"); console.log(resp.data); ``` @@ -914,13 +914,13 @@ console.log(resp.data); #### Example of request ```bash -curl "https://anikototvapi.vercel.app/api/servers?ids={episodeIds}" +curl "https://anikototvapi.vercel.app/api/servers?ids={server_ids}" ``` ```javascript import axios from "axios"; const resp = await axios.get("https://anikototvapi.vercel.app/api/servers", { - params: { ids: "yourEpisodeIds" } + params: { ids: "yourServerIds" } }); console.log(resp.data); ``` @@ -1016,13 +1016,13 @@ Server list for an episode — returns available streaming servers with their na | `ids` | `string` | **required** | `server_ids` from `/episodes` response (base64-encoded) | ```bash -curl "https://anikototvapi.vercel.app/api/servers?ids={episodeIds}" +curl "https://anikototvapi.vercel.app/api/servers?ids={server_ids}" ``` ```javascript import axios from "axios"; const resp = await axios.get("https://anikototvapi.vercel.app/api/servers", { - params: { ids: "yourEpisodeIds" } + params: { ids: "yourServerIds" } }); console.log(resp.data); ``` @@ -2172,7 +2172,7 @@ CMD ["node", "server.js"] |:---|:---|:---| | ❌ `npm install` fails | Node.js version too old | Upgrade to Node.js 20+ (`node -v`) | | ❌ 500 error on filter | Missing `keyword` param | Add `?keyword=` (even empty) to filter requests | -| ❌ Empty episodes array | AJAX not loaded | Use `/api/episodes/:slug` which fetches via AJAX | +| ❌ Empty episodes array | Wrong parameter | Use `/api/episodes/:animeId` with numeric animeId (e.g., 958) | | ❌ CORS errors | Frontend domain blocked | CORS is `*` — check browser extension | | ❌ 404 on API routes | Wrong URL format | Use `/api/` prefix, not just `/` | | ❌ Deploy fails on Vercel | Build error | Check `node server.js` locally first | @@ -2204,7 +2204,7 @@ Use /api/search?keyword=your+search. Results include title, poster,
📺 How do I get episode lists?
-Use /api/episodes/:slug where :slug is the anime URL slug (e.g., one-piece-odmau). This fetches episode data via AJAX for accuracy. The response includes animeId, totalEpisodes, and episodes array. +Use /api/episodes/:id where :id is the anime slug or animeId (e.g., 958 for Naruto). The response includes animeId, totalEpisodes, and episodes array with server_ids for each episode.
diff --git a/docs/architecture.md b/docs/architecture.md index 15a6b5a..dcf11cd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -140,7 +140,7 @@ Client Response ## Streaming Flow ``` -/api/episodes/:slug +/api/episodes/:animeId ↓ Returns: server_ids, animeId, totalEpisodes ↓ diff --git a/docs/endpoints.md b/docs/endpoints.md index 2daaf0c..6c5fcc0 100644 --- a/docs/endpoints.md +++ b/docs/endpoints.md @@ -169,12 +169,12 @@ Get episode list for an anime. | Param | Type | Required | Description | |-------|------|----------|-------------| -| `id` | string | Yes | Anime slug | +| `id` | string | Yes | Anime slug or animeId | **Request:** ```bash -curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" +curl "https://anikototvapi.vercel.app/api/episodes/958" ``` **Response:** @@ -183,19 +183,20 @@ curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" { "success": true, "results": { - "animeId": "7174", - "totalEpisodes": 1, + "animeId": 958, + "slug": "958", + "totalEpisodes": 220, "episodes": [ { - "id": "110289", + "id": "16638", "episode_no": 1, "slug": "1", "title": "", "active": true, "href": "#", - "server_ids": "SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0", - "timestamp": "1729249503", - "mal_id": "53236" + "server_ids": "dXNCT3hNQzk3THhSTW8ySnM5...", + "timestamp": "1729197616", + "mal_id": "20" } ] } diff --git a/docs/examples.md b/docs/examples.md index bd66a5f..0d1b841 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -21,26 +21,26 @@ curl "https://anikototvapi.vercel.app/api/search?keyword=naruto" ### Anime Info ```bash -curl "https://anikototvapi.vercel.app/api/info?id=road-of-naruto-ggjw8" +curl "https://anikototvapi.vercel.app/api/info?id=naruto-eybxz" ``` ### Episodes ```bash -curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" +curl "https://anikototvapi.vercel.app/api/episodes/958" ``` ### Servers ```bash -SERVER_IDS=$(curl -s "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])") +SERVER_IDS=$(curl -s "https://anikototvapi.vercel.app/api/episodes/958" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])") curl "https://anikototvapi.vercel.app/api/servers?ids=$SERVER_IDS" ``` ### Stream URL ```bash -LINK_ID=$(curl -s "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])" | xargs -I{} curl -s "https://anikototvapi.vercel.app/api/servers?ids={}" | python3 -c "import sys,json; print(json.load(sys.stdin)['results'][0]['link_id'])") +LINK_ID=$(curl -s "https://anikototvapi.vercel.app/api/episodes/958" | python3 -c "import sys,json; print(json.load(sys.stdin)['results']['episodes'][0]['server_ids'])" | xargs -I{} curl -s "https://anikototvapi.vercel.app/api/servers?ids={}" | python3 -c "import sys,json; print(json.load(sys.stdin)['results'][0]['link_id'])") curl "https://anikototvapi.vercel.app/api/stream?id=$LINK_ID" ``` @@ -140,15 +140,15 @@ async function getAnimeInfo(slug) { return info; } -getAnimeInfo('road-of-naruto-ggjw8'); +getAnimeInfo('naruto-eybxz'); ``` ### Full Streaming Flow ```javascript -async function getStreamUrl(animeSlug) { +async function getStreamUrl(animeId) { // Step 1: Get episodes - const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`); + const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeId}`); const episodesData = await episodesRes.json(); const episodes = episodesData.results.episodes; @@ -179,7 +179,7 @@ async function getStreamUrl(animeSlug) { } // Usage -getStreamUrl('road-of-naruto-ggjw8') +getStreamUrl(958) .then(url => { console.log('Stream URL:', url); // Use with video player @@ -268,11 +268,11 @@ searchAnime('naruto').then(results => { ```javascript const axios = require('axios'); -async function getStreamUrl(animeSlug) { +async function getStreamUrl(animeId) { const BASE = 'https://anikototvapi.vercel.app/api'; // Step 1: Get episodes - const { data: episodesData } = await axios.get(`${BASE}/episodes/${animeSlug}`); + const { data: episodesData } = await axios.get(`${BASE}/episodes/${animeId}`); const episodes = episodesData.results.episodes; if (!episodes || episodes.length === 0) { @@ -302,7 +302,7 @@ async function getStreamUrl(animeSlug) { } // Usage -getStreamUrl('road-of-naruto-ggjw8') +getStreamUrl(958) .then(url => console.log('Stream URL:', url)) .catch(err => console.error('Error:', err.message)); ``` @@ -312,12 +312,12 @@ getStreamUrl('road-of-naruto-ggjw8') ```javascript const axios = require('axios'); -async function getEpisodeList(animeSlug) { - const { data } = await axios.get(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`); +async function getEpisodeList(animeId) { + const { data } = await axios.get(`https://anikototvapi.vercel.app/api/episodes/${animeId}`); - const { animeId, totalEpisodes, episodes } = data.results; + const { animeId: id, totalEpisodes, episodes } = data.results; - console.log(`Anime ID: ${animeId}`); + console.log(`Anime ID: ${id}`); console.log(`Total Episodes: ${totalEpisodes}`); console.log(`Episodes available: ${episodes.length}`); @@ -328,7 +328,7 @@ async function getEpisodeList(animeSlug) { return data.results; } -getEpisodeList('road-of-naruto-ggjw8'); +getEpisodeList(958); ``` ### Suggestions diff --git a/docs/index.md b/docs/index.md index dd3044c..e855dc2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,7 +18,7 @@ curl https://anikototvapi.vercel.app/api curl "https://anikototvapi.vercel.app/api/search?keyword=naruto" # Get anime info -curl "https://anikototvapi.vercel.app/api/info?id=road-of-naruto-ggjw8" +curl "https://anikototvapi.vercel.app/api/info?id=naruto-eybxz" ``` **Live Response — Homepage:** diff --git a/docs/streaming.md b/docs/streaming.md index 3cb08fc..33e5bc0 100644 --- a/docs/streaming.md +++ b/docs/streaming.md @@ -5,7 +5,7 @@ This guide explains how to get streaming URLs from AniKotoAPI in 3 steps. ## Overview ``` -Step 1: Get Episodes → /api/episodes/:slug +Step 1: Get Episodes → /api/episodes/:id Step 2: Get Servers → /api/servers?ids={server_ids} Step 3: Get Stream URL → /api/stream?id={link_id} ``` @@ -14,12 +14,12 @@ Step 3: Get Stream URL → /api/stream?id={link_id} ## Step 1: Get Episodes -Each anime has multiple episodes. Fetch the episode list with the anime slug. +Each anime has multiple episodes. Fetch the episode list with the anime slug or animeId. **Request:** ```bash -curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" +curl "https://anikototvapi.vercel.app/api/episodes/958" ``` **Response:** @@ -28,19 +28,20 @@ curl "https://anikototvapi.vercel.app/api/episodes/road-of-naruto-ggjw8" { "success": true, "results": { - "animeId": "7174", - "totalEpisodes": 1, + "animeId": 958, + "slug": "958", + "totalEpisodes": 220, "episodes": [ { - "id": "110289", + "id": "16638", "episode_no": 1, "slug": "1", "title": "", "active": true, "href": "#", - "server_ids": "SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0", - "timestamp": "1729249503", - "mal_id": "53236" + "server_ids": "dXNCT3hNQzk3THhSTW8ySnM5...", + "timestamp": "1729197616", + "mal_id": "20" } ] } @@ -58,7 +59,7 @@ Each episode has multiple servers. Use the `server_ids` from Step 1. **Request:** ```bash -curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5takIxL2EybGl4TzJoNE1pN3JXdFNlODVocWtTckt1SFR0YUxrNzNhanQ2MEJoVG9UUEZNeWJOMm1uUThpYjNxejhhUEZWMitnNFFtTUNMYjBTc1FJZjZNNFZPNm5LMlVuTnpOU25ScUI1dHVGczM0UzluZ2xITG5qbExabnBDdGphY0VRPT0" +curl "https://anikototvapi.vercel.app/api/servers?ids=dXNCT3hNQzk3THhSTW8ySnM5..." ``` **Response:** @@ -69,19 +70,19 @@ curl "https://anikototvapi.vercel.app/api/servers?ids=SlNVT25JaFlCMnZOeXZ2aG5tak "results": [ { "type": "sub", - "ep_id": "110289", - "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ", - "cmid": "animixplay-fqs", - "sv_id": "1", - "name": "HD-1" + "ep_id": "16638", + "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...", + "cmid": "animixplay-fqsqfvdf4u", + "sv_id": "8e4", + "name": "VidPlay-1" }, { "type": "sub", - "ep_id": "110289", - "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOEZ4cFNpMDdQbnV1S3dNdklpRkhWbzRsVmgxSGx4YWx3LytPcnZXU0RCVHc9PQ", - "cmid": "animixplay-fqs", - "sv_id": "2", - "name": "Vidstream-2" + "ep_id": "16638", + "link_id": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...", + "cmid": "animixplay-fqsqfvdf4u", + "sv_id": "323", + "name": "HD-1" } ] } @@ -98,7 +99,7 @@ Get the actual streaming URL using the `link_id` from Step 2. **Request:** ```bash -curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ" +curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr..." ``` **Response:** @@ -107,8 +108,8 @@ curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr { "success": true, "results": { - "linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZrOWdjeldjOERLaWNMMXFNbVB3WUJqOHZGS2FSWVgvbVJraVpIV1dQRjRoN01hOFUvYmxsWXFYNGtiR0h5OWdGQWc9PQ", - "url": "https://megaplay.buzz/stream/s-5/94736/sub", + "linkId": "MTF1dkFtaW9BRTZPbzJJRElFZUZr...", + "url": "https://vidtube.site/stream/aVlsNDR3MnRLbWRvQUFBbWJUNERLQT09/sub", "skipData": { "intro": [0, 0], "outro": [0, 0] @@ -124,9 +125,9 @@ curl "https://anikototvapi.vercel.app/api/stream?id=MTF1dkFtaW9BRTZPbzJJRElFZUZr ## JavaScript Example ```javascript -async function getStreamUrl(animeSlug) { +async function getStreamUrl(animeId) { // Step 1: Get episodes - const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeSlug}`); + const episodesRes = await fetch(`https://anikototvapi.vercel.app/api/episodes/${animeId}`); const episodesData = await episodesRes.json(); const episodes = episodesData.results.episodes; @@ -146,18 +147,18 @@ async function getStreamUrl(animeSlug) { throw new Error('No servers found'); } - // Pick first server (HD-1) + // Pick first server (VidPlay-1) const linkId = servers[0].link_id; // Step 3: Get stream URL const streamRes = await fetch(`https://anikototvapi.vercel.app/api/stream?id=${linkId}`); const streamData = await streamRes.json(); - return streamData.results.url; // "https://megaplay.buzz/stream/s-5/94736/sub" + return streamData.results.url; // "https://vidtube.site/stream/..." } // Usage -getStreamUrl('road-of-naruto-ggjw8') +getStreamUrl(958) .then(url => console.log('Stream URL:', url)) .catch(err => console.error('Error:', err)); ``` @@ -169,11 +170,11 @@ getStreamUrl('road-of-naruto-ggjw8') ```python import requests -def get_stream_url(anime_slug): +def get_stream_url(anime_id): base = "https://anikototvapi.vercel.app/api" # Step 1: Get episodes - episodes_res = requests.get(f"{base}/episodes/{anime_slug}") + episodes_res = requests.get(f"{base}/episodes/{anime_id}") episodes_data = episodes_res.json() episodes = episodes_data['results']['episodes'] @@ -199,7 +200,7 @@ def get_stream_url(anime_slug): return stream_data['results']['url'] # Usage -url = get_stream_url('road-of-naruto-ggjw8') +url = get_stream_url(958) print(f"Stream URL: {url}") ``` @@ -247,7 +248,7 @@ player.source = { | Issue | Solution | |-------|----------| -| "No episodes found" | Check the anime slug is correct (use `/api/search` first) | +| "No episodes found" | Check the anime ID is correct (use `/api/search` first to find slug, then use animeId) | | "No servers found" | The `server_ids` may be invalid, try another episode | | Stream URL 403 | Some servers require specific referrer headers | | CORS error | Use a proxy or access from server-side | @@ -261,7 +262,7 @@ For a simpler approach, use the `/watch` endpoint which returns episode data, se **Request:** ```bash -curl "https://anikototvapi.vercel.app/api/watch?slug=road-of-naruto-ggjw8&ep=1" +curl "https://anikototvapi.vercel.app/api/watch?slug=naruto-eybxz&ep=1" ``` **Response includes:**