API Documentation
97 GET routes under /v1, mirroring the Jikan v4 functional surface over public
MyAnimeList pages. No authentication, fully open CORS. Every route below has a try button that fires
a real request from your browser.
Conventions
Response envelope
Every success is wrapped in data + meta. Field names are camelCase —
functional parity with Jikan, not schema-identical cloning.
{
"data": { … },
"meta": {
"cached": true,
"stale": false,
"refreshFailed": false,
"fetchedAt": "2026-07-27T12:00:00Z"
}
}
Errors
Errors return an error object with a stable machine-readable code and a request id
you can quote when reporting issues.
{
"error": {
"code": "NOT_FOUND",
"message": "Route not found.",
"requestId": "…"
}
}
Common codes: NOT_FOUND, INVALID_FILTER,
RATE_LIMITED, UPSTREAM_SUSPICIOUS, NO_LOCAL_ENTRIES.
Headers
X-Cache-Status—hit,miss,staleX-Request-Id— per-request UUIDX-Worker-Version— deployed versionRetry-After— on429only
Parameter rules
pagestarts at 1limit1–300, default 100 (user lists only)- Usernames: ASCII alphanumeric,
_,-, max 32 chars - IDs: positive integers (
400otherwise) :season—winter/spring/summer/fall
Rate limits
Two per-IP windows, enforced globally across all routes (mirroring Jikan's own published
policy): 30 requests / 10 s burst and 60 requests / minute sustained. Exceeding either returns
429 RATE_LIMITED with a Retry-After header (10 or 60).
Enforcement is per Cloudflare colo and eventually consistent — treat the numbers as an operational target,
not an exact contract.
Caching
Fresh data is served straight from the edge database (D1) without touching MyAnimeList — TTL is
6 h for most resources and 2 h for user lists. A cache miss fetches the public page once, parses it,
and persists the normalized result (a 30 s per-resource lease prevents thundering herds). If a refresh fails and a
stale copy exists, you still get 200 with meta.stale: true. Valid cached data is never
replaced by a suspicious upstream document.
Self-hosting MIT, no auth
Run your own copy on your own Cloudflare account. Four commands, no API key, nothing to register beyond the Cloudflare account itself.
-
Get the code
Node 18 or newer, and a Cloudflare account you can deploy Workers from.
git clone https://github.com/LucasHenriqueDiniz/jikan-edge cd jikan-edge npm install
-
Create the database
Creates the D1 database, writes its id into
wrangler.jsoncand applies the migrations. Idempotent, so it reuses one you already made.npm run setup
-
Deploy
Publishing stays a separate, deliberate step;
setupnever does it for you.npx wrangler deploy
-
Confirm it came up
data.checks.databaseanswersok,not_migrated,not_configuredorunavailable, so one call names which of the three is wrong instead of leaving you to interpret a 500.Request
curl https://YOUR-WORKER.workers.dev/health
What a healthy deploy returns
{ "data": { "status": "ok", "service": "jikan-edge", "checks": { "database": "ok" } } }
Check the plan before you commit to it. Workers Free caps CPU at 10 ms per request, and this
API measures p95 27 ms on a cache miss, so the heavier routes return Error 1102 there.
Cached responses and the light routes run fine.
The full self-hosting guide covers the manual path, a troubleshooting table, and what running this responsibly asks of you: user agent, rate limits, cache TTLs and the source policy.
Not served investigated & documented
Every missing route was investigated against the real MyAnimeList pages — evidence lives in docs/routes.md.
| Jikan route | Status | Why |
|---|---|---|
/clubs?q= | q ignored | MAL's club search does no server-side filtering — the real search is an internal JS endpoint our source policy forbids. |
/top/reviews | not served | MAL has no review ranking mechanism (no sort-by-helpful, day-only dates). It would just be /reviews/anime in a costume. |
/users/:u/history | not served | The history page is empty without login. /users/:u/userupdates covers the public equivalent. |
/users/:u/external | not served | The MAL profile exposes no structured external links. |
/users/userbyid/:id | not served | Depends on a Jikan-internal mechanism with no public MAL page behind it. |
| per-episode forum | not served | No reliable dedicated public page per episode discussion. |
For LLMs & agents
Building against this API with an AI coding agent (Claude, Cursor, an MCP-connected tool,
anything that reads context before writing code)? /llms.txt is a plain-text summary made for
that: base URL, response envelope, error codes, rate limits and the known-limitations list above, all in one
page small enough to sit entirely in a prompt — no need to feed it this whole HTML document. For a client
generator, /openapi.json is the same contract as OpenAPI 3.1, generated from the code.
Follows the llms.txt convention some agents check for automatically. It links back to this page and to docs/routes.md for anything that needs the full route-by-route detail.