animedex mangadex

MangaDex is a scanlation aggregator hosted at https://api.mangadex.org. It is the deepest manga catalogue the project wraps: every series / chapter / cover / scanlation group / author / custom list, plus an authenticated /user surface for the caller’s own follows / lists / reading history. animedex covers 26 anonymous endpoints plus 13 authenticated read endpoints as 39 high-level Python functions.

animedex mangadex demo — search, show, feed, chapter

References

Site

https://mangadex.org/

API documentation

https://api.mangadex.org/docs/

Auth flow (Personal Client)

https://api.mangadex.org/docs/02-authentication/personal-clients/

Python module

animedex.backends.mangadex

Rich models

animedex.backends.mangadex.models

  • Backend: MangaDex (api.mangadex.org).

  • Rate limit: 5 req/sec anonymous; transport bucket matches.

  • Auth: optional. Anonymous endpoints work without credentials; the /user/* and /manga/*/ status surface needs an OAuth2 Bearer token via Personal Clien t password grant. See “Authenticated endpoints” below for the exact flow.

Six anonymous endpoints, in detail

Manga by UUID — show()

animedex mangadex show 801513b a-a712-498c-8f57-cae55b38cc92 \
  --jq '.attributes | {title: .title.en, status, year}'
# => {
#      "title":  "Berserk",
#      "status": "ongoing",
#      "year":   1989
#    }

Chapter feed — feed()

animedex mangadex feed 801513b a-a712-498c-8f57-cae55b38cc92 \
  --lang en --limit 5 --jq '.[ ].attributes | {chapter, title}'

One chapter — chapter()

animedex mangadex chapter <cha pter-uuid> \
  --jq '.attributes | {chapter , title, translatedLanguage, pages}'

Cover record — cover()

animedex mangadex cover <cover -uuid> --jq '.attributes.fileName'
# The full image URL is compos ed as
# https://uploads.mangadex.org /covers/<manga-id>/<fileName>

Random manga — random_manga()

animedex mangadex random-manga  --jq '.attributes.title.en'

Authenticated endpoints

The /user/* and /manga/*/status surface requires an OAuth2 Bearer token. MangaDex’s Personal Client flow exchanges client_id:client_secret:username:password for a 15-minute access token; animedex caches the token in process memory keyed on client_id.

Setup

  1. Visit https://mangadex.org/settings → API Clients → “Create”.

  2. Note the client_id (looks like personal-client-<uuid>-<suff ix>) and client_secret.

  3. Provide credentials to animedex via one of:

    # Per-call (CLI):
    animedex mangadex me --cred s "<client_id>:<client_secret>:<username>:<password>"
    
    # Per-shell (env var):
    export ANIMEDEX_MANGADEX_CR EDS="<client_id>:<client_secret>:<username>:<password>"
    animedex mangadex me
    
    # Persistent (token store):
    animedex auth set mangadex \
      "<client_id>:<client_secr et>:<username>:<password>"
    animedex mangadex me
    

The four-tuple is colon-separated. The token store goes through the OS keyring per the project’s secret-handling convention.

Authenticated walkthrough

Current user — me()

animedex mangadex me --jq '.at tributes | {username, roles}'

My follows — my_follows_manga()

animedex mangadex my-follows-m anga --limit 5 \
  --jq '.[].attributes.title.e n'

Reading history — my_history()

animedex mangadex my-history - -jq '.[]'

Read markers per manga — my_manga_read_markers()

animedex mangadex my-manga-rea d-markers \
  801513ba-a712-498c-8f57-cae5 5b38cc92 --jq '.[]'

Endpoint summary

Anonymous reads

Command

Python entry point

Returns

search <q>

animedex.backends.mangadex.search()

list[MangaDexManga]

show <id>

animedex.backends.mangadex.show()

MangaDexManga

feed <id>

animedex.backends.mangadex.feed()

list[MangaDexChapter]

chapter <id>

animedex.backends.mangadex.chapter()

MangaDexChapter

chapter-search

animedex.backends.mangadex.chapter_search()

list[MangaDexChapter]

cover <id>

animedex.backends.mangadex.cover()

MangaDexCover

cover-search

animedex.backends.mangadex.cover_search()

