Resolve API
Нормализуйте написание кода и получите варианты, источники, карточку, происхождение и потоки одного тайтла.
/resolve объясняет, что это за код и что говорит каждый источник. /movie
возвращает первого ответившего провайдера; эти эндпоинты смотрят все источники и сохраняют
расхождения.
Используйте, чтобы нормализовать abp002, ABP-002 или ABP-2, перечислить все источники
тайтла или получить карточку для шеринга или карту потоков за один вызов.
| Эндпоинт | Возвращает | За 1000 вызовов |
|---|---|---|
GET /resolve | Канонический код, варианты, источники, ссылка, inline-карточка | $1.20 |
POST /resolve/batch | Найден или нет для до 100 кодов | $0.40 за начатую группу из 10 уникальных кодов |
GET /resolve/compare | Два тайтла рядом | $0.40 |
GET /resolve/provenance | Источник и уверенность по каждому полю | $0.40 |
GET /resolve/streams | Доступность потоков, сэмплов и magnet-ссылок | $0.40 |
GET /resolve
Нормализует написание в один канонический код и возвращает всё привязанное: варианты,
источники, ссылку на /movie, карточку 1200×630.
| Параметр | Тип | Обязательно | Значение |
|---|---|---|---|
q | string | да | Код или написание для сопоставления. Минимум 2 символа. |
format | png, jpg или svg | нет | Кодировка карточки. По умолчанию png. |
curl -s 'https://api.javinfo.dev/resolve?q=abp002&format=jpg' \
-H "x-javinfo-key: jvi_your_key_here"{
"input": "abp002",
"code": "ABP-002",
"shareSlug": "85150B9G60S0M",
"found": true,
"variants": ["ABP-002", "ABP002"], // 7 total
"contentIdGuess": "118abp00002",
"sources": ["fanza", "javdatabase"], // 6 total
"link": "/movie?q=ABP-002",
"card": {
"format": "jpg",
"mime": "image/jpeg",
"dataUri": "data:image/jpeg;base64,…"
}
}Карточка встроена в card.dataUri, поэтому ответ большой: около 1,1 МБ с png (по
умолчанию), 900 КБ с svg, 180 КБ с jpg. Выбирайте jpg, когда важен размер: растр с
потерями, примерно в шесть раз меньше png. Base64 в примере обрезана; dataUri — полный
URI data: для <img src>.
| Поле | Значение |
|---|---|
input | Строка, которую вы отправили, без изменений. |
code | Канонический код. |
variants | Каждое написание, которое ведёт к тому же тайтлу, самое каноническое первым. |
sources | Публичные id источников, где числится тайтл. |
contentIdGuess | Id контента DMM, если он есть в индексе витрины, иначе null. |
link | Путь API для того же тайтла, /movie?q=<code>. Он указан относительно https://api.javinfo.dev и требует заголовок x-javinfo-key. |
card | Карточка 1200×630 как data URI, или null. |
found | true при 200. Промах — это 404. |
shareSlug | Slug с контрольной суммой для канонического кода. |
Карточка показывает код, английское название (сокращённое или код, если названия нет), до
трёх имён состава и студию, до четырёх жанровых меток, затем рейтинг, длительность, дату
выпуска и число магнитов, когда известны. Значок STREAMABLE отмечает стрим. Обложка
справа, поверх размытой копии. null, если рендеринг недоступен: считайте её необязательной
и сохраняйте метаданные.
Код без совпадений — 404, не пустая карточка:
{
"defined": false,
"code": "NOT_FOUND",
"status": 404,
"message": "no title found for \"ZZZZ-99999\""
}POST /resolve/batch
Проверяет до 100 кодов за запрос: очистите список пользователя или сопоставьте каталог без 100 последовательных вызовов.
| Поле тела | Тип | Обязательно | Значение |
|---|---|---|---|
codes | массив строк | да | От 1 до 100 непустых строк. |
curl -s -X POST 'https://api.javinfo.dev/resolve/batch' \
-H "x-javinfo-key: jvi_your_key_here" \
-H 'content-type: application/json' \
-d '{"codes":["ABP-002","beb001","ZZZZ-99999"]}'{
"count": 3,
"found": 2,
"results": [
{ "input": "ABP-002", "code": "ABP-002", "found": true },
{ "input": "beb001", "code": "BEB-001", "found": true },
{ "input": "ZZZZ-99999", "code": "ZZZZ-99999", "found": false }
]
}Ненайденный код — found: false внутри обычного 200, не 404; code содержит лучшую
догадку. count — коды после дедупликации, found — сколько нашлось.
Коды обрезаются и дедуплицируются до подсчёта. "ABP-002" и " ABP-002 " занимают один слот
и появляются в results раз. После обрезки совпадение точное, поэтому abp-002 и ABP-002
— два слота.
Пустой массив codes, больше 100 кодов или пустая строка — это 400:
{
"defined": false,
"code": "BAD_REQUEST",
"status": 400,
"message": "Input validation failed",
"data": {
"issues": [
{
"origin": "array",
"code": "too_small",
"minimum": 1,
"inclusive": true,
"path": ["codes"],
"message": "Too small: expected array to have >=1 items"
}
]
}
}Та же форма покрывает остальные ошибки валидации, с другой записью issues.
GET /resolve/compare
Два тайтла рядом: базовая карточка каждого, общие поля, оценка сходства.
| Параметр | Тип | Обязательно | Значение |
|---|---|---|---|
a | string | да | Первый код. Минимум 2 символа. |
b | string | да | Второй код. Минимум 2 символа. |
curl -s 'https://api.javinfo.dev/resolve/compare?a=SSIS-001&b=ABP-002' \
-H "x-javinfo-key: jvi_your_key_here"{
"a": {
"input": "SSIS-001",
"code": "SSIS-001",
"shareSlug": "AD9MJMSD60R32E",
"found": true,
"variants": [
"SSIS-001",
"SSIS001",
"…"
],
"contentIdGuess": "ssis00001",
"sources": [
"fanza",
"javdatabase",
"javlibrary",
"javbus",
"missav",
"sextb"
],
"link": "/movie?q=SSIS-001"
},
"b": {
"input": "ABP-002",
"code": "ABP-002",
"shareSlug": "85150B9G60S0M",
"found": true,
"variants": [
"ABP-002",
"ABP002",
"…"
],
"contentIdGuess": "118abp00002",
"sources": [
"fanza",
"javdatabase",
"javlibrary",
"javbus",
"missav",
"sextb"
],
"link": "/movie?q=ABP-002"
},
"shared": {
"actresses": [],
"categories": [],
"maker": null
},
"similarity": 0.05
}У каждой стороны форма /resolve без карточки. sources перечисляет совпавшие источники;
contentIdGuess — id контента DMM, если он есть в индексе витрины, как в /resolve.
shared содержит пересечение actresses и categories без учёта регистра; maker
заполняется только при точном совпадении строки мейкера у обоих тайтлов.
similarity — смесь 0–1, в основном общие актрисы (0.34) и категории (0.26), плюс тот же
мейкер (0.1), продолжительность (0.06) и близость дат (0.06), с округлением до 3 знаков.
Если код не найден, эта сторона found: false, shared пуст, similarity 0. Никогда
404.
GET /resolve/provenance
Показывает источник каждого поля, доверие API к нему и что говорили другие источники.
| Параметр | Тип | Обязательно | Значение |
|---|---|---|---|
q | string | да | Код или написание для сопоставления. Минимум 2 символа. |
curl -s 'https://api.javinfo.dev/resolve/provenance?q=ABP-002' \
-H "x-javinfo-key: jvi_your_key_here"{
"code": "ABP-002",
"found": true,
"sources": ["fanza", "javbus"], // 6 total, alphabetical
"fields": {
"title": {
"value": "NEW TOKYO Style 01 - Aikarin",
"source": "fanza",
"confidence": 1,
"candidates": [ // 6 total, trust order
{ "source": "fanza", "value": "NEW TOKYO Style 01 - Aikarin" },
{ "source": "javdatabase", "value": "NEW TOKYO Style 01 - Aikarin" }
]
},
"titleJa": {
"value": "NEW TOKYO流儀 01 あいかりん",
"source": "javlibrary",
"confidence": 0.8,
"candidates": [ // 4 total
{ "source": "javlibrary", "value": "NEW TOKYO流儀 01 あいかりん" },
{ "source": "javbus", "value": "NEW TOKYO流儀 01 あいかりん" }
]
},
"rating": {
"value": 8.1,
"source": "javlibrary",
"confidence": 0.8,
"candidates": [{ "source": "javlibrary", "value": 8.1 }]
}
// releaseDate, runtimeMins, maker, label, series, categories,
// actresses and cover follow the same shape
},
"data": {
"title": "NEW TOKYO Style 01 - Aikarin",
"titleJa": "NEW TOKYO流儀 01 あいかりん",
"rating": 8.1
// the merged value for every field above
}
}fields покрывает title, titleJa, releaseDate, runtimeMins, maker, label, series,
categories, actresses, cover и rating.
Скаляры уходят к источнику с наибольшим весом; массивы вроде categories и actresses
объединяются, не заменяются. candidates перечисляет источники со значением, лучший
первым, так что расхождение видно в ответе.
confidence — вес победителя, делённый на лучший вес ответа: 1 для верхнего источника,
ниже для остальных. Веса, от большего к меньшему: витрины 1, javdatabase 0.85, javlibrary
0.8, javbus 0.7, missav 0.6, sextb 0.55. sources по алфавиту; candidates по
доверию.
Неизвестный код: 404 с телом GET /resolve.
GET /resolve/streams
Где посмотреть или скачать тайтл: HLS-потоки, сэмплы, magnet-ссылки, субтитры, размер галереи.
| Параметр | Тип | Обязательно | Значение |
|---|---|---|---|
q | string | да | Код или написание для сопоставления. Минимум 2 символа. |
curl -s 'https://api.javinfo.dev/resolve/streams?q=ABP-002' \
-H "x-javinfo-key: jvi_your_key_here"{
"code": "ABP-002",
"found": true,
"playback": "hls",
"availability": {
"magnets": 47,
"stream": true,
"sample": false,
"trailer": false,
"gallery": 0,
"subtitles": [],
"uncensored": false,
"score": 0.7
},
"streams": {
"master": "https://surrit.com/c511196b-b4f8-47bf-a6b0-64ba625fc2a4/playlist.m3u8",
"variants": [
"https://surrit.com/c511196b-b4f8-47bf-a6b0-64ba625fc2a4/1280x720/video.m3u8",
"https://surrit.com/c511196b-b4f8-47bf-a6b0-64ba625fc2a4/842x480/video.m3u8"
]
},
"sampleUrl": null,
"galleryCount": 106,
"sources": ["fanza", "javdatabase"] // 6 total
}playback — ответ в строку: hls при потоке, иначе magnet при magnet-ссылках, иначе
sample при сэмпле или трейлере, иначе none.
availability добавляет детали:
| Поле | Значение |
|---|---|
magnets | Уникальные info hash magnet-ссылок по всем источникам. |
stream | Есть HLS-мастер. |
sample | Есть сэмпл-клип или трейлер. |
trailer | Именно трейлер. |
gallery | Число изображений галереи из источника, выбранного для медиа. |
subtitles | Языки субтитров, обнаруженные в метаданных. zh пока единственный помеченный. |
uncensored | Метаданные помечают тайтл как без цензуры. |
score | Полнота от 0 до 1: magnet-ссылки 0.35, поток 0.35, сэмпл 0.15, галерея 0.1, субтитры 0.05. |
streams — {master, variants} при HLS-потоке, иначе null. master — плейлист для
плеера; variants — по разрешениям. sampleUrl — сэмпл-клип, если есть; galleryCount —
наибольшее число изображений по всем источникам.
Неизвестный код: 404 с телом GET /resolve.
Стоимость
Списывается только свежий 200. Попадания в кэш (X-Cache: HIT), ответы 4xx и
деградировавшие ответы (X-Degraded) бесплатны. Resolve, compare и provenance кэшируют на 1
час; streams — на 15 минут. Batch не кэшируется.
GET /resolve стоит $1.20 за 1000 вызовов, потому что рендерит карточку; остальные эндпоинты — $0.40
за 1000 вызовов.
Batch тарифицирует коды после обрезки и дедупликации, группами по 10:
| Уникальных кодов | За 1000 вызовов |
|---|---|
| 1–10 | $0.40 |
| 11–20 | $0.80 |
| 21–30 | $1.20 |
| 100 | $4.00 |
Коды состояния
| Эндпоинт | Коды |
|---|---|
GET /resolve | 200, 400, 401, 402, 404, 429 |
POST /resolve/batch | 200, 400, 401, 402, 429 |
GET /resolve/compare | 200, 400, 401, 402, 429 |
GET /resolve/provenance | 200, 400, 401, 402, 404, 429 |
GET /resolve/streams | 200, 400, 401, 402, 404, 429 |
q короче 2 символов, неизвестный format и ошибки batch выше — 400.
Общие ошибки
Без ключа и с плохим ключом — 401, но тела разные.
# No key
curl -s 'https://api.javinfo.dev/resolve?q=ABP-002'{
"defined": false,
"code": "UNAUTHORIZED",
"status": 401,
"message": "Unauthorized"
}# Bad key
curl -s 'https://api.javinfo.dev/resolve?q=ABP-002' \
-H "x-javinfo-key: jvi_not_a_real_key"{ "error": "invalid api key" }402 значит, что баланс ниже цены вызова. Ничего не списывается; Retry-After: 3600 —
подсказка автоматическим клиентам.
{
"defined": false,
"code": "PAYMENT_REQUIRED",
"status": 402,
"message": "insufficient balance"
}429 — минутный лимит на аккаунт; Retry-After несёт секунды ожидания.
{ "error": "rate limit exceeded" }Аккаунт: Лимиты и тарификацию и Ошибки. Справочник по
операции: /docs/api/discovery/resolve.