Endpoints
Detailed API endpoint documentation
API Endpoints
Host Manifest
GET /
Returns the host manifest containing metadata about the host and a list of available sources. This is the first endpoint Alethia calls when a user adds a new host URL. It serves as the discovery mechanism for all sources provided by the host.
Alethia uses this endpoint to:
- Display the host name and author in the UI
- Enumerate available sources for the user to browse
- Check source versions and detect updates via
hashcomparison
Response Fields
| Field | Type | Description |
|---|---|---|
name | string | Display name of the host |
author | string | Name or handle of the host maintainer |
repository | string | URL to the host's source code repository |
version | string | Semantic version of the host (e.g., 1.0.0) |
hash | string | Content hash for change detection |
sources | string[] | Array of source slugs available on this host |
manifest | object | Per-source metadata including version, hash, and status |
Response
{
"name": "myhost",
"author": "developer",
"repository": "https://github.com/developer/myhost",
"version": "1.0.0",
"hash": "abc123def456",
"sources": ["mangadex"],
"manifest": {
"mangadex": {
"version": "1.0.0",
"hash": "xyz789",
"status": "active"
}
}
}Source Status Values
| Status | Description |
|---|---|
active | Source is fully functional |
deprecated | Source works but will be removed in a future version |
removed | Source is no longer available |
Source Metadata
GET /:source
Returns the complete configuration for a specific source. This endpoint provides Alethia with all the information needed to interact with the source, including supported search options, filters, authentication requirements, and UI presets.
Alethia calls this endpoint when:
- A user first enables a source
- Checking for source configuration updates
- Building the search UI with available filters and sort options
Response Fields
| Field | Type | Description |
|---|---|---|
name | string | Display name of the source |
slug | string | Unique identifier (lowercase a-z only) |
icon | string | URL to the source's icon image |
languages | string[] | Supported language codes (e.g., ["en", "ja"]) |
nsfw | boolean | Whether the source contains NSFW content by default |
url | string | Base URL of the upstream source |
referer | string | Referer header to use for image requests (important for hotlink protection) |
auth | object | Authentication configuration (see Authentication) |
search | object | Search capabilities (sort options, filters, tags) |
presets | array | Predefined search configurations for quick access |
version | string | Semantic version of the source |
hash | string | Content hash for change detection |
Response
{
"name": "MangaDex",
"slug": "mangadex",
"icon": "https://example.com/icon.png",
"languages": ["en"],
"nsfw": false,
"url": "https://mangadex.org",
"referer": "https://mangadex.org",
"auth": {
"type": "none",
"required": false
},
"search": {
"sort": ["relevance", "latest", "popularity"],
"filters": ["status", "contentRating", "includeTag"],
"tags": [
{ "slug": "action", "name": "Action", "nsfw": false }
]
},
"presets": [
{
"name": "Latest Updates",
"description": "Recently updated manga",
"request": {
"query": "",
"page": 1,
"limit": 20,
"sort": "latest",
"direction": "desc"
}
}
],
"version": "1.0.0",
"hash": "abc123"
}Referer Header
The referer field is crucial for sources with hotlink protection. Alethia will include this header when loading images. Without the correct referer, images may fail to load or return 403 errors.
Search Configuration Contract
The search.sort and search.filters arrays define the only valid values Alethia will send in search requests. Your host should validate incoming search requests against these declared values and reject any undefined sort options or filter keys with a clear error response (see Error Response).
Health Check
GET /:source/health
Returns the health status of the source itself. This is a lightweight endpoint that confirms the source adapter is running and can respond to requests. It does not check upstream connectivity — use /ping for that.
Use this endpoint for:
- Load balancer health checks
- Kubernetes liveness probes
- Basic monitoring and alerting
Response
{
"status": "ok"
}Upstream Ping
GET /:source/ping
Tests connectivity to the upstream source by making a lightweight request to the upstream API. Returns the connection status and latency. This helps diagnose whether issues are with your host or the upstream source.
Use this endpoint for:
- Diagnosing connectivity issues
- Monitoring upstream availability
- Displaying source status in the UI
Response Fields
| Field | Type | Description |
|---|---|---|
status | string | ok if upstream is reachable, down otherwise |
latencyMs | number | Round-trip time in milliseconds |
error | string | Error message (only present when status is down) |
Response (Success)
{
"status": "ok",
"latencyMs": 150
}Response (Failure)
{
"status": "down",
"latencyMs": 5000,
"error": "Connection timeout"
}Authentication
POST /:source/authenticate
Alethia supports a degree of source-specific authentication. Technically, this involves providing (on the client), fields based on what is depended on the source's auth.type configuration. On success, returns headers that Alethia will include in subsequent requests to authenticated endpoints. (stored in Keychain and will clear on logout/reauth/authorization failure - usually an indicator of authentication expiring).
Alethia stores the returned headers securely and includes them in requests to /search, /:mangaSlug, /:mangaSlug/chapters, and /:mangaSlug/chapters/:chapterSlug.
Authentication Flow
Using Authentication Headers
When Alethia makes requests to the above mentioned endpoints, it includes any necessary authentication headers returned from the /authenticate route. Your host from here has a number of responsibilities:
- Forwarding headers to upstream — Pass the authentication headers (Authorization, Cookie, etc.) to the upstream API when making requests (typically these are done through headers but some GraphQL-like services actually pass them into the body of the request - but generally your host is responsible for handling this nuance).
- Validating auth requirements — If your source has
auth.required: true, check that valid auth headers are present before processing the request. (technically not required but it's a good practice to avoid unnecessary upstream calls). - Returning appropriate errors — If auth is required but headers are missing or invalid, return an
UNAUTHORIZEDerror (see Error Response).
Validate Required Authentication
If your source configuration declares auth.required: true, your host must validate that authentication headers are present and valid on protected endpoints (/search, /:mangaSlug, etc.). Return an INVALID_CREDENTIALS error with HTTP 401 if auth is missing or invalid.
Authentication Types
Sources declare their authentication requirements in the auth field of their configuration. Alethia currently supports the following six authentication types.
| Type | Fields | Use Cases |
|---|---|---|
none | — | Public sources with no login required (MangaDex public API, etc.) |
basic | username password | Traditional login systems returning stateless tokens or Basic auth headers |
session | username password | Cookie-based session auth, common for traditional web applications |
api_key | apiKey | Self-hosted services (Komga, Kavita), developer APIs with dashboard-issued keys |
bearer | token | Pre-obtained OAuth tokens, JWT from external auth flows, personal access tokens |
cookie | cookie | Fallback for complex auth (Cloudflare challenges, CAPTCHAs) where users copy cookies from browser |
None
No authentication required. The /authenticate endpoint returns empty headers. Most public sources use this type.
Source Configuration
{
"auth": {
"type": "none",
"required": false
}
}Request Body — Not needed, but if called:
{}Response
{
"success": true,
"headers": {}
}Basic
Username and password authentication. Typically used for sources with traditional login systems. The host validates credentials against the upstream API and returns an Authorization header.
Source Configuration
{
"auth": {
"type": "basic",
"required": true,
"fields": ["username", "password"]
}
}Request Body
{
"username": "user@example.com",
"password": "password123"
}Response
{
"success": true,
"headers": {
"Authorization": "Basic dXNlcjpwYXNz..."
}
}Session
Username and password authentication that returns session cookies. Similar to basic auth but the upstream uses cookie-based sessions instead of stateless tokens. Common for traditional web applications.
Source Configuration
{
"auth": {
"type": "session",
"required": true,
"fields": ["username", "password"]
}
}Request Body
{
"username": "user@example.com",
"password": "password123"
}Response
{
"success": true,
"headers": {
"Cookie": "session=abc123; user_id=456"
}
}API Key
Single API key authentication. Useful for sources that issue API keys through a dashboard or settings page rather than traditional username/password login. Common for self-hosted services like Komga.
Source Configuration
{
"auth": {
"type": "api_key",
"required": true,
"fields": ["apiKey"]
}
}Request Body
{
"apiKey": "sk-abc123def456"
}Response
{
"success": true,
"headers": {
"X-API-Key": "sk-abc123def456"
}
}Bearer
Bearer token authentication. The user provides a pre-obtained token directly (e.g., from an OAuth flow, settings page, or external authentication). The host doesn't perform authentication — it just validates and passes through the token.
Source Configuration
{
"auth": {
"type": "bearer",
"required": true,
"fields": ["token"]
}
}Request Body
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}Response
{
"success": true,
"headers": {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."
}
}Cookie
Direct cookie authentication. The user provides raw cookie values, typically copied from browser developer tools. This is a fallback for sources with complex authentication (e.g., Cloudflare challenges, CAPTCHAs) that can't be automated.
Source Configuration
{
"auth": {
"type": "cookie",
"required": true,
"fields": ["cookie"]
}
}Request Body
{
"cookie": "session=abc123; cf_clearance=xyz789"
}Response
{
"success": true,
"headers": {
"Cookie": "session=abc123; cf_clearance=xyz789"
}
}Cookie Expiration
Cookies obtained from browser sessions often have expiration times. Users may need to re-authenticate periodically when using cookie-based auth.
Error Responses
All authentication types are expected to return the same error format on failure:
{
"success": false,
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Invalid username or password"
}
}Error Codes
(Ideal, but should generally be a valid kind of error code, to see all possible error codes, see the list of error responses..)
| Code | Description |
|---|---|
MISSING_FIELDS | Required field not provided |
INVALID_CREDENTIALS | Authentication failed |
RATE_LIMITED | Too many attempts |
Search
POST /:source/search
Search for manga on the source. This is a POST request with a JSON body containing the search query, pagination, sorting, and filter parameters. The available sort options and filters depend on what the source declared in its configuration.
Request Translation
The search request body is a standardized format that Alethia sends to your host. Your adapter is responsible for translating these fields into whatever format your upstream source expects — REST query parameters, different JSON structures, GraphQL queries, or custom headers. This abstraction allows Alethia to work with any source regardless of the upstream API design.
This endpoint powers:
- The main search functionality in Alethia
- Browse/discover pages using presets
- Filtered browsing by tags, status, etc.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
query | string | No | Search query text. Empty string returns all results (useful for browsing). |
page | number | Yes | Page number, 1-indexed. |
limit | number | No | Results per page. Default: 20, max: 100. |
sort | string | Yes | Sort option. Must be one of the values from the source's search.sort array. |
direction | string | No | Sort direction: asc or desc. Default: desc. |
filters | object | No | Key-value pairs for filtering. Keys must match the source's search.filters array. |
Validate Against Configuration
Your host should validate that sort and filters values match what's declared in the source's configuration. Reject requests with undefined sort options or filter keys with a clear error response (see Error Response). This prevents invalid queries from reaching the upstream API and helps catch client-side bugs early.
Request Body
{
"query": "one piece",
"page": 1,
"limit": 20,
"sort": "relevance",
"direction": "desc",
"filters": {
"status": ["ongoing"],
"contentRating": ["safe", "suggestive"]
}
}Direction Support
The direction field may be ignored by some sources. Not all upstream APIs support bidirectional sorting — some only return results in a fixed order for each sort option. Check the source's capabilities before relying on this field.
Response Fields
| Field | Type | Description |
|---|---|---|
results | Entry[] | Array of manga entries matching the search |
page | number | Current page number (mirrors the request) |
more | boolean | true if more results are available on the next page |
Response
{
"results": [
{
"slug": "one-piece",
"title": "One Piece",
"cover": "https://..."
}
],
"page": 1,
"more": true
}Entry Fields
| Field | Type | Description |
|---|---|---|
slug | string | Unique identifier for the manga (used in subsequent requests, see Slugs) |
title | string | Display title |
cover | string | null | URL to cover image (can be null) |
Lightweight Results
Search results return minimal data to keep responses fast. Full metadata (tags, classification, authors, etc.) is fetched when the user views manga details.
Manga Details
GET /:source/:mangaSlug
Get detailed information about a specific manga. The mangaSlug comes from a search result's slug field (see Slugs). This endpoint returns comprehensive metadata including synopsis, authors, all covers, and full tag information.
Alethia calls this endpoint when:
- A user taps on a manga from search results
- Refreshing manga details in the library
- Building the manga detail page UI
Path Parameters
| Parameter | Description |
|---|---|
source | Source slug (e.g., mangadex) |
mangaSlug | Manga identifier from search results |
Response Fields
| Field | Type | Description |
|---|---|---|
slug | string | Unique identifier (same as path parameter) |
url | string | URL to the manga on the upstream source |
title | string | Primary display title |
alternativeTitles | string[] | Other titles (translations, romanizations, etc.) |
authors | string[] | List of authors |
synopsis | string | Description/summary of the manga |
covers | string[] | Array of cover image URLs |
tags | string[] | Array of tag slugs (strings, not objects) |
classification | string | Content rating: Unknown, Safe, Suggestive, Explicit, or Pornographic |
publication | string | Publication status: Unknown, Ongoing, Completed, Cancelled, or Hiatus |
createdAt | string | ISO 8601 timestamp of when the manga was added |
updatedAt | string | ISO 8601 timestamp of last update |
Response
{
"slug": "one-piece",
"url": "https://mangadex.org/title/...",
"title": "One Piece",
"alternativeTitles": ["ワンピース", "OP"],
"authors": ["Oda Eiichiro"],
"synopsis": "Gol D. Roger, a man referred to as the \"Pirate King,\" is set to be executed...",
"covers": ["https://...", "https://..."],
"tags": ["action", "adventure", "comedy"],
"classification": "Safe",
"publication": "Ongoing",
"createdAt": "2020-01-15T10:30:00Z",
"updatedAt": "2024-12-01T08:00:00Z"
}Chapters
GET /:source/:mangaSlug/chapters
Get the list of available chapters for a manga. Returns chapters in reverse chronological order (newest first). Each chapter includes metadata for display and a slug for fetching pages (see Slugs).
Alethia calls this endpoint when:
- Displaying the chapter list on a manga's detail page
- Checking for new chapters during library updates
- Building download queues
Path Parameters
| Parameter | Description |
|---|---|
source | Source slug (e.g., mangadex) |
mangaSlug | Manga identifier |
Response Fields (per chapter)
| Field | Type | Description |
|---|---|---|
slug | string | Unique identifier for the chapter |
url | string | URL to the chapter on the upstream source |
title | string | Chapter title (may include chapter name or just number) |
number | number | Chapter number (used for sorting and progress tracking) |
date | string | ISO 8601 timestamp of when the chapter was released/uploaded |
language | string | Language code (e.g., en, ja) |
scanlator | string | Name of the scanlation group (may be empty) |
Response
[
{
"slug": "chapter-1100",
"url": "https://...",
"title": "Chapter 1100: My Dear Hero",
"number": 1100,
"date": "2024-01-15T00:00:00Z",
"language": "en",
"scanlator": "TCB Scans"
},
{
"slug": "chapter-1099",
"url": "https://...",
"title": "Chapter 1099",
"number": 1099,
"date": "2024-01-08T00:00:00Z",
"language": "en",
"scanlator": "TCB Scans"
}
]Multiple Scanlators
Some sources provide multiple versions of the same chapter from different scanlation groups. These appear as separate entries with the same number but different slug and scanlator values.
Chapter Pages
GET /:source/:mangaSlug/chapters/:chapterSlug
Get the page image URLs for a specific chapter. Returns an ordered array of image URLs that Alethia will display in the reader. The chapterSlug comes from the chapter list response (see Slugs).
Alethia calls this endpoint when:
- A user opens a chapter to read
- Pre-fetching pages for smoother reading
- Downloading chapters for offline reading
Path Parameters
| Parameter | Description |
|---|---|
source | Source slug (e.g., mangadex) |
mangaSlug | Manga identifier |
chapterSlug | Chapter identifier from the chapters list |
Response
An array of image URLs in reading order:
[
"https://uploads.mangadex.org/.../1.png",
"https://uploads.mangadex.org/.../2.png",
"https://uploads.mangadex.org/.../3.png"
]URL Expiration
Some sources return temporary URLs that expire after a short period. Alethia handles this by re-fetching the page list when URLs fail to load, but be aware that caching these URLs long-term may cause issues.
Image Loading
Remember to configure the referer field in your source configuration if the upstream has hotlink protection. Alethia will include this header when loading images.