Toonstream API
A comprehensive Vercel serverless API for scraping anime and cartoon content from ToonStream. This API provides structured data for series, movies, episodes, categories, cast members, and search functionality.
- Homepage Scraping - Latest series, movies, and trending content
- Series Details - Complete series information with flexible season/episode queries
- Episode Details - Episode metadata with streaming server sources
- Movies - Individual movie details and movie listings
- Search - Full-text search across all content
- Categories - Browse by networks, genres, and languages
- Cast Pages - Content filtered by cast members
- Alphabetical Browsing - Browse content by letter (A-Z)
- Server Filtering - Get specific streaming servers or all available sources
- Pagination Support - Navigate through paginated content
- CORS Enabled - Ready for frontend integration
- Installation
- Deployment
- API Endpoints
- Query Parameters
- Response Format
- Examples
- Error Handling
- Contributing
- License
- Clone the repository
git clone https://github.com/senpaiorbit/toon_stream_api.git
cd toonstream-api- Install dependencies
npm install- Configure base URL
Create src/baseurl.txt and add the base URL:
https://toonstream.one
- Test locally
vercel dev- Install Vercel CLI
npm install -g vercel- Login to Vercel
vercel login- Deploy
vercel- Production deployment
vercel --prodYour API will be live at: https://your-project.vercel.app
Scrapes the homepage with latest content, featured series, and trending items.
Endpoint:
GET /home
GET /
Response includes:
- Latest series
- Latest movies
- Featured content
- Trending shows
- Random series/movies
- Weekly schedule
Example:
curl https://your-api.vercel.app/homeGet detailed series information with flexible season and episode queries.
Endpoint:
GET /series/{slug}
GET /api/series?slug={slug}
Query Parameters:
slug(required) - Series slug (e.g.,attack-on-titan)seasons(optional) - Season selection:- Single:
?seasons=1 - Multiple:
?seasons=1,2,3 - Range:
?seasons=2-4 - All:
?seasons=all - Default:
1
- Single:
src(optional) - Include server sources:?src=true- Include iframe sources for all episodes?src=false- Exclude server sources (default)
server(optional) - Filter specific servers:- By number:
?server=0,1,2 - By range:
?server=0-4 - All servers:
?server=all
- By number:
Examples:
# Basic series info (season 1 only)
GET /series/attack-on-titan
# Multiple seasons
GET /series/attack-on-titan?seasons=1,2,3
# All seasons
GET /series/attack-on-titan?seasons=all
# With server sources
GET /series/attack-on-titan?seasons=1&src=true&server=all
# Specific servers
GET /series/attack-on-titan?seasons=1,2&src=true&server=0,1,2
# Season range with server range
GET /series/attack-on-titan?seasons=2-4&src=true&server=0-3Response:
{
"success": true,
"data": {
"seriesSlug": "attack-on-titan",
"title": "Attack on Titan",
"image": "https://image.tmdb.org/t/p/w185/...",
"rating": "8.658",
"year": "2013",
"totalSeasons": 6,
"totalEpisodes": 97,
"requestedSeasons": [1, 2],
"includeServerSources": true,
"availableSeasons": [
{"seasonNumber": 0, "name": "Season 0"},
{"seasonNumber": 1, "name": "Season 1"}
],
"categories": [...],
"tags": [...],
"cast": [...],
"seasons": [
{
"seasonNumber": 1,
"year": "2013",
"rating": "8.658",
"episodes": [
{
"episodeNumber": "1x1",
"title": "Attack on Titan 1x1",
"image": "https://...",
"time": "13 years ago",
"url": "https://toonstream.one/episode/attack-on-titan-1x1/",
"servers": [
{
"serverNumber": 0,
"displayNumber": 1,
"name": "X",
"src": "https://toonstream.one/home/?trembed=0&trid=35148&trtype=2"
}
]
}
]
}
]
},
"stats": {
"totalSeasons": 6,
"requestedSeasons": 2,
"fetchedEpisodes": 37,
"includesServerSources": true
}
}Get episode details with streaming server sources.
Endpoint:
GET /episode/{slug}
GET /api/episode?slug={slug}
Query Parameters:
slug(required) - Episode slug (e.g.,attack-on-titan-2x1)server(optional) - Filter servers:- By number:
?server=0,1,2 - By range:
?server=0-4 - By name:
?server=x,short,ruby - All:
?server=all
- By number:
Examples:
# All servers
GET /episode/attack-on-titan-2x1
# Specific servers by number
GET /episode/attack-on-titan-2x1?server=0,1,2
# Server range
GET /episode/attack-on-titan-2x1?server=0-4
# Specific servers by name
GET /episode/attack-on-titan-2x1?server=x,short,ruby
# All servers explicitly
GET /episode/attack-on-titan-2x1?server=allResponse:
{
"success": true,
"data": {
"episodeSlug": "attack-on-titan-2x1",
"title": "Attack on Titan 2x1",
"image": "https://...",
"description": "Episode description...",
"year": "2017",
"rating": "8.658",
"categories": [...],
"cast": [...],
"navigation": {
"previousEpisode": "https://toonstream.one/episode/attack-on-titan-1x25/",
"nextEpisode": "https://toonstream.one/episode/attack-on-titan-2x2/",
"seriesPage": "https://toonstream.one/series/attack-on-titan/"
},
"servers": [
{
"serverNumber": 0,
"displayNumber": 1,
"name": "X",
"src": "https://toonstream.one/home/?trembed=0&trid=35148&trtype=2",
"isActive": true
},
{
"serverNumber": 1,
"displayNumber": 2,
"name": "Vidstream",
"src": "https://toonstream.one/home/?trembed=1&trid=35148&trtype=2",
"isActive": false
}
]
},
"stats": {
"totalServersAvailable": 10,
"serversReturned": 2
}
}GET /movies/{slug}
GET /api/movies?path={slug}
Example:
GET /movies/naruto-the-movieResponse includes:
- Movie metadata
- Streaming servers
- Cast & crew
- Similar movies
- Download links
GET /movies
GET /movies/page/{page}
Examples:
GET /movies
GET /movies/page/2Search across all content types.
Endpoint:
GET /search/{query}
GET /home/search/{query}
GET /home?s={query}
Query Parameters:
q,s, orquery- Search term (min 2 characters)
Examples:
# URL path
GET /search/naruto
# Query parameter
GET /home?s=naruto
# Multi-word search
GET /search/one%20pieceResponse:
{
"success": true,
"data": {
"searchQuery": "naruto",
"hasResults": true,
"results": [
{
"id": "post-3812",
"title": "Naruto ShippΕ«den",
"image": "https://...",
"url": "https://...",
"rating": "8.553",
"contentType": "series",
"categories": [...],
"tags": [...]
}
]
},
"stats": {
"resultsCount": 8,
"seriesCount": 5,
"moviesCount": 3
}
}Browse content by categories (networks, genres, languages).
Endpoint:
GET /category/{path}
GET /category/{parent}/{category}
GET /category/{path}/page/{page}
Query Parameters:
path(required) - Category pathpage(optional) - Page number (default: 1)type(optional) - Filter by type:movies,series,post
Examples:
# Single-level category
GET /category/crunchyroll
GET /category/action
GET /category/anime
# Nested category
GET /category/language/hindi-language
GET /category/language/tamil-language
# With pagination
GET /category/crunchyroll/page/2
# With type filter
GET /category/action?type=moviesCommon Categories:
- Networks:
crunchyroll,netflix,disney,cartoon-network - Genres:
action,comedy,horror,sci-fi,romance - Languages:
language/hindi-language,language/english,language/japaneses
Browse content by cast members.
Endpoint:
GET /cast/{name}
GET /home/cast_tv/{name}
GET /home/cast/{name}/page/{page}
Examples:
GET /cast/saori-hayami
GET /home/cast_tv/saori-hayami
GET /cast/saori-hayami/page/2Browse content alphabetically.
Endpoint:
GET /home/letter/{letter}
GET /home/letter/{letter}/page/{page}
Examples:
GET /home/letter/A
GET /home/letter/N/page/2
GET /home/letter/0-9seasons=1- Single seasonseasons=1,2,3- Multiple seasonsseasons=2-4- Season rangeseasons=all- All available seasons
server=0,1,2- Specific servers by numberserver=0-4- Server rangeserver=x,short,ruby- By server nameserver=all- All servers
page=2- Page number (default: 1)
type=movies- Only moviestype=series- Only seriestype=post- Only posts
src=true- Include iframe sourcessrc=false- Exclude sources (default)
All successful responses follow this structure:
{
"success": true,
"data": {
// Endpoint-specific data
},
"stats": {
// Statistics about the response
}
}Error responses:
{
"success": false,
"error": "Error message",
"statusCode": 404
}const response = await fetch(
'https://your-api.vercel.app/series/attack-on-titan?seasons=all&src=true&server=all'
);
const data = await response.json();
// Access all episodes with servers
data.data.seasons.forEach(season => {
season.episodes.forEach(episode => {
console.log(`${episode.title} has ${episode.servers.length} servers`);
});
});const response = await fetch(
'https://your-api.vercel.app/episode/attack-on-titan-2x1?server=0,1,2'
);
const data = await response.json();
// Access first 3 servers
data.data.servers.forEach(server => {
console.log(`${server.name}: ${server.src}`);
});const response = await fetch(
'https://your-api.vercel.app/search/naruto'
);
const data = await response.json();
// Filter by content type
const series = data.data.results.filter(item => item.contentType === 'series');
const movies = data.data.results.filter(item => item.contentType === 'movie');const response = await fetch(
'https://your-api.vercel.app/category/action/page/2?type=movies'
);
const data = await response.json();
// Access pagination
console.log(`Current page: ${data.data.pagination.currentPage}`);
console.log(`Total pages: ${data.data.pagination.totalPages}`);The API returns appropriate HTTP status codes:
200- Success400- Bad Request (missing required parameters)404- Not Found (content doesn't exist)405- Method Not Allowed (use GET)500- Internal Server Error
Always check the success field:
const response = await fetch('https://your-api.vercel.app/series/invalid-slug');
const data = await response.json();
if (!data.success) {
console.error(`Error: ${data.error}`);
// Handle error
}toonstream-api/
βββ api/
β βββ index.js # Homepage scraper
β βββ series.js # Series details with seasons
β βββ episode.js # Episode details with servers
β βββ series_page.js # Series listing
β βββ movies.js # Individual movie details
β βββ movies_page.js # Movies listing
β βββ search.js # Search functionality
β βββ category.js # Category pages
β βββ cast.js # Cast member pages
β βββ letter.js # Alphabetical browsing
β βββ proxy.js # Dynamic URL proxy
βββ src/
β βββ baseurl.txt # Base URL configuration
βββ package.json
βββ vercel.json # Vercel configuration
βββ .gitignore
βββ README.md
{
"dependencies": {
"axios": "^1.6.0",
"cheerio": "^1.0.0-rc.12"
}
}Consider implementing rate limiting for production use:
// Example using vercel.json
{
"functions": {
"api/**/*.js": {
"memory": 1024,
"maxDuration": 30
}
}
}CORS is enabled by default for all origins. To restrict:
res.setHeader('Access-Control-Allow-Origin', 'https://yourdomain.com');- Use specific queries - Request only what you need
- Cache responses - Implement caching on your frontend
- Pagination - Use pagination for large datasets
- Filter servers - Request specific servers instead of all
- Parallel requests - Use
Promise.all()for multiple endpoints
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
This API is for educational purposes only. Please respect copyright laws and the terms of service of the source website.
For issues and questions:
- Open an issue on GitHub
- Contact: tanbirst2st2@gmail.com
Made with β€οΈ by tanbirst1st1 (https://github.com/senpaiorbit)