mikai API

API v1

Публічний API Mikai

Каталог аніме з українськими озвученнями та субтитрами, плеєр із розбивкою по командах, україномовні постери з авторством, розклад і стрічка новинок. Ключ не обовʼязковий — він лише підіймає ліміти.

https://api.mikai.me/public/v1OpenAPI 3.1MarkdownОтримати ключ

Огляд

Публічний API Mikai віддає каталог аніме з українськими озвученнями та субтитрами: назви, зовнішні ідентифікатори, плеєр із розбивкою по командах і провайдерах, україномовні постери з авторством, розклад виходу серій і стрічку новинок.

Усі відповіді — JSON у спільному конверті. Успішна відповідь має ok: true і поле result; пагіновані списки додатково повертають total, page і pages, тож рахувати кількість сторінок вручну не треба.

{
  "ok": true,
  "total": 1423,
  "page": 1,
  "pages": 72,
  "result": [  ]
}

Усі мітки часу — RFC3339 в UTC: addedAt, publishedAt, updatedAt, час виходу серії в розкладі. Дати без часу (startDate, birthday) — YYYY-MM-DD.

Описи аніме — українською. Це наш власний текст, а не синопсис з MAL чи AniList.

У блоці episodes поле total — це заплановане число серій; 0 означає «ще невідомо», а не «серій немає». Скільки вже вийшло, каже aired, скільки озвучено або перекладено — localized.
API читальний: жоден ендпоінт не змінює дані на нашому боці. Ключ не обовʼязковий — він лише підіймає ліміти.

Швидкий старт

Ключ не потрібен, щоб почати. Просто зробіть запит:

curl "https://api.mikai.me/public/v1/anime?limit=5"

Без ключа діють невеликі ліміти — їх вистачає, щоб роздивитись API. Для постійного застосунку створіть ключ у профілі, розділ «Для розробників»: https://mikai.me/user/developers. Повний токен показується один раз, одразу після створення.

curl -H "X-API-Key: mk_xxxxxxxx…" \
  "https://api.mikai.me/public/v1/anime?limit=5"

Які ліміти діють саме для вас, показує /me.

curl "https://api.mikai.me/public/v1/me"

Ключ доступу

Ключ необовʼязковий: усі ендпоінти працюють і без нього, просто з меншими лімітами. Ключ підіймає ліміти й дає власний лічильник використання.

Передати його можна двома способами — оберіть той, що зручніший вашому HTTP-клієнту:

X-API-Key: mk_xxxxxxxx…
# або
Authorization: Bearer mk_xxxxxxxx…
Ключ — це секрет. Не вставляйте його у фронтенд-код і в публічні репозиторії: будь-хто, хто його побачить, витрачатиме вашу квоту.
КодКоли трапляється
401Передано недійсний ключ
403Ключ вимкнено
404Ресурс не знайдено
422Некоректні параметри запиту або посилання на аніме
429Перевищено ліміт за хвилину або добову квоту

Помилки

Помилка приходить у тому ж конверті з ok: false. Поле code — стабільний ідентифікатор, на який можна перемикатись у коді; message — людський текст українською, який ми можемо переформулювати будь-коли.

{
  "ok": false,
  "error": {
    "errorCode": 422,
    "code": "invalid_parameter",
    "message": "invalid parameter: sort=\"popularity\" is not one of mal_rating, name, updated, views, year"
  }
}
codeHTTPЩо сталося
invalid_parameter422Невідоме значення параметра — у повідомленні перелічені допустимі
invalid_reference422Некоректне посилання на аніме у {ref}
too_many_ids422У /resolve передано понад 100 значень
invalid_request400Тіло запиту не є коректним JSON
not_found404Ресурс не знайдено
invalid_api_key401Передано недійсний ключ
api_key_disabled403Ключ вимкнено
rate_limited429Вичерпано ліміт за хвилину
quota_exceeded429Вичерпано добову квоту
internal_error500Помилка на нашому боці
Невідоме значення фільтра — це 422, а не порожній список. Так помилка в клієнті не виглядає як «нічого не знайдено».

