時間 jikan-edge / docs

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.

https://jikan.lucashdo.comcopy

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, stale
  • X-Request-Id — per-request UUID
  • X-Worker-Version — deployed version
  • Retry-After — on 429 only

Parameter rules

  • page starts at 1
  • limit 1–300, default 100 (user lists only)
  • Usernames: ASCII alphanumeric, _, -, max 32 chars
  • IDs: positive integers (400 otherwise)
  • :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.

  1. 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
  2. Create the database Creates the D1 database, writes its id into wrangler.jsonc and applies the migrations. Idempotent, so it reuses one you already made.
    npm run setup
  3. Deploy Publishing stays a separate, deliberate step; setup never does it for you.
    npx wrangler deploy
  4. Confirm it came up data.checks.database answers ok, not_migrated, not_configured or unavailable, 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 routeStatusWhy
/clubs?q=q ignoredMAL's club search does no server-side filtering — the real search is an internal JS endpoint our source policy forbids.
/top/reviewsnot servedMAL has no review ranking mechanism (no sort-by-helpful, day-only dates). It would just be /reviews/anime in a costume.
/users/:u/historynot servedThe history page is empty without login. /users/:u/userupdates covers the public equivalent.
/users/:u/externalnot servedThe MAL profile exposes no structured external links.
/users/userbyid/:idnot servedDepends on a Jikan-internal mechanism with no public MAL page behind it.
per-episode forumnot servedNo 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.

/llms.txtopen

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.