{
  "components": {
    "schemas": {
      "Envelope": {
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "result": {
            "description": "Корисне навантаження ендпоінта"
          },
          "total": {
            "description": "Загальна кількість елементів у пагінованих відповідях",
            "type": "integer"
          }
        },
        "required": [
          "ok"
        ],
        "type": "object"
      },
      "Error": {
        "properties": {
          "error": {
            "properties": {
              "errorCode": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "const": false,
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "IDs": {
        "properties": {
          "al": {
            "type": [
              "integer",
              "null"
            ]
          },
          "hikka": {
            "type": [
              "string",
              "null"
            ]
          },
          "imdb": {
            "description": "Довідкове поле: за ним не можна шукати, бо один IMDb-запис описує всю франшизу",
            "type": [
              "string",
              "null"
            ]
          },
          "mal": {
            "type": [
              "integer",
              "null"
            ]
          },
          "mikai": {
            "type": "integer"
          },
          "slug": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ImageFormats": {
        "properties": {
          "jpg": {
            "format": "uri",
            "type": "string"
          },
          "webp": {
            "format": "uri",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ImageSet": {
        "properties": {
          "big": {
            "$ref": "#/components/schemas/ImageFormats"
          },
          "medium": {
            "$ref": "#/components/schemas/ImageFormats"
          },
          "small": {
            "$ref": "#/components/schemas/ImageFormats"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "apiKey": {
        "description": "Необовʼязковий ключ, створений у налаштуваннях профілю. Підіймає ліміти.",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "bearer": {
        "description": "Той самий необовʼязковий ключ, переданий як Bearer-токен.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Публічний API каталогу аніме з українськими озвученнями та субтитрами. Ключ необовʼязковий.",
    "title": "Mikai Public API",
    "version": "1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/anime": {
      "get": {
        "description": "Пагінований каталог з короткою інформацією. Фільтри збігаються з тими, що працюють на сайті. Якщо передано search, результати впорядковані за релевантністю, а sort і order ігноруються.",
        "operationId": "animeList",
        "parameters": [
          {
            "description": "Пошук за назвою (українською, англійською або оригінальною)",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Жанри через кому — значення поля name з /genres",
            "in": "query",
            "name": "genres",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "Жанри, яких не має бути",
            "in": "query",
            "name": "genresExclude",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "all — усі перелічені жанри, any — будь-який із них",
            "in": "query",
            "name": "genresMatch",
            "required": false,
            "schema": {
              "default": "all",
              "type": "string"
            }
          },
          {
            "description": "Теги через кому — значення поля name з /tags",
            "in": "query",
            "name": "tags",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "Теги, яких не має бути",
            "in": "query",
            "name": "tagsExclude",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "all або any",
            "in": "query",
            "name": "tagsMatch",
            "required": false,
            "schema": {
              "default": "all",
              "type": "string"
            }
          },
          {
            "description": "Конкретні роки через кому, наприклад 1999,2003",
            "in": "query",
            "name": "years",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "Рік від",
            "in": "query",
            "name": "yearFrom",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Рік до",
            "in": "query",
            "name": "yearTo",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "winter, spring, summer, autumn, unknown",
            "in": "query",
            "name": "seasons",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "tv, movie, special, ova, ona, music, other, unknown",
            "in": "query",
            "name": "formats",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "finished, ongoing, announce, cancelled, break, unknown",
            "in": "query",
            "name": "statuses",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "Студії через кому",
            "in": "query",
            "name": "studios",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          {
            "description": "ID команд озвучення через кому",
            "in": "query",
            "name": "teams",
            "required": false,
            "schema": {
              "items": {
                "type": "integer"
              },
              "type": "array"
            }
          },
          {
            "description": "name, year, updated (за останньою доданою серією), views, mal_rating",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": "name",
              "type": "string"
            }
          },
          {
            "description": "asc або desc. За замовчуванням asc для name і desc для решти полів",
            "in": "query",
            "name": "order",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Номер сторінки",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": "1",
              "type": "integer"
            }
          },
          {
            "description": "Розмір сторінки, максимум 100",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": "20",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "page": 1,
                  "pages": 107,
                  "result": [
                    {
                      "episodes": 0,
                      "format": "tv",
                      "ids": {
                        "al": 21,
                        "hikka": "gasdas-one-piece",
                        "imdb": "tt0388629",
                        "mal": 21,
                        "mikai": 1523,
                        "slug": "one-piece"
                      },
                      "images": {
                        "poster": {
                          "big": {
                            "jpg": "https://images.mikai.me/poster/big/….jpg",
                            "webp": "https://images.mikai.me/poster/big/….webp"
                          }
                        }
                      },
                      "isAdult": false,
                      "season": "autumn",
                      "status": "ongoing",
                      "titles": {
                        "english": "One Piece",
                        "original": "ワンピース",
                        "ua": "Ван Піс"
                      },
                      "year": 1999
                    }
                  ],
                  "total": 214
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Список аніме",
        "tags": [
          "Аніме"
        ]
      }
    },
    "/anime/random": {
      "get": {
        "description": "Коротка картка випадкового тайтлу.",
        "operationId": "animeRandom",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Випадкове аніме",
        "tags": [
          "Аніме"
        ]
      }
    },
    "/anime/{ref}": {
      "get": {
        "description": "Усе про тайтл одним запитом: опис, жанри й теги, оцінки, вікове обмеження, країна, класифікація серій (філери/канон), звʼязані тайтли, схожі, україномовні постери та зведення релізів. Окремо доводиться питати лише список серій — він на /anime/{ref}/player.",
        "operationId": "animeDetail",
        "parameters": [
          {
            "description": "Будь-який ідентифікатор: 1523, mal:21, al:21, hikka:…, slug:…",
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Звузити відповідь до потрібних блоків: releases, uaPosters, relations, similar. За замовчуванням приходять усі",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ресурс не знайдено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Детальна інформація",
        "tags": [
          "Аніме"
        ]
      }
    },
    "/anime/{ref}/player": {
      "get": {
        "description": "Список серій. Реліз — це одна команда (або колаборація) і один трек: озвучення voice чи субтитри sub. Усередині релізу серії лежать плоским списком, а кожна серія містить масив sources з усіма провайдерами, які її хостять. Якщо серії не потрібні, те саме зведення релізів уже є в детальній картці аніме.",
        "operationId": "animePlayer",
        "parameters": [
          {
            "description": "Ідентифікатор аніме",
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "false — повернути тільки зведення релізів, без списку серій",
            "in": "query",
            "name": "episodes",
            "required": false,
            "schema": {
              "default": "true",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "result": {
                    "anime": {
                      "ids": {
                        "mal": 21,
                        "mikai": 1523
                      },
                      "titles": {
                        "ua": "Ван Піс"
                      }
                    },
                    "licensed": false,
                    "releases": [
                      {
                        "episodes": [
                          {
                            "addedAt": "2026-08-20T10:00:00Z",
                            "kind": "mangaCanon",
                            "label": "640",
                            "number": 640,
                            "sources": [
                              {
                                "addedAt": "2026-08-20T10:00:00Z",
                                "embedUrl": "https://…",
                                "provider": "ashdi"
                              },
                              {
                                "addedAt": "2026-08-20T10:02:00Z",
                                "embedUrl": "https://…",
                                "provider": "moon"
                              }
                            ]
                          }
                        ],
                        "episodesCount": 640,
                        "id": "t_45:voice",
                        "isCollab": false,
                        "kind": "voice",
                        "lastEpisode": 640,
                        "teams": [
                          {
                            "id": 45,
                            "name": "FanVoxUA",
                            "slug": "fanvoxua"
                          }
                        ],
                        "updatedAt": "2026-08-20T10:00:00Z"
                      }
                    ]
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ресурс не знайдено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Серії та джерела",
        "tags": [
          "Плеєр"
        ]
      }
    },
    "/anime/{ref}/posters": {
      "get": {
        "description": "Оригінальна обкладинка плюс усі україномовні постери. Для кожного приходить команда, яка його опублікувала, та особистий автор, якщо він відомий.",
        "operationId": "animePosters",
        "parameters": [
          {
            "description": "Ідентифікатор аніме",
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ресурс не знайдено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Постери одного аніме",
        "tags": [
          "Постери"
        ]
      }
    },
    "/genres": {
      "get": {
        "description": "Канонічні назви жанрів та їхні українські відповідники. Значення поля name — те, що приймає фільтр genres.",
        "operationId": "genres",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Жанри",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Перевірка доступності",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/me": {
      "get": {
        "description": "Які ліміти діють для цього виклику і скільки з них уже витрачено. Без ключа повертає ліміти анонімного доступу.",
        "operationId": "me",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Поточні ліміти",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/meta": {
      "get": {
        "description": "Усі допустимі значення enum-полів і полів сортування, розміри та формати зображень, чинні ліміти й версія контракту. Зручно звіряти клієнт із живим сервером замість того, щоб зашивати списки в код.",
        "operationId": "meta",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Самоопис API",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/posters/ua": {
      "get": {
        "description": "Усі україномовні постери з пагінацією — для дзеркал і галерей. Кожен запис несе аніме, до якого належить.",
        "operationId": "postersFeed",
        "parameters": [
          {
            "description": "Мітка часу RFC3339",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Номер сторінки",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": "1",
              "type": "integer"
            }
          },
          {
            "description": "Розмір сторінки, максимум 100",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": "20",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Стрічка всіх постерів",
        "tags": [
          "Постери"
        ]
      }
    },
    "/resolve": {
      "get": {
        "description": "Те саме, що POST-версія, але списком у query — зручно перевірити руками або з клієнта, який не вміє слати тіло в GET.",
        "operationId": "resolveGet",
        "parameters": [
          {
            "description": "mal, al, hikka, slug або mikai",
            "in": "query",
            "name": "source",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "До 100 значень через кому",
            "in": "query",
            "name": "ids",
            "required": true,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Резолв ідентифікаторів (GET)",
        "tags": [
          "Аніме"
        ]
      },
      "post": {
        "description": "Зіставляє до 100 зовнішніх ідентифікаторів з нашими за один запит. Значення, яких у нас немає, повертаються як null.",
        "operationId": "resolve",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "ids": {
                    "description": "До 100 значень",
                    "items": {},
                    "type": "array"
                  },
                  "source": {
                    "description": "mal, al, hikka, slug або mikai",
                    "type": "string"
                  }
                },
                "required": [
                  "source",
                  "ids"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "result": {
                    "1": {
                      "al": 1,
                      "mal": 1,
                      "mikai": 12,
                      "slug": "cowboy-bebop"
                    },
                    "21": {
                      "al": 21,
                      "mal": 21,
                      "mikai": 1523,
                      "slug": "one-piece"
                    },
                    "999999999": null
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Батч-резолв ідентифікаторів",
        "tags": [
          "Аніме"
        ]
      }
    },
    "/schedule": {
      "get": {
        "description": "Обʼєкт із сімома ключами — від monday до sunday. Усі дні присутні завжди, навіть порожні. День визначається за київським часом виходу серії, а саме поле airing приходить у UTC.",
        "operationId": "schedule",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "result": {
                    "monday": [
                      {
                        "airing": "2026-08-31T06:30:00Z",
                        "anime": {
                          "ids": {
                            "mal": 21,
                            "mikai": 1523
                          },
                          "titles": {
                            "ua": "Ван Піс"
                          }
                        },
                        "episode": 641,
                        "finished": false
                      }
                    ],
                    "tuesday": []
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Розклад виходу серій",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/studios": {
      "get": {
        "description": "Перелік студій-виробників для фільтра studios.",
        "operationId": "studios",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Студії",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/tags": {
      "get": {
        "description": "Канонічні назви тегів та їхні українські відповідники. Значення поля name — те, що приймає фільтр tags.",
        "operationId": "tags",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Теги",
        "tags": [
          "Довідники"
        ]
      }
    },
    "/teams": {
      "get": {
        "operationId": "teamsList",
        "parameters": [
          {
            "description": "Пошук за назвою",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Лише ті, хто озвучує",
            "in": "query",
            "name": "haveVoice",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Лише ті, хто робить субтитри",
            "in": "query",
            "name": "haveSubs",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "name, count (кількість тайтлів), updated (за останнім релізом)",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": "name",
              "type": "string"
            }
          },
          {
            "description": "asc або desc. За замовчуванням asc для name і desc для решти",
            "in": "query",
            "name": "order",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Номер сторінки",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": "1",
              "type": "integer"
            }
          },
          {
            "description": "Розмір сторінки, максимум 50",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": "20",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Список команд",
        "tags": [
          "Команди"
        ]
      }
    },
    "/teams/{ref}": {
      "get": {
        "description": "Приймає числовий id або slug команди. views — скільки разів дивилися серії команди на Mikai; серії, випущені в колаборації, зараховуються кожній команді з неї.",
        "operationId": "teamDetail",
        "parameters": [
          {
            "description": "ID або slug команди",
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "result": {
                    "animeCount": 128,
                    "avatar": {
                      "big": {
                        "jpg": "…",
                        "webp": "…"
                      }
                    },
                    "birthday": "2018-04-12",
                    "description": "…",
                    "hasSubs": false,
                    "hasVoice": true,
                    "id": 45,
                    "links": {
                      "telegram": "https://t.me/…",
                      "youtube": "https://…"
                    },
                    "name": "FanVoxUA",
                    "slug": "fanvoxua",
                    "views": {
                      "last30Days": 118904,
                      "monthlyAvg": 96500,
                      "total": 4210533
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ресурс не знайдено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Інформація про команду",
        "tags": [
          "Команди"
        ]
      }
    },
    "/teams/{ref}/anime": {
      "get": {
        "operationId": "teamAnime",
        "parameters": [
          {
            "description": "ID або slug команди",
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Номер сторінки",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": "1",
              "type": "integer"
            }
          },
          {
            "description": "Розмір сторінки, максимум 100",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": "20",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ресурс не знайдено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Роботи команди",
        "tags": [
          "Команди"
        ]
      }
    },
    "/updates": {
      "get": {
        "description": "Щойно опубліковані серії по всьому сайту, найновіші першими. Це найдешевший спосіб тримати дзеркало або канал у Telegram актуальним: передавайте since з часом попереднього запиту. Поле teams влаштоване так само, як у плеєрі: для колаборації воно містить усі команди, що працювали над релізом, і isCollab: true. Одна серія, яку хостять кілька провайдерів, приходить окремим записом на кожного.",
        "operationId": "updates",
        "parameters": [
          {
            "description": "Мітка часу RFC3339 — повернути лише те, що зʼявилось пізніше",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Номер сторінки",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": "1",
              "type": "integer"
            }
          },
          {
            "description": "Розмір сторінки, максимум 100",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": "20",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "result": [
                    {
                      "anime": {
                        "ids": {
                          "mal": 21,
                          "mikai": 1523
                        },
                        "titles": {
                          "ua": "Ван Піс"
                        }
                      },
                      "embedUrl": "https://…",
                      "episode": 640,
                      "isCollab": false,
                      "kind": "voice",
                      "provider": "ashdi",
                      "publishedAt": "2026-08-25T18:12:00Z",
                      "teamName": "FanVoxUA",
                      "teams": [
                        {
                          "id": 45,
                          "name": "FanVoxUA",
                          "slug": "fanvoxua"
                        }
                      ]
                    }
                  ],
                  "total": 87
                },
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            },
            "description": "Успішна відповідь",
            "headers": {
              "X-Quota-Remaining": {
                "description": "Скільки запитів лишилось на сьогодні",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Скільки запитів лишилось у поточній хвилині",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Передано недійсний ключ"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Ключ вимкнено"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Некоректні параметри"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Перевищено ліміт за хвилину або добову квоту"
          }
        },
        "summary": "Стрічка новинок",
        "tags": [
          "Плеєр"
        ]
      }
    }
  },
  "security": [
    {},
    {
      "apiKey": []
    },
    {
      "bearer": []
    }
  ],
  "servers": [
    {
      "url": "https://api.mikai.me/public/v1"
    }
  ],
  "tags": [
    {
      "description": "Каталог, детальна інформація та схожі тайтли.",
      "name": "Аніме"
    },
    {
      "description": "Озвучення та субтитри, згруповані по релізах.",
      "name": "Плеєр"
    },
    {
      "description": "Україномовні постери з інформацією про авторство.",
      "name": "Постери"
    },
    {
      "description": "Команди озвучення та субтитрування і їхні роботи.",
      "name": "Команди"
    },
    {
      "description": "Розклад, словники та самоопис API.",
      "name": "Довідники"
    }
  ]
}