Warning
This API Provides Access To Mature/Adult Manga And Manhwa Content. By Using This API Or Its Browse Interface, You Confirm That You Are At Least 18 Years Of Age. Parental Discretion Is Advised.
A free, open-source REST API for manga, manhwa, and webtoon data — no authentication required.
Built as a middleware layer on top of OmegaScans with caching, rate limiting, retry logic, data normalization, and a full browse interface.
📖 Documentation · 📚 Browse Series · 💓 Health Status · 🐛 Report Bug · ✨ Request Feature
- 📖 About
- 🤔 Why OmegaAPI?
- ✨ Key Features
- 📡 API Endpoints
- 🚀 Quick Start
- 📦 Response Format
- ⏱️ Rate Limiting
- 💾 Caching
- 🔄 Retry Logic
- 🚨 Error Handling
- 💻 Code Examples
- 🛠️ Tech Stack
- 📁 Project Structure
- ⚙️ Local Development
- 🚢 Deployment
- 🗺️ Roadmap
- 🤝 Contributing
- ❓ FAQ
⚠️ Legal Disclaimer- 📋 Changelog
- 📝 License
- 🙏 Acknowledgments
OmegaAPI is a free, public REST API that provides comprehensive manga, manhwa, and webtoon data. It acts as a middleware layer on top of the OmegaScans API, adding:
- In-memory caching with configurable TTL (5–15 min) for sub-second responses
- Rate limiting with sliding window algorithm (60 req/min per IP)
- Retry logic with automatic single retry on 5xx upstream errors
- Data normalization for consistent, predictable JSON responses
- Error handling with descriptive messages and proper HTTP status codes
- CORS support for direct browser access from any origin
- Pagination headers for programmatic access to metadata
- Sorting & filtering on series list endpoints
- Browse interface — a full manhwa-style website with search, genre filters, chapter reader, bookmarks, and reading history
Whether you're building a manga reader app, a recommendation engine, a tracking tool, or a content aggregator — OmegaAPI gives you the data you need with a clean, consistent interface.
Why "Omega"? — Named after OmegaScans, the upstream data source. The Ω symbol represents the final, complete API for manga data.
| OmegaAPI | Other APIs | |
|---|---|---|
| 🔐 Authentication | None required | API keys, OAuth |
| ⏱️ Rate Limit | 60 req/min | Often lower or paid |
| 📦 Response Format | Consistent envelope | Varies by endpoint |
| 💾 Caching | Built-in (5–15 min) | Manual |
| 🔄 Retry Logic | Auto-retry on 5xx | Manual |
| 📊 Pagination Headers | X-Pagination-* | Body only |
| 🔀 Sort & Filter | ?sort=&status=&type= | Client-side |
| 🌐 CORS | All origins | Restricted |
| 💰 Cost | Free forever | Freemium/paid |
| 🖥️ Browse UI | Full manhwa website | Docs only |
| Feature | Description |
|---|---|
| 📚 263+ Series | Titles, descriptions, ratings, chapters, genres, authors, studios, cover images, tags |
| ⚡ Sub-Second Responses | In-memory caching (5 min series, 10 min search, 15 min chapters) |
| 🔍 Full-Text Search | Search across hundreds of series with pagination |
| 🖼️ Chapter Images | Every page image URL for any chapter — build reader apps |
| 🔀 Sort & Filter | ?sort=rating&order=desc&status=ongoing&type=manhwa |
| 🎲 Random Discovery | /api/v1/random endpoint for series discovery |
| 📊 Pagination Headers | X-Pagination-Total, X-Per-Page, X-Current-Page in headers |
| 🔓 Zero Auth | No API keys, no sign-ups, no OAuth |
| 🌐 CORS Ready | Call from any frontend — browser, mobile, desktop |
| 🛡️ Rate Limiting | 60 req/min per IP with X-RateLimit-* headers |
| 📦 Consistent Envelope | Every response: { success, data, pagination? } |
| 🔄 Auto Retry | Single retry on 5xx upstream errors |
| 💓 Health Monitoring | Upstream probe with latency tracking, cached 30s |
| 🖼️ OG Image Generator | /api/og for dynamic social sharing images |
| Feature | Description |
|---|---|
| 📱 Manhwa Browse UI | Featured banner, scroll rows, genre filters, search autocomplete |
| 📖 Chapter Reader | Vertical and paged reading modes with prev/next navigation |
| ❤️ Bookmarks / My List | Heart button on cards, dedicated scroll row |
| 📜 Reading History | Track progress with "Continue Reading" row and progress bars |
| 🔍 Recent Searches | Shown in search overlay with clear history option |
| 📌 Reading Position | Scroll position saved per chapter, restored on revisit |
| 🔞 Age Verification | 18+ gate with localStorage persistence |
| 🎨 Neo-Brutalist UI | Bold cards, frosted glass nav, spring animations |
| 🌙 Dark Theme | Immersive manhwa reading experience |
| 📱 Responsive | Mobile-first, works on all screen sizes |
| 🎭 Dual Theme | Light landing page, dark browse pages |
| ⚡ Error Boundary | Graceful error recovery on all browse pages |
https://omegaapi.vercel.app/api/v1
| Property | Value |
|---|---|
| Protocol | HTTPS only |
| Method | GET only |
| Auth | None required |
| CORS | All origins |
| Content-Type | application/json |
| Rate Limit | 60 req/min per IP |
GET /api/v1/series
Browse all series with search, sorting, filtering, and pagination.
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
perPage |
integer | 20 |
Results per page (max 100) |
q |
string | — | Search query to filter by title |
sort |
string | — | Sort by: title, rating, views, updated |
order |
string | desc |
Sort direction: asc, desc |
status |
string | — | Filter: ongoing, completed, hiatus |
type |
string | — | Filter: manga, manhwa, manhua |
# Browse all series
curl https://omegaapi.vercel.app/api/v1/series
# Sort by rating, descending
curl "https://omegaapi.vercel.app/api/v1/series?sort=rating&order=desc"
# Filter ongoing manhwa
curl "https://omegaapi.vercel.app/api/v1/series?status=ongoing&type=manhwa"GET /api/v1/series/{slug}
Get complete metadata for a single series.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug |
string | ✅ | Series identifier |
include |
string | — | Pass chapters to embed full chapter list |
curl https://omegaapi.vercel.app/api/v1/series/sex-stopwatch
curl "https://omegaapi.vercel.app/api/v1/series/sex-stopwatch?include=chapters"📄 Full Response
{
"success": true,
"data": {
"id": 7,
"title": "Sex Stopwatch",
"slug": "sex-stopwatch",
"description": "When a man discovers a mysterious stopwatch...",
"rating": 4.96,
"status": "Completed",
"type": "Manhwa",
"totalViews": 20110784,
"chaptersCount": 155,
"bookmarksCount": 12840,
"alternativeNames": "Sex Stopwatch",
"author": "Author Name",
"studio": "Studio Name",
"releaseYear": "2023",
"releaseSchedule": ["Monday", "Thursday"],
"tags": ["Adult", "Comedy", "Drama"],
"thumbnail": "https://media.omegascans.org/.../thumb.jpg",
"cover": "https://media.omegascans.org/.../cover.jpg",
"badge": null,
"chapters": []
}
}GET /api/v1/chapters/{slug}
GET /api/v1/series/{slug}/chapters ← RESTful alias
Get all chapters for a series with pagination.
| Parameter | Type | Default | Description |
|---|---|---|---|
slug |
string | — | Series slug |
page |
integer | 1 |
Page number |
perPage |
integer | 100 |
Results per page (max 500) |
curl https://omegaapi.vercel.app/api/v1/chapters/sex-stopwatch
curl https://omegaapi.vercel.app/api/v1/series/sex-stopwatch/chaptersGET /api/v1/chapter/{slug}/{chapter}
Get chapter content with all page image URLs.
curl https://omegaapi.vercel.app/api/v1/chapter/sex-stopwatch/chapter-1📄 Response
{
"success": true,
"data": {
"id": 10944,
"name": "Chapter 1",
"slug": "chapter-1",
"pageCount": 13,
"images": [
"https://media.omegascans.org/.../01.jpg",
"https://media.omegascans.org/.../02.jpg"
],
"series": {
"title": "Sex Stopwatch",
"slug": "sex-stopwatch"
}
}
}GET /api/v1/search?q={query}
Full-text search across all series.
curl "https://omegaapi.vercel.app/api/v1/search?q=solo"GET /api/v1/random
Get a random series for discovery.
| Parameter | Type | Default | Description |
|---|---|---|---|
count |
integer | 1 |
Number of random series (max 10) |
curl https://omegaapi.vercel.app/api/v1/random
curl "https://omegaapi.vercel.app/api/v1/random?count=5"GET /api/v1/genres
Returns all 24 supported genre categories.
curl https://omegaapi.vercel.app/api/v1/genresGET /api/v1/health
API health status with upstream probe (cached 30s).
curl https://omegaapi.vercel.app/api/v1/health📄 Response
{
"success": true,
"data": {
"status": "ok",
"version": "3.9.0",
"uptime": 86400,
"upstream": {
"status": "ok",
"latencyMs": 180,
"url": "https://api.omegascans.org",
"cached": true
}
}
}GET /api/v1/stats
API statistics, endpoint listing, cache state, and version info.
curl https://omegaapi.vercel.app/api/v1/statsGET /api/og?title={title}&rating={rating}&views={views}&status={status}
Generate dynamic SVG Open Graph images for social sharing.
curl "https://omegaapi.vercel.app/api/og?title=Solo%20Leveling&rating=4.9&views=15M&status=Completed"No API key needed. Just make a request:
# Get a series
curl https://omegaapi.vercel.app/api/v1/series/sex-stopwatch
# Search
curl "https://omegaapi.vercel.app/api/v1/search?q=solo"
# Get chapter images
curl https://omegaapi.vercel.app/api/v1/chapter/sex-stopwatch/chapter-1
# Random series
curl https://omegaapi.vercel.app/api/v1/random
# Check health
curl https://omegaapi.vercel.app/api/v1/healthJavaScript
const res = await fetch('https://omegaapi.vercel.app/api/v1/series/sex-stopwatch');
const { success, data } = await res.json();
if (success) {
console.log(data.title); // "Sex Stopwatch"
console.log(data.rating); // 4.96
console.log(data.chaptersCount); // 155
}Python
import requests
BASE = "https://omegaapi.vercel.app/api/v1"
# Get a series
data = requests.get(f"{BASE}/series/sex-stopwatch").json()
print(data["data"]["title"], data["data"]["rating"])
# Search
results = requests.get(f"{BASE}/search", params={"q": "solo"}).json()
for s in results["data"]:
print(f"{s['title']} — {s['rating']}")cURL + jq
# Series title
curl -s https://omegaapi.vercel.app/api/v1/series/sex-stopwatch | jq '.data.title'
# Search results
curl -s "https://omegaapi.vercel.app/api/v1/search?q=solo" | jq '.data[].title'
# Chapter page count
curl -s https://omegaapi.vercel.app/api/v1/chapter/sex-stopwatch/chapter-1 | jq '.data.pageCount'Go
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type Response struct {
Success bool `json:"success"`
Data map[string]interface{} `json:"data"`
}
func main() {
resp, _ := http.Get("https://omegaapi.vercel.app/api/v1/series/sex-stopwatch")
defer resp.Body.Close()
var result Response
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result.Data["title"])
}PHP
<?php
$data = json_decode(file_get_contents(
'https://omegaapi.vercel.app/api/v1/series/sex-stopwatch'
), true);
echo $data['data']['title'] . ' — ' . $data['data']['rating'];Ruby
require 'net/http'
require 'json'
data = JSON.parse(Net::HTTP.get(URI(
'https://omegaapi.vercel.app/api/v1/series/sex-stopwatch'
)))
puts "#{data['data']['title']} — #{data['data']['rating']}"Every response follows a consistent envelope:
|
✅ Success (paginated) {
"success": true,
"data": [...],
"pagination": {
"total": 250,
"perPage": 20,
"currentPage": 1,
"lastPage": 13,
"hasNext": true,
"hasPrevious": false
}
} |
✅ Success (single item) {
"success": true,
"data": { ... }
}❌ Error {
"success": false,
"error": "Series not found"
} |
All paginated endpoints include these headers:
| Header | Description |
|---|---|
X-Pagination-Total |
Total items across all pages |
X-Pagination-Per-Page |
Items per page |
X-Pagination-Current-Page |
Current page number |
X-Pagination-Last-Page |
Last available page |
X-Pagination-Has-Next |
true if more pages exist |
X-Pagination-Has-Previous |
true if previous pages exist |
| Setting | Value |
|---|---|
| Limit | 60 requests per minute |
| Window | Rolling 60-second window |
| Scope | Per IP address |
| Header | Description |
|---|---|
X-RateLimit-Limit |
Max requests allowed (60) |
X-RateLimit-Remaining |
Requests remaining |
X-RateLimit-Reset |
Unix timestamp when window resets |
X-Request-ID |
Unique UUID for tracing |
Retry-After |
Seconds to wait (on 429 only) |
const res = await fetch('https://omegaapi.vercel.app/api/v1/series');
if (res.status === 429) {
const retryAfter = res.headers.get('Retry-After');
await new Promise(r => setTimeout(r, retryAfter * 1000));
}| Resource | TTL | Why |
|---|---|---|
| Series list | 5 min | General browsing |
| Series detail | 5 min | Metadata rarely changes |
| Search results | 10 min | Expensive upstream queries |
| Chapter content | 15 min | Images are immutable |
| Genres | 30 min | Static list |
| Health probe | 30 sec | Avoid upstream hammering |
Cached responses include X-Cache: HIT. Vercel edge cache adds additional layer via Cache-Control: public, s-maxage=300.
OmegaAPI automatically retries failed upstream requests:
| Setting | Value |
|---|---|
| Retries | 1 attempt |
| Trigger | 5xx status codes only |
| Delay | 1 second between attempts |
| Scope | Does not retry 4xx errors |
This handles transient upstream failures without exposing errors to API consumers.
| Code | Status | Description |
|---|---|---|
200 |
OK | Request successful |
400 |
Bad Request | Invalid parameters |
404 |
Not Found | Resource doesn't exist |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Server Error | Upstream API error |
503 |
Service Unavailable | API degraded |
JavaScript — Build a Reader
const BASE = 'https://omegaapi.vercel.app/api/v1';
// Get series details
const series = await fetch(`${BASE}/series/sex-stopwatch`).then(r => r.json());
console.log(`${series.data.title} — ${series.data.chaptersCount} chapters`);
// Load chapter images into DOM
const chapter = await fetch(`${BASE}/chapter/sex-stopwatch/chapter-1`).then(r => r.json());
const reader = document.getElementById('reader');
chapter.data.images.forEach((url, i) => {
const img = document.createElement('img');
img.src = url;
img.alt = `Page ${i + 1}`;
img.loading = 'lazy';
reader.appendChild(img);
});Python — Series Scraper
import requests
BASE = "https://omegaapi.vercel.app/api/v1"
# Get top-rated series
series = requests.get(f"{BASE}/series", params={
"sort": "rating", "order": "desc", "perPage": 10
}).json()
for s in series["data"]:
print(f"⭐ {s['rating']} — {s['title']} ({s['chaptersCount']} ch)")cURL + jq — Quick Queries
# Top 5 rated series
curl -s "https://omegaapi.vercel.app/api/v1/series?sort=rating&perPage=5" | jq '.data[] | "\(.rating) \(.title)"'
# All ongoing manhwa
curl -s "https://omegaapi.vercel.app/api/v1/series?status=ongoing&type=manhwa" | jq '.data[].title'
# Random series
curl -s https://omegaapi.vercel.app/api/v1/random | jq '.data.title'| Runtime | Node.js 18+ |
| Framework | Next.js 14 (App Router, Edge Runtime) |
| Language | TypeScript 5 |
| Data Source | OmegaScans API |
| Caching | In-memory Map with TTL + Vercel Edge Cache |
| Rate Limiting | Custom sliding window per IP |
| Styling | Tailwind CSS 3 |
| Deployment | Vercel (iad1 region) |
OmegaAPI/
├── public/
│ ├── favicon.svg, favicon-*.png, og-image.png
│ └── robots.txt
├── scripts/
│ └── generate-search-index.ts # Build-time search index
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── og/route.ts # Dynamic OG image generator
│ │ │ └── v1/
│ │ │ ├── series/
│ │ │ │ ├── route.ts # GET /api/v1/series
│ │ │ │ └── [slug]/
│ │ │ │ ├── route.ts # GET /api/v1/series/:slug
│ │ │ │ └── chapters/ # GET /api/v1/series/:slug/chapters
│ │ │ ├── chapters/[slug]/ # GET /api/v1/chapters/:slug
│ │ │ ├── chapter/[slug]/[ch]/ # GET /api/v1/chapter/:slug/:chapter
│ │ │ ├── search/ # GET /api/v1/search
│ │ │ ├── random/ # GET /api/v1/random
│ │ │ ├── genres/ # GET /api/v1/genres
│ │ │ ├── health/ # GET /api/v1/health
│ │ │ └── stats/ # GET /api/v1/stats
│ │ ├── browse/
│ │ │ ├── page.tsx # Manhwa-style browse page
│ │ │ ├── [slug]/page.tsx # Series detail
│ │ │ ├── [slug]/[chapter]/page.tsx # Chapter reader
│ │ │ └── genre/[name]/page.tsx # Genre pages
│ │ ├── docs/page.tsx # API documentation
│ │ ├── support/page.tsx # Support & FAQ
│ │ ├── terms/page.tsx # Terms of Service
│ │ ├── privacy/page.tsx # Privacy Policy
│ │ ├── page.tsx # Landing page
│ │ ├── layout.tsx # Root layout
│ │ ├── globals.css # Design tokens
│ │ └── sitemap.ts # Dynamic sitemap
│ ├── components/
│ │ ├── icons.tsx # 35+ SVG icons
│ │ ├── layout.tsx # Navbar + Footer
│ │ ├── ui.tsx # Shared UI utilities
│ │ └── ErrorBoundary.tsx # React Error Boundary
│ ├── lib/
│ │ ├── omega.ts # OmegaScans API client + normalizer
│ │ ├── cache.ts # In-memory TTL cache
│ │ ├── rate-limit.ts # Sliding window rate limiter
│ │ ├── storage.ts # localStorage utilities
│ │ └── utils.ts # Response helpers
│ └── types/index.ts # TypeScript interfaces
├── .env.example # Environment variable template
├── CHANGELOG.md # Version history
├── LICENSE # MIT License
└── README.md # This file
# Clone
git clone https://github.com/Shineii86/OmegaAPI.git
cd OmegaAPI
# Install
npm install
# Develop
npm run devOpen http://localhost:3000.
| Command | Description |
|---|---|
npm run dev |
Development server with hot reload |
npm run build |
Production build |
npm start |
Production server |
npm run lint |
ESLint |
curl http://localhost:3000/api/v1/health
curl "http://localhost:3000/api/v1/series?page=1&perPage=5"
curl "http://localhost:3000/api/v1/search?q=solo"- Fork this repository
- Go to vercel.com/new
- Import your fork
- Click Deploy — no env vars needed
| Platform | Command | Notes |
|---|---|---|
| Vercel | vercel |
Zero config |
| Railway | railway up |
Easy setup |
| Render | Connect repo | Auto-deploy |
| Fly.io | fly deploy |
Edge deployment |
| Self-hosted | npm run build && npm start |
Full control |
- REST API with caching & rate limiting
- Browse UI with search & genre filters
- Chapter reader (vertical + paged)
- Reading history & bookmarks
- Sort & filter on API
- Random series endpoint
- Pagination metadata headers
- Retry logic on upstream errors
- Dynamic OG image generator
- React Error Boundary
- Static search index (build-time generation)
- WebSocket for real-time chapter notifications
- API key system for higher rate limits
- GraphQL endpoint
- Multi-language support
Contributions welcome! Here's how:
- 🐛 Report bugs — Open an issue
- ✨ Request features — Open an issue
- 📝 Improve docs — Fix typos, add examples
- 💻 Submit code — Fix bugs or implement features
# Fork → Clone → Branch → Code → Test → Commit → PR
git checkout -b feature/amazing-feature
npm run build # Test
git commit -m 'feat: add amazing feature'
git push origin feature/amazing-featureIs OmegaAPI really free?
Yes! Completely free, always. No API keys, no sign-ups, no hidden costs.Do I need an API key?
No. Just make a request and get JSON.What are the rate limits?
60 requests per minute per IP. Headers tell you exactly how many you have left.Can I use this in my frontend?
Yes! CORS is enabled for all origins. Call directly from any browser or app.Where does the data come from?
OmegaAPI wraps the OmegaScans API, normalizing and caching data. Not affiliated with OmegaScans.How often is data updated?
Real-time from OmegaScans, cached 5–15 min per endpoint.Can I use this commercially?
Yes! MIT License allows commercial use. Respect rate limits.Can I self-host?
Yes! Clone, `npm install`, deploy anywhere. See [Deployment](#-deployment).This project is unofficial and not affiliated with or endorsed by OmegaScans.
- Acts as a middleware/proxy to the official OmegaScans backend
- No content is hosted or redistributed
- Rate limiting protects upstream servers
- Use responsibly and respect the original site's terms
Terms of Service · Privacy Policy · MIT License
See CHANGELOG.md for full version history.
- 🔄 Retry Logic — Auto-retry on 5xx upstream errors
- 💓 Health Check Cache — Upstream probe cached 30s
- 📊 Pagination Headers —
X-Pagination-*on all paginated endpoints - 🔀 Sort & Filter —
?sort=,?status=,?type=on series list - 🎲 Random Endpoint —
/api/v1/randomfor discovery - 🖼️ OG Image Generator —
/api/ogfor dynamic social images - 🛡️ Error Boundary — Graceful recovery on all browse pages
- 📝 Structured Documentation — Box headers, section markers, feature tags
- 🔓 Payment System Removed — All browse pages now free
- 📦 Version Synced —
3.9.0across package.json, health, and stats
This project is licensed under the MIT License — see LICENSE.
| Project | Role |
|---|---|
| OmegaScans | Upstream data source |
| Next.js | React framework |
| Vercel | Hosting & edge deployment |
| Tailwind CSS | CSS framework |
| ShineiAPI | Design inspiration |