Ліміти та квоти

Без ключа запити рахуються по IP, з ключем — по ключу.

Спосіб викликуЗа хвилинуЗа добу (UTC)
Без ключа151 000
З ключем6010 000

Кожна відповідь містить поточний стан лічильників:

ЗаголовокЗначення
X-RateLimit-LimitЛіміт запитів за хвилину
X-RateLimit-RemainingСкільки лишилось у поточній хвилині
X-RateLimit-ResetЧерез скільки секунд лічильник обнулиться
X-Quota-LimitДобова квота
X-Quota-RemainingСкільки лишилось на сьогодні
X-Quota-ResetСекунд до опівночі UTC

Після перевищення приходить 429 із заголовком Retry-After. Замість того щоб опитувати каталог по колу, використовуйте /updates?since=… — вона віддає лише те, що зʼявилося після вказаного моменту.

Потрібно більше — напишіть нам, ліміт конкретного ключа можна підняти.

Кешування

Кожна успішна відповідь має ETag і Cache-Control. Надішліть If-None-Match з отриманим раніше тегом — і якщо нічого не змінилось, прийде 304 без тіла.

curl -H 'If-None-Match: "3f2a91c4e0d7"'   "https://api.mikai.me/public/v1/genres"
ЩоЖиве в кеші
/genres, /tags, /studios, /meta1 година
каталог, картка аніме, плеєр, команди5 хвилин
/schedule, /updates, /posters/ua1 хвилина
/me, /health, /anime/randomне кешуються
304 так само коштує один запит за лімітом — економія тут у трафіку й розборі JSON, а не у квоті.

Ідентифікатори

Скрізь, де у шляху стоїть {ref}, можна підставити будь-який відомий ідентифікатор. Без префікса це id Mikai:

GET /anime/1523                    # id Mikai
GET /anime/mal:21                  # MyAnimeList
GET /anime/al:21                   # AniList
GET /anime/hikka:gasdas-one-piece  # Hikka slug
GET /anime/slug:one-piece          # наш slug

Той самий {ref} працює і для вкладених ресурсів: /anime/mal:21/player, /anime/mal:21/posters.

Кожна відповідь про аніме містить повний блок ids, тож одного запиту досить, щоб дізнатись усі відповідники. IMDb у ньому теж є, але шукати за ним не можна: один IMDb-запис описує всю франшизу, а не окремий сезон.

Рядок без префікса, який не є числом (наприклад one-piece), повертає 422 з підказкою — щоб помилка в клієнті не виглядала як «аніме немає».

Коли треба зіставити багато ідентифікаторів одразу, беріть /resolve: до 100 значень за один запит, і за лімітами це коштує один запит.

Аніме, вкладене в іншу відповідь — у розкладі, стрічці новинок, звʼязаних тайтлах — приходить скорочено: ids, titles і images. Решта полів там просто не читається з бази, тому ми їх і не показуємо; повна картка — за /anime/{ref}.

Зображення

API віддає готові абсолютні посилання — збирати їх вручну не треба. Кожне зображення доступне у трьох розмірах і двох форматах:

{
  "big":    { "webp": "https://images.mikai.me/poster/big/70733847-…webp",
              "jpg":  "https://images.mikai.me/poster/big/70733847-….jpg" },
  "medium": {  },
  "small":  {  }
}
РозмірНайбільша сторона
big1600 px
medium900 px
small400 px

Файли віддаються з Cache-Control: immutable — їх можна безпечно кешувати надовго.

Використання та атрибуція

Дані можна використовувати у власних застосунках, ботах і сайтах. Просимо про три речі:

  • вказуйте джерело — посилання на mikai.me;
  • зберігайте авторство команд озвучення та авторів постерів — воно приходить у полях team та author;
  • не використовуйте API для масового дзеркалювання відео — посилання на плеєри належать провайдерам.

