Skip to main content
Migrate to the v2 files before 1 February 2027.The older calendar files (the same paths without the /v2/ segment) are deprecated. They keep regenerating until 1 February 2027, after which they stop updating permanently and will serve stale data.Update your code to read from https://data.simkl.in/calendar/v2/… — the v2 payload is smaller, normalizes every timestamp to UTC, and ships far richer per-show metadata.
No auth required. Calendar data is public — send the standard required URL parameters (client_id, app-name, app-version) and a User-Agent header, but no user Authorization token.
Which IDs can I send/expect? All accepted input identifiers and the keys you’ll see echoed back in responses are listed at Standard media objects → Supported ID keys. Send every ID you have on writes — Simkl picks the first that resolves and ignores the rest. Reminder: slug is response-only (never send it on a request).
Simkl publishes pre-built JSON calendars on its CDN. Use them to power the “Upcoming”, “Next”, “Schedule”, or “Calendar” sections of your app — without per-user API calls. The files are regenerated every 6 hours and cached on a CDN for 5 hours. Check the response’s Last-Modified header to know when they were last refreshed.
The CDN ignores all query strings. Don’t append ?random=... or similar — you’ll just bust the cache for everyone with no benefit. The same URL serves identical content.

Why use these instead of API calls

  • No user Authorization token required (still send client_id, app-name, app-version, and User-Agent like every Simkl request).
  • Hugely cheaper — one file covers thousands of airings across hundreds of shows.
  • Cacheable on the user’s device for hours.
A typical pattern: when the user opens their watchlist, combine the calendar JSON (cached locally for 3–6 hours) with the user’s synced watchlist (also cached) to compute “Next episode airs in 3 days” — without re-syncing the user’s watchlist every time.

Files

Airing next (rolling window — yesterday + next 33 days)

Monthly archives

Three regeneration tiers:
  • Current month + next 3 months ahead — regenerated every 6 hours. Future-month files contain only what’s already been scheduled or announced, so item counts taper off the further ahead you go.
  • Previous 12 months — regenerated every 24 hours.
  • Older than 12 months — archived in place. Files remain queryable indefinitely but are no longer regenerated; Last-Modified freezes at end-of-month.
URL pattern:
Examples for the past month ({{PAST_YEAR}}/{{PAST_MONTH}}) and the furthest future month available right now ({{FUTURE_YEAR}}/{{FUTURE_MONTH}}, which is currentMonth + 3). These dates substitute on page load — they always reflect today:
Requesting any month beyond currentMonth + 3 returns 404.

Response shape

Every v2 file — rolling and monthly, all three catalogs — is a single object with exactly two keys:
calendar is the schedule. metadata is the show library. A show airing 12 episodes this month appears 12 times in calendar but only once in metadata. That’s the whole point of the split: title, poster, IDs, ratings, and genres are stored once instead of being repeated on every airing. To render a row, take a calendar entry and look up its show:
metadata keys are strings. It’s a JSON object, so simkl_id becomes a string key. In JavaScript metadata[entry.simkl_id] works because JS coerces the number to a string on property access. In strongly-typed languages, convert explicitly — Python metadata[str(entry["simkl_id"])], Swift metadata[String(entry.simklId)], Kotlin metadata[entry.simklId.toString()].
Every simkl_id in calendar is guaranteed to have a matching metadata record, and there are no orphan metadata records — the two are always consistent within a single file.

Sample (TV)

calendar[] — the schedule

integer
required
Simkl ID of the show or movie. Join key into metadata (as a string).
string (ISO 8601, UTC)
required
Air / release timestamp, always UTC with a trailing Z — e.g. 2026-07-20T04:00:00Z. Convert to the user’s local timezone for display. Entries are ordered chronologically.
integer | null
required
Marks finale episodes so you can badge them in the UI. null on ordinary episodes and on all movie entries.
object
TV and anime only — the key is absent entirely on movie files (Type 2 null — see Null and missing values). A movie release has no episode, so the whole object is omitted rather than set to null.

metadata{} — the show library

Keyed by simkl_id (as a string). One record per distinct title in the file.
Code defensively — TV records can be sparse. Newly-added shows that Simkl hasn’t finished enriching yet carry only a minimal set of keys (title, url, poster, ids, release_date, rank, ratings) and omit the rest. Anime and movie records are consistently complete, but on TV always use optional access (show.genres ?? [], show?.network) rather than assuming a key exists.
string
required
Display title.
string | null
Anime files only. Romanized title (e.g. Chibi Maruko-chan). Type 4 null when none is on file.
string
required
Link to the title on simkl.com. Normally a root-relative path (/tv/3437/king-of-the-hill) — prefix with https://simkl.com to build a full link. Sparse TV records may instead carry a fully-qualified URL, so normalize before use rather than blindly concatenating.
array
Localized and alternate titles. Each entry is name (string), lang (integer — Simkl internal language code, not ISO 639), and type (one of official, short, synonym, original).
string | null
required
Image path fragment. Combine with the prefixes in Image conventions — for example https://wsrv.nl/?url=https://simkl.in/posters/{poster}_m.webp&q=90. Type 4 null when no poster is on file; fall back to https://simkl.in/poster_no_pic.png (see fallbacks).
string | null
Backdrop image path fragment. Same prefixing rules as poster. Type 4 null when none is on file — commonly absent on new or regional titles.
object
required
External and Simkl IDs. Always carries simkl_id + slug. tmdb is near-universal; imdb / tvdb appear on TV and movies, mal / anidb / anilist / kitsu on anime. Additional slug variants (letterslug, traktmslug, tvdbslug, trakttvslug, mdlslug, jwtv, …) appear on titles with those platform links — the object is permissive, so read the keys you need and ignore the rest.
string | null
required
The title’s original premiere / release date. Normally a full ISO 8601 UTC timestamp (1997-01-12T15:30:00Z); a small number of TV records carry a date-only string (2026-07-13). Parse defensively. Type 4 null when unknown.Note this is the title’s first-ever release — the per-episode air date is calendar[].date.
integer | null
required
Simkl popularity rank. Lower non-zero values = more popular. 0 or Type 4 null for titles that aren’t ranked yet (common on new, upcoming, and regional entries — the majority of movie records are unranked).
string
Percentage of users who started the title and abandoned it, as a display string ("8.5%"). "-" when there’s not enough data. Parse with a parseFloat-style call if you need it numerically.
integer | null
Number of Simkl users who have watched the title. Type 4 null on unreleased titles.
integer | null
Number of Simkl users with the title on their watchlist.
object
required
Aggregate ratings keyed by source. Simkl is always present; the second source is imdb on TV and movies, mal on anime. Individual rating / votes values are Type 4 null on titles with no votes yet.
string | null
Lowercase two-letter country code (us, jp, kr).
string | null
Lowercase two-letter language code (en, ja).
string | null
Episode or feature runtime as a display string ("22m", "1h 57m"). Type 4 null when unknown.
string
Release / airing status. Observed values: ongoing, ended, premiere, soon, and undefined (the literal string, on a handful of un-enriched TV records). Treat this as an open vocabulary — match the values you care about and fall through gracefully on anything else.
integer
TV and anime only. Total episodes on file across all seasons.
string
Anime files only. Catalog format — one of tv, movie, ova, ona, special, music.
string | null
TV and anime only. Broadcasting network or streaming service (Hulu, CBS). Type 4 null when not on file.
string
Movie files only. Physical / digital release date in MM/DD/YYYY format — note this differs from the ISO 8601 release_date.
array
Genre names as display strings (["Animation", "Comedy"]).
string | null
YouTube video ID (not a full URL) — build the link as https://www.youtube.com/watch?v={trailer}. Type 4 null when no trailer is on file, which is the majority of entries.

Worked example — render the next 7 days

Anime differs in two places. calendar[].episode has no season key (use episode.episode alone), and metadata adds title_romaji and anime_type. Movie files have no episode object at all — the calendar entry is just simkl_id, date, and finale_type.