diff --git a/src/all/torrentioanime/build.gradle b/src/all/torrentioanime/build.gradle
index 52ec219c..258789ef 100644
--- a/src/all/torrentioanime/build.gradle
+++ b/src/all/torrentioanime/build.gradle
@@ -1,7 +1,7 @@
 ext {
     extName = 'Torrentio Anime (Torrent / Debrid)'
     extClass = '.Torrentio'
-    extVersionCode = 14
+    extVersionCode = 15
     containsNsfw = false
 }
 
diff --git a/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/Torrentio.kt b/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/Torrentio.kt
index 007f9cc6..021cf57f 100644
--- a/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/Torrentio.kt
+++ b/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/Torrentio.kt
@@ -10,10 +10,10 @@ import androidx.preference.ListPreference
 import androidx.preference.MultiSelectListPreference
 import androidx.preference.PreferenceScreen
 import androidx.preference.SwitchPreferenceCompat
+import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.AniZipResponse
 import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.AnilistMeta
 import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.AnilistMetaLatest
 import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.DetailsById
-import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.EpisodeList
 import eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto.StreamDataTorrent
 import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
 import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
@@ -66,6 +66,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
             .add("query", query)
             .add("variables", variables)
             .build()
+
         return POST("https://graphql.anilist.co", body = requestBody)
     }
 
@@ -148,7 +149,8 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
 
     override fun popularAnimeParse(response: Response): AnimesPage {
         val jsonData = response.body.string()
-        return parseSearchJson(jsonData) }
+        return parseSearchJson(jsonData)
+    }
 
     // =============================== Latest ===============================
     override fun latestUpdatesRequest(page: Int): Request {
@@ -300,41 +302,55 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
 
     // ============================== Episodes ==============================
     override fun episodeListRequest(anime: SAnime): Request {
-        return GET("https://anime-kitsu.strem.fun/meta/series/anilist%3A${anime.url}.json")
+        return GET("https://api.ani.zip/mappings?anilist_id=${anime.url}")
     }
 
     override fun episodeListParse(response: Response): List<SEpisode> {
         val responseString = response.body.string()
-        val episodeList = json.decodeFromString<EpisodeList>(responseString)
+        val aniZipResponse = json.decodeFromString<AniZipResponse>(responseString)
 
-        return when (episodeList.meta?.type) {
-            "series" -> {
-                episodeList.meta.videos
-                    ?.let { videos ->
-                        if (preferences.getBoolean(UPCOMING_EP_KEY, UPCOMING_EP_DEFAULT)) { videos } else { videos.filter { video -> (video.released?.let { parseDate(it) } ?: 0L) <= System.currentTimeMillis() } }
+        return when (aniZipResponse.mappings?.type) {
+            "TV" -> {
+                aniZipResponse.episodes
+                    ?.let { episodes ->
+                        if (preferences.getBoolean(UPCOMING_EP_KEY, UPCOMING_EP_DEFAULT)) {
+                            episodes
+                        } else {
+                            episodes.filter { (_, episode) -> (episode?.airDate?.let { parseDate(it) } ?: 0L) <= System.currentTimeMillis() }
+                        }
                     }
-                    ?.map { video ->
+                    ?.mapNotNull { (_, episode) ->
+                        val episodeNumber = runCatching { episode?.episode?.toFloat() }.getOrNull()
+
+                        if (episodeNumber == null) {
+                            return@mapNotNull null
+                        }
+
+                        val title = episode?.title?.get("en")
+
                         SEpisode.create().apply {
-                            episode_number = video.episode?.toFloat() ?: 0.0F
-                            url = "/stream/series/${video.videoId}.json"
-                            date_upload = video.released?.let { parseDate(it) } ?: 0L
-                            name = "Episode ${video.episode} : ${
-                                video.title?.removePrefix("Episode ")
-                                    ?.replaceFirst("\\d+\\s*".toRegex(), "")
-                                    ?.trim()
-                            }"
-                            scanlator = (video.released?.let { parseDate(it) } ?: 0L).takeIf { it > System.currentTimeMillis() }?.let { "Upcoming" } ?: ""
+                            episode_number = episodeNumber
+                            url = "/stream/series/kitsu:${aniZipResponse.mappings.kitsuId}:${String.format(Locale.ENGLISH, "%.0f", episodeNumber)}.json"
+                            date_upload = episode?.airDate?.let { parseDate(it) } ?: 0L
+                            name = if (title == null) "Episode ${episode?.episode}" else "Episode ${episode.episode}: $title"
+                            scanlator = (episode?.airDate?.let { parseDate(it) } ?: 0L).takeIf { it > System.currentTimeMillis() }?.let { "Upcoming" } ?: ""
                         }
                     }.orEmpty().reversed()
             }
 
-            "movie" -> {
-                // Handle movie response
+            "MOVIE" -> {
+                val dateUpload = if (!aniZipResponse.episodes.isNullOrEmpty()) {
+                    aniZipResponse.episodes["1"]?.airDate?.let { parseDate(it) } ?: 0L
+                } else {
+                    0L
+                }
+
                 listOf(
                     SEpisode.create().apply {
                         episode_number = 1.0F
-                        url = "/stream/movie/${episodeList.meta.kitsuId}.json"
+                        url = "/stream/movie/kitsu:${aniZipResponse.mappings.kitsuId}.json"
                         name = "Movie"
+                        date_upload = dateUpload
                     },
                 ).reversed()
             }
@@ -342,6 +358,12 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
             else -> emptyList()
         }
     }
+
+    private fun parseDateTime(dateStr: String): Long {
+        return runCatching { DATE_TIME_FORMATTER.parse(dateStr)?.time }
+            .getOrNull() ?: 0L
+    }
+
     private fun parseDate(dateStr: String): Long {
         return runCatching { DATE_FORMATTER.parse(dateStr)?.time }
             .getOrNull() ?: 0L
@@ -421,6 +443,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
             udp://www.torrent.eu.org:451/announce,
             ${fetchTrackers().split("\n").joinToString(",")}
         """.trimIndent()
+
         return streamList.streams?.map { stream ->
             val urlOrHash =
                 if (debridProvider == "none") {
@@ -875,8 +898,12 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
         private const val IS_EFFICIENT_KEY = "efficient"
         private const val IS_EFFICIENT_DEFAULT = false
 
-        private val DATE_FORMATTER by lazy {
+        private val DATE_TIME_FORMATTER by lazy {
             SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH)
         }
+
+        private val DATE_FORMATTER by lazy {
+            SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
+        }
     }
 }
diff --git a/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/dto/AniZipDto.kt b/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/dto/AniZipDto.kt
new file mode 100644
index 00000000..b555f3f2
--- /dev/null
+++ b/src/all/torrentioanime/src/eu/kanade/tachiyomi/animeextension/all/torrentioanime/dto/AniZipDto.kt
@@ -0,0 +1,67 @@
+package eu.kanade.tachiyomi.animeextension.all.torrentioanime.dto
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class AniZipResponse(
+    val titles: Map<String, String?>? = null,
+    val episodes: Map<String, AniZipEpisode?>? = null,
+    val episodeCount: Int? = null,
+    val specialCount: Int? = null,
+    val images: List<AniZipImage?>? = null,
+    val mappings: AniZipMappings? = null,
+)
+
+@Serializable
+data class AniZipEpisode(
+    val episode: String? = null,
+    val episodeNumber: Int? = null,
+    val absoluteEpisodeNumber: Int? = null,
+    val seasonNumber: Int? = null,
+    val title: Map<String, String?>? = null,
+    val length: Int? = null,
+    val runtime: Int? = null,
+    @SerialName("airdate")
+    val airDate: String? = null,
+    val rating: String? = null,
+    @SerialName("anidbEid")
+    val aniDbEpisodeId: Long? = null,
+    val tvdbShowId: Long? = null,
+    val tvdbId: Long? = null,
+    val overview: String? = null,
+    val image: String? = null,
+)
+
+@Serializable
+data class AniZipImage(
+    val coverType: String? = null,
+    val url: String? = null,
+)
+
+@Serializable
+data class AniZipMappings(
+    @SerialName("animeplanet_id")
+    val animePlanetId: String? = null,
+    @SerialName("kitsu_id")
+    val kitsuId: Long? = null,
+    @SerialName("mal_id")
+    val myAnimeListId: Long? = null,
+    val type: String? = null,
+    @SerialName("anilist_id")
+    val aniListId: Long? = null,
+    @SerialName("anisearch_id")
+    val aniSearchId: Long? = null,
+    @SerialName("anidb_id")
+    val aniDbId: Long? = null,
+    @SerialName("notifymoe_id")
+    val notifyMoeId: String? = null,
+    @SerialName("livechart_id")
+    val liveChartId: Long? = null,
+    @SerialName("thetvdb_id")
+    val theTvDbId: Long? = null,
+    @SerialName("imdb_id")
+    val imdbId: String? = null,
+    @SerialName("themoviedb_id")
+    val theMovieDbId: String? = null,
+)