Аніме під жорсткою українською ліцензією повертаються без джерел: licensed: true і порожній releases. Блок license при цьому каже, хто ліцензіат і де дивитись легально — покажіть це замість порожнього плеєра. Інші ліцензії на видачу не впливають.

Версії та сумісність

Версія контракту приходить у /meta як version. У межах /public/v1 ми можемо додавати нові поля й ендпоінти — тому ваш клієнт має ігнорувати незнайомі поля, а не падати на них.

  • нове поле у відповіді або новий необовʼязковий параметр — не ламає сумісність і може зʼявитись будь-коли;
  • видалення чи перейменування поля, зміна типу — тільки в новій версії шляху (/public/v2);
  • стару версію ми тримаємо щонайменше пів року після виходу нової й попереджаємо в контактах.
Значення enum-полів теж можуть поповнюватись. Замість того щоб зашивати списки, звіряйтесь із /meta — там і формати, і статуси, і допустимі поля сортування.

Аніме

Каталог, детальна інформація та схожі тайтли.

GET/public/v1/anime

Список аніме

Пагінований каталог з короткою інформацією. Фільтри збігаються з тими, що працюють на сайті. Якщо передано search, результати впорядковані за релевантністю, а sort і order ігноруються.

Параметри

search stringПошук за назвою (українською, англійською або оригінальною)
genres string[]Жанри через кому — значення поля name з /genres
genresExclude string[]Жанри, яких не має бути
genresMatch string = allall — усі перелічені жанри, any — будь-який із них
tags string[]Теги через кому — значення поля name з /tags
tagsExclude string[]Теги, яких не має бути
tagsMatch string = allall або any
years string[]Конкретні роки через кому, наприклад 1999,2003
yearFrom intРік від
yearTo intРік до
seasons string[]winter, spring, summer, autumn, unknown
formats string[]tv, movie, special, ova, ona, music, other, unknown
statuses string[]finished, ongoing, announce, cancelled, break, unknown
studios string[]Студії через кому
teams int[]ID команд озвучення через кому
sort string = namename, year, updated (за останньою доданою серією), views, mal_rating
order stringasc або desc. За замовчуванням asc для name і desc для решти полів
page int = 1Номер сторінки
limit int = 20Розмір сторінки, максимум 100

Запит

curl "https://api.mikai.me/public/v1/anime?statuses=ongoing&limit=2"

Відповідь

{
  "ok": true,
  "total": 214,
  "page": 1,
  "pages": 107,
  "result": [
    {
      "ids": { "mikai": 1523, "slug": "one-piece", "mal": 21,
               "al": 21, "hikka": "gasdas-one-piece", "imdb": "tt0388629" },
      "titles": { "ua": "Ван Піс", "english": "One Piece", "original": "ワンピース" },
      "images": {
        "poster": { "big": { "webp": "https://images.mikai.me/poster/big/….webp",
                             "jpg":  "https://images.mikai.me/poster/big/….jpg" } }
      },
      "format": "tv",
      "status": "ongoing",
      "season": "autumn",
      "year": 1999,
      "episodes": 0,
      "isAdult": false
    }
  ]
}
GET/public/v1/anime/{ref}

Детальна інформація

Усе про тайтл одним запитом: опис, жанри й теги, оцінки, вікове обмеження, країна, класифікація серій (філери/канон), звʼязані тайтли, схожі, україномовні постери та зведення релізів. Окремо доводиться питати лише список серій — він на /anime/{ref}/player.

Параметри

ref * stringБудь-який ідентифікатор: 1523, mal:21, al:21, hikka:…, slug:…
include string[]Звузити відповідь до потрібних блоків: releases, uaPosters, relations, similar. За замовчуванням приходять усі

Запит

curl "https://api.mikai.me/public/v1/anime/mal:21"

Відповідь

{
  "ok": true,
  "result": {
    "ids": { "mikai": 1523, "slug": "one-piece", "mal": 21, "al": 21 },
    "titles": { "ua": "Ван Піс", "english": "One Piece" },
    "description": "…",
    "format": "tv",
    "status": "ongoing",
    "startDate": "1999-10-20",
    "source": "manga",
    "studio": "Toei Animation",
    "country": "JP",
    "ageRating": "pg13",
    "episodes": { "total": 0, "aired": 1122, "localized": 640, "durationMin": 24 },
    "scores": { "mikai": 9.1, "mikaiCount": 812, "mal": 8.73, "malCount": 1400000 },
    "genres": [ { "name": "Action", "ua": "Бойовик" } ],
    "tags": [ { "name": "Pirates", "ua": "Пірати" } ],
    "episodeTypes": { "filler": [ { "from": 54, "to": 60 } ] },
    "licensed": false,
    "releases": [
      {
        "id": "t_45:voice",
        "kind": "voice",
        "isCollab": false,
        "teams": [ { "id": 45, "slug": "fanvoxua", "name": "FanVoxUA" } ],
        "episodesCount": 640,
        "lastEpisode": 640,
        "updatedAt": "2026-08-20T10:00:00Z"
      }
    ],
    "uaPosters": [ { "id": 7, "isSelected": true, "author": "Оксана К.", "team": {  }, "images": {  } } ],
    "relations": [ { "kind": "sideStory", "anime": {  } } ],
    "similar": [ { "ids": { "mikai": 902, "mal": 6702 }, "titles": { "ua": "Фейрі Тейл" }, "format": "tv",  } ]
  }
}
GET/public/v1/anime/random

Випадкове аніме

Коротка картка випадкового тайтлу.

Запит

curl "https://api.mikai.me/public/v1/anime/random"
GET/public/v1/resolve

Резолв ідентифікаторів (GET)

Те саме, що POST-версія, але списком у query — зручно перевірити руками або з клієнта, який не вміє слати тіло в GET.

Параметри

source * stringmal, al, hikka, slug або mikai
ids * string[]До 100 значень через кому

Запит

curl "https://api.mikai.me/public/v1/resolve?source=mal&ids=1,21,999999999"
POST/public/v1/resolve

Батч-резолв ідентифікаторів

Зіставляє до 100 зовнішніх ідентифікаторів з нашими за один запит. Значення, яких у нас немає, повертаються як null.

Параметри

source * stringmal, al, hikka, slug або mikai
ids * arrayДо 100 значень

Запит

curl -X POST -H "Content-Type: application/json" \
  -d '{"source":"mal","ids":[1,21,999999999]}' \
  "https://api.mikai.me/public/v1/resolve"

Відповідь

{
  "ok": true,
  "result": {
    "1":  { "mikai": 12, "slug": "cowboy-bebop", "mal": 1, "al": 1 },
    "21": { "mikai": 1523, "slug": "one-piece", "mal": 21, "al": 21 },
    "999999999": null
  }
}

Плеєр

Озвучення та субтитри, згруповані по релізах.

GET/public/v1/anime/{ref}/player

Серії та джерела

Список серій. Реліз — це одна команда (або колаборація) і один трек: озвучення voice чи субтитри sub. Усередині релізу серії лежать плоским списком, а кожна серія містить масив sources з усіма провайдерами, які її хостять. Якщо серії не потрібні, те саме зведення релізів уже є в детальній картці аніме.

Параметри

ref * stringІдентифікатор аніме
episodes bool = truefalse — повернути тільки зведення релізів, без списку серій

Запит

curl "https://api.mikai.me/public/v1/anime/mal:21/player"

Відповідь

{
  "ok": true,
  "result": {
    "anime": { "ids": { "mikai": 1523, "mal": 21 }, "titles": { "ua": "Ван Піс" } },
    "licensed": false,
    "releases": [
      {
        "id": "t_45:voice",
        "kind": "voice",
        "isCollab": false,
        "teams": [ { "id": 45, "slug": "fanvoxua", "name": "FanVoxUA" } ],
        "episodesCount": 640,
        "lastEpisode": 640,
        "updatedAt": "2026-08-20T10:00:00Z",
        "episodes": [
          {
            "number": 640,
            "label": "640",
            "kind": "mangaCanon",
            "addedAt": "2026-08-20T10:00:00Z",
            "sources": [
              { "provider": "ashdi", "embedUrl": "https://…", "addedAt": "2026-08-20T10:00:00Z" },
              { "provider": "moon",  "embedUrl": "https://…", "addedAt": "2026-08-20T10:02:00Z" }
            ]
          }
        ]
      }
    ]
  }
}
GET/public/v1/updates

Стрічка новинок

Щойно опубліковані серії по всьому сайту, найновіші першими. Це найдешевший спосіб тримати дзеркало або канал у Telegram актуальним: передавайте since з часом попереднього запиту. Поле teams влаштоване так само, як у плеєрі: для колаборації воно містить усі команди, що працювали над релізом, і isCollab: true. Одна серія, яку хостять кілька провайдерів, приходить окремим записом на кожного.

Параметри

since stringМітка часу RFC3339 — повернути лише те, що зʼявилось пізніше
page int = 1Номер сторінки
limit int = 20Розмір сторінки, максимум 100

Запит

curl "https://api.mikai.me/public/v1/updates?since=2026-08-25T00:00:00Z&limit=50"

Відповідь

{
  "ok": true,
  "total": 87,
  "result": [
    {
      "anime": { "ids": { "mikai": 1523, "mal": 21 }, "titles": { "ua": "Ван Піс" } },
      "teams": [ { "id": 45, "slug": "fanvoxua", "name": "FanVoxUA" } ],
      "isCollab": false,
      "teamName": "FanVoxUA",
      "kind": "voice",
      "provider": "ashdi",
      "episode": 640,
      "embedUrl": "https://…",
      "publishedAt": "2026-08-25T18:12:00Z"
    }
  ]
}

Постери

Україномовні постери з інформацією про авторство.

GET/public/v1/anime/{ref}/posters

Постери одного аніме

Оригінальна обкладинка плюс усі україномовні постери. Для кожного приходить команда, яка його опублікувала, та особистий автор, якщо він відомий.

Параметри

ref * stringІдентифікатор аніме

Запит

curl "https://api.mikai.me/public/v1/anime/mal:21/posters"

Відповідь

{
  "ok": true,
  "result": {
    "anime": { "ids": { "mikai": 1523, "mal": 21 } },
    "original": { "big": { "webp": "https://images.mikai.me/poster/big/….webp", "jpg": "…" } },
    "uaPosters": [
      {
        "id": 7,
        "isSelected": true,
        "author": "Оксана К.",
        "team": { "id": 45, "slug": "fanvoxua", "name": "FanVoxUA" },
        "images": {
          "big":    { "webp": "https://images.mikai.me/ua_poster/big/70733847-7883-11f1-b061-96742946622a.webp",
                      "jpg":  "https://images.mikai.me/ua_poster/big/70733847-7883-11f1-b061-96742946622a.jpg" },
          "medium": {  },
          "small":  {  }
        }
      }
    ]
  }
}
GET/public/v1/posters/ua

Стрічка всіх постерів

Усі україномовні постери з пагінацією — для дзеркал і галерей. Кожен запис несе аніме, до якого належить.

Параметри

since stringМітка часу RFC3339
page int = 1Номер сторінки
limit int = 20Розмір сторінки, максимум 100

Запит

curl "https://api.mikai.me/public/v1/posters/ua?limit=50"

Команди

Команди озвучення та субтитрування і їхні роботи.

GET/public/v1/teams

Список команд

Параметри

search stringПошук за назвою
haveVoice boolЛише ті, хто озвучує
haveSubs boolЛише ті, хто робить субтитри
sort string = namename, count (кількість тайтлів), updated (за останнім релізом)
order stringasc або desc. За замовчуванням asc для name і desc для решти
page int = 1Номер сторінки
limit int = 20Розмір сторінки, максимум 50

Запит

curl "https://api.mikai.me/public/v1/teams?haveVoice=true&limit=5"
GET/public/v1/teams/{ref}

Інформація про команду

Приймає числовий id або slug команди. views — скільки разів дивилися серії команди на Mikai; серії, випущені в колаборації, зараховуються кожній команді з неї.

Параметри

ref * stringID або slug команди

Запит

curl "https://api.mikai.me/public/v1/teams/fanvoxua"

Відповідь

{
  "ok": true,
  "result": {
    "id": 45,
    "slug": "fanvoxua",
    "name": "FanVoxUA",
    "description": "…",
    "birthday": "2018-04-12",
    "avatar": { "big": { "webp": "…", "jpg": "…" } },
    "links": { "telegram": "https://t.me/…", "youtube": "https://…" },
    "hasVoice": true,
    "hasSubs": false,
    "animeCount": 128,
    "views": { "total": 4210533, "last30Days": 118904, "monthlyAvg": 96500 }
  }
}
GET/public/v1/teams/{ref}/anime

Роботи команди

Параметри

ref * stringID або slug команди
page int = 1Номер сторінки
limit int = 20Розмір сторінки, максимум 100

Запит

curl "https://api.mikai.me/public/v1/teams/fanvoxua/anime"

Довідники

Розклад, словники та самоопис API.

GET/public/v1/schedule

Розклад виходу серій

Обʼєкт із сімома ключами — від monday до sunday. Усі дні присутні завжди, навіть порожні. День визначається за київським часом виходу серії, а саме поле airing приходить у UTC.

Запит

curl "https://api.mikai.me/public/v1/schedule"

Відповідь

{
  "ok": true,
  "result": {
    "monday": [
      {
        "anime": { "ids": { "mikai": 1523, "mal": 21 }, "titles": { "ua": "Ван Піс" } },
        "episode": 641,
        "airing": "2026-08-31T06:30:00Z",
        "finished": false
      }
    ],
    "tuesday": []
  }
}
GET/public/v1/genres

Жанри

Канонічні назви жанрів та їхні українські відповідники. Значення поля name — те, що приймає фільтр genres.

Запит

curl "https://api.mikai.me/public/v1/genres"
GET/public/v1/tags

Теги

Канонічні назви тегів та їхні українські відповідники. Значення поля name — те, що приймає фільтр tags.

Запит

curl "https://api.mikai.me/public/v1/tags"
GET/public/v1/studios

Студії

Перелік студій-виробників для фільтра studios.

Запит

curl "https://api.mikai.me/public/v1/studios"
GET/public/v1/meta

Самоопис API

Усі допустимі значення enum-полів і полів сортування, розміри та формати зображень, чинні ліміти й версія контракту. Зручно звіряти клієнт із живим сервером замість того, щоб зашивати списки в код.

Запит

curl "https://api.mikai.me/public/v1/meta"

Відповідь

{
  "ok": true,
  "result": {
    "version": "1.0",
    "formats": [ "tv", "movie",  ],
    "statuses": [ "finished", "ongoing",  ],
    "relationKinds": [ "prequel", "sequel", "sideStory",  ],
    "animeSortFields": [ "mal_rating", "name", "updated", "views", "year" ],
    "teamSortFields": [ "count", "name", "updated" ],
    "sortOrders": [ "asc", "desc" ],
    "matchModes": [ "all", "any" ],
    "detailIncludes": [ "releases", "uaPosters", "relations", "similar" ],
    "limits": {
      "anonymous": { "rateLimitPerMin": 15, "dailyQuota": 1000 },
      "withKey":   { "rateLimitPerMin": 60, "dailyQuota": 10000 }
    },
    "maxPageSize": 100,
    "maxTeamPageSize": 50
  }
}
GET/public/v1/me

Поточні ліміти

Які ліміти діють для цього виклику і скільки з них уже витрачено. Без ключа повертає ліміти анонімного доступу.

Запит

curl "https://api.mikai.me/public/v1/me"
GET/public/v1/health

Перевірка доступності

Запит

curl "https://api.mikai.me/public/v1/health"

Знайшли помилку або бракує ендпоінта? Напишіть нам — контакти.

mikai.me