list[MangaDexCover]

aggregate <id>

animedex.backends.mangadex.aggregate()

MangaDexResource

recommendation <id>

animedex.backends.mangadex.recommendation()

list[MangaDexResource]

random-manga

animedex.backends.mangadex.random_manga()

MangaDexManga

manga-tag

animedex.backends.mangadex.manga_tag()

list[MangaDexResource]

author <id>

animedex.backends.mangadex.author()

MangaDexResource

author-search

animedex.backends.mangadex.author_search()

list[MangaDexResource]

group <id>

animedex.backends.mangadex.group()

MangaDexResource

group-search

animedex.backends.mangadex.group_search()

list[MangaDexResource]

list-show <id>

animedex.backends.mangadex.list_show()

MangaDexResource

list-feed <id>

animedex.backends.mangadex.list_feed()

list[MangaDexChapter]

user <id>

animedex.backends.mangadex.user()

MangaDexResource

user-lists <id>

animedex.backends.mangadex.user_lists()

list[MangaDexResource]

statistics-manga <id>

animedex.backends.mangadex.statistics_manga()

MangaDexResource

statistics-manga-batch

animedex.backends.mangadex.statistics_manga_batch()

MangaDexResource

statistics-chapter <id>

animedex.backends.mangadex.statistics_chapter()

MangaDexResource

statistics-chapter-batch

animedex.backends.mangadex.statistics_chapter_batch()

MangaDexResource

statistics-group <id>

animedex.backends.mangadex.statistics_group()

MangaDexResource

report-reasons <category>

animedex.backends.mangadex.report_reasons()

list[MangaDexResource]

ping

animedex.backends.mangadex.ping()

str

Authenticated reads

Command

Python entry point

Returns

me

animedex.backends.mangadex.me()

MangaDexUser

my-follows-manga

animedex.backends.mangadex.my_follows_manga()

list[MangaDexManga]

is-following-manga <id>

animedex.backends.mangadex.is_following_manga()

bool

my-follows-group

animedex.backends.mangadex.my_follows_group()

list[MangaDexResource]

is-following-group <id>

animedex.backends.mangadex.is_following_group()

bool

my-follows-user

animedex.backends.mangadex.my_follows_user()

list[MangaDexResource]

is-following-user <id>

animedex.backends.mangadex.is_following_user()

bool

my-follows-list

animedex.backends.mangadex.my_follows_list()

list[MangaDexResource]

my-follows-manga-feed

animedex.backends.mangadex.my_follows_manga_feed()

list[MangaDexChapter]

my-lists

animedex.backends.mangadex.my_lists()

list[MangaDexResource]

my-history

animedex.backends.mangadex.my_history()

list[MangaDexResource]

my-manga-status

animedex.backends.mangadex.my_manga_status()

dict[str, str]

my-manga-status-by-id <id>

animedex.backends.mangadex.my_manga_status_by_id()

str or None

my-manga-read-markers <id>

animedex.backends.mangadex.my_manga_read_markers()

list[str]

Pagination

MangaDex paginates with ?limit=M&offset=N (JSON:API style). The high-level helpers expose limit / offset kwargs:

animedex mangadex search "Bers erk" --limit 5 --jq '.[].attributes.title.en'
animedex mangadex search "Bers erk" --limit 5 --offset 5 --jq '.[].attributes.title.en'

Gotchas

  • Title is language-keyed: manga.attributes.title is a {lang: text} map; the to_ common() projection picks en first, then ja-ro, then any non-empty entry. Use --jq .attributes.title.ja if you s pecifically want the Japanese title.

  • Bearer tokens expire in 15 minutes: animedex caches per client_id and re-runs the p assword grant when the cache is stale; long-running shells will see one extra round-trip every ~14 minutes.

  • 404 on follow-checks is a feature: is-following-manga / is-following-group / is-f ollowing-user return false on 404 (the upstream’s “you are no t following” response shape) and raise ApiError only on othe r failure modes.

  • The ``/at-home/server`` endpoint is not wired: the page-image fetcher has its own short-lived base URLs and HTTP/2 concurrency caps; it’s a deferred follow-up .

The Python library page covers the same surface from inside Python.