Tsuzuki
Home › API

Tsuzuki API v1 · FREE · NO KEY

A read-only REST API for anime airing schedules. Unlike the upstream data it is built on, every episode comes back with the release variants that actually exist — the Japanese broadcast, the subtitled simulcast and the English dub — and with human corrections for delays and broadcast breaks already applied.

Try it now → Open the calendar

Why not just call AniList?

You should, for most things — this API is built on AniList and credits it everywhere. But AniList publishes one time per episode: the Japanese TV broadcast. It has no field for when Crunchyroll actually posts the sub, no dub dates at all, and no way to say "this week's episode was pre-empted by a sports block."

That correction layer is what this API adds. If you only need Japanese broadcast times, go straight to AniList and skip the hop.

Conventions

ItemDetail
Base URLhttps://tsuzuki.top/api/v1
AuthNone. No key, no signup.
FormatJSON. Every response has an ok boolean; errors add error and sometimes hint.
TimesUnix seconds in airingAt, plus an ISO-8601 UTC string in airingAtIso. Convert to your own timezone.
CORSOpen to any origin — call it straight from a browser.
CachingResponses are CDN-cached for 5 minutes. Cache on your side too; do not poll faster than the data changes.
Rate limitRoughly 60 requests/minute per client. Over it you get 429 with Retry-After.
Adult titlesExcluded by default. Pass includeAdult=1 on /schedule if you need them.
FreshnessAnswers come from a server-side catalog refreshed every few hours, not from a live upstream call per request. GET /api/v1 reports each cached season's age under catalog.
Attribution is required. If you ship anything public on top of this, credit AniList (the underlying data) and Tsuzuki (the corrections), both with a visible link. This runs on a free tier — bulk scraping will get blocked, but asking first almost never will. Ask in the Discord.

The air-type model

Every episode entry carries an airType and two honesty flags:

FieldMeaning
airTyperaw (Japanese broadcast), sub (subtitled simulcast), or dub (English dub).
exacttrue when the time comes from the broadcast schedule or a confirmed correction.
estimatedtrue when we derived the time rather than confirming it — currently only for subs on a known simulcast platform, where we fall back to the broadcast time. Never shown to a user without a marker; please do the same.
platformWhere that release lands, when known.
notenull, or {kind, reason, source} where kind is delay, break, early or note.
isBreaktrue when there is no episode in that slot. Break entries have a null airingAt and never appear in /schedule.

A dub entry only exists where someone has confirmed a dub date. We would rather return nothing than a date we invented — so an absent dub means "unknown", not "no dub".

Endpoints

GET /api/v1

Service description and the machine-readable endpoint list.

GET /api/v1/schedule

Corrected schedule for a date window. This is the endpoint most people want.

ParamDefaultNotes
starttodayYYYY-MM-DD, interpreted as UTC.
days71–31.
airTypeallraw, sub or dub.
platformExact platform name, e.g. Crunchyroll.
formatTV, TV_SHORT, MOVIE, ONA, OVA, SPECIAL.
includeAdultoff1 to include adult titles.
curl "https://tsuzuki.top/api/v1/schedule?days=1&airType=sub&platform=Crunchyroll"
{
  "ok": true,
  "query": { "start": "2026-08-04", "days": 1, "airType": "sub", "platform": "Crunchyroll" },
  "count": 12,
  "episodes": [
    {
      "mediaId": 128757,
      "episode": 5,
      "airType": "sub",
      "airingAt": 1754321400,
      "airingAtIso": "2026-08-04T13:30:00.000Z",
      "exact": true,
      "estimated": false,
      "platform": "Crunchyroll",
      "isBreak": false,
      "note": null,
      "title": "Young Ladies Don't Play Fighting Games",
      "coverImage": "https://s4.anilist.co/…"
    }
  ],
  "attribution": "Data from AniList, corrected by Tsuzuki."
}

GET /api/v1/anime/{anilistId}

One title with its full per-episode variant schedule, plus the raw corrections record if one exists. Break weeks are included here. Add ?full=1 for the untouched media record instead of the summary shape.

curl "https://tsuzuki.top/api/v1/anime/128757"

GET /api/v1/seasons/{season}/{year}

A season's lineup, each title with its nextEpisode already resolved through the correction layer. season is winter, spring, summer or fall. ?full=1 returns the complete media records — that is what the Tsuzuki app itself loads.

curl "https://tsuzuki.top/api/v1/seasons/summer/2026"

GET /api/v1/airing

Currently-airing titles that AniList never assigned a season to — Korean and Chinese productions, and long-running ONAs that don't map onto a Japanese broadcast season. A season query cannot reach these by construction, so if you build a calendar the way everyone does (three seasons calls around the date you care about) you will silently miss them. They are already folded into /schedule; this endpoint exists for consumers that page season by season. ?full=1 behaves as it does on seasons.

curl "https://tsuzuki.top/api/v1/airing"

GET /api/v1/franchise/{anilistId}

Every anime in the same franchise, in release order. Upstream only ever gives a title its direct relations, so asking season 3 what it belongs to gets you seasons 2 and 4 and nothing else. This walks the whole relation graph and returns the lot — seasons, movies, OVAs, specials, spin-offs — each with the relationLabel that placed it there and isRoot on the title you asked about.

Entries are sorted by start date. One known only to the year sorts after everything precisely dated in that year, and one with no date at all sorts last. Very large franchises are capped; truncated tells you when that happened.

curl "https://tsuzuki.top/api/v1/franchise/16498"

GET /api/v1/search

Title search. q is a fragment of any title (English, romaji or native), limit is 1–25 and defaults to 12. Answers from the seasons already cached where it can and reaches upstream only for titles outside them — source in the response says which happened. ?full=1 returns complete media records.

curl "https://tsuzuki.top/api/v1/search?q=frieren"

GET /api/v1/overrides

The raw correction document — every offset rule, exact time and delay/break note we hold, keyed by AniList id. Useful if you want to apply the corrections yourself against data you already have. The schema is documented inside /data/overrides.json.

Errors

StatusMeans
400A parameter is malformed. error says which.
404Unknown endpoint, or no anime with that id.
429Rate limited. Wait Retry-After seconds.
502 / 503Upstream AniList failed or rate-limited us. Retry shortly.
Found a wrong time? The corrections are only as good as what gets reported. Open any show on the calendar and use ⚠ Report a wrong time — fixes go live for every API consumer within minutes.