Saltar al contenido
javinfo

Resolución API

Normaliza cualquier forma de escribir un código y obtén variantes, fuentes, tarjeta, procedencia y streams.

/resolve dice qué es un código y qué dice cada fuente. /movie devuelve el primer proveedor que responde; estos endpoints consultan todas las fuentes y conservan las discrepancias.

Úsalos para normalizar abp002, ABP-002 o ABP-2, listar todas las fuentes de un título, o una tarjeta para compartir o un mapa de streams en una llamada.

EndpointDevuelvePor 1000 llamadas
GET /resolveCódigo canónico, variantes, fuentes, enlace, tarjeta en línea$1.20
POST /resolve/batchEncontrado o no encontrado para hasta 100 códigos$0.40 por grupo iniciado de 10 códigos únicos
GET /resolve/compareDos títulos lado a lado$0.40
GET /resolve/provenanceFuente y confianza por campo$0.40
GET /resolve/streamsDisponibilidad de stream, muestra y magnet$0.40

GET /resolve

Normaliza cualquier forma a un código canónico y devuelve todo lo asociado: variantes, fuentes, un enlace a /movie y una tarjeta de 1200×630.

ParámetroTipoObligatorioSignificado
qstringsíEl código o la forma de escribirlo que hay que resolver. Al menos 2 caracteres.
formatpng, jpg o svgnoCodificación de la tarjeta. Predeterminado 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,…"
  }
}

La tarjeta va en card.dataUri, así que la respuesta es grande: unos 1,1 MB con png (predeterminado), 900 KB con svg y 180 KB con jpg. Elige jpg cuando importe el tamaño: un raster con pérdida unas seis veces más pequeño que png. La carga base64 está recortada en el ejemplo; dataUri es un URI data: completo, para un <img src>.

CampoSignificado
inputLa cadena que enviaste, sin cambios.
codeEl código canónico.
variantsCada forma de escribir que identifica el mismo título, de la más canónica a la menos.
sourcesIds públicos de las fuentes que listan el título.
contentIdGuessId de contenido de DMM cuando el índice de la tienda lo tiene; si no, null.
linkRuta de la API para el mismo título, /movie?q=<code>. Es relativa a https://api.javinfo.dev y necesita tu cabecera x-javinfo-key.
cardLa tarjeta de 1200×630 como URI de datos, o null.
foundtrue en un 200. Un fallo es un 404.
shareSlugSlug con suma de comprobación para el código canónico.

La tarjeta muestra el código, el título en inglés (acortado o el código si no hay), hasta tres nombres del reparto y el estudio, hasta cuatro etiquetas de género y, cuando se conocen, valoración, duración, fecha de lanzamiento y magnets. Una insignia STREAMABLE marca el stream. La carátula va a la derecha sobre una copia desenfocada de la portada. Es null si no hay render: trátala como opcional y conserva los metadatos.

Un código sin coincidencias es 404, no una tarjeta vacía:

{
  "defined": false,
  "code": "NOT_FOUND",
  "status": 404,
  "message": "no title found for \"ZZZZ-99999\""
}

POST /resolve/batch

Comprueba hasta 100 códigos en una solicitud: limpia la lista de un usuario o coteja tu catálogo sin 100 llamadas secuenciales.

Campo del cuerpoTipoObligatorioSignificado
codesarray de stringssíDe 1 a 100 cadenas no vacías.
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 }
  ]
}

Un fallo es found: false dentro de un 200 normal, no un 404; code lleva la mejor suposición canónica. count son los códigos tras deduplicar; found, cuántos acertaron.

Los códigos se recortan y deduplican antes de contar. "ABP-002" y " ABP-002 " ocupan una ranura y aparecen una vez en results. La coincidencia es exacta tras el recorte: abp-002 y ABP-002 son dos ranuras.

Un array codes vacío, más de 100 códigos o una cadena vacía son un 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"
      }
    ]
  }
}

La misma forma cubre los demás fallos, con otra entrada en issues.

GET /resolve/compare

Dos títulos lado a lado: ficha básica de cada uno, campos compartidos y puntuación de similitud.

ParámetroTipoObligatorioSignificado
astringsíPrimer código. Al menos 2 caracteres.
bstringsíSegundo código. Al menos 2 caracteres.
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
}

Cada lado tiene la forma de /resolve, sin tarjeta. sources lista las fuentes que coinciden; contentIdGuess es el id de contenido de DMM cuando el índice de la tienda lo tiene, igual que en /resolve.

shared contiene la intersección sin distinguir mayúsculas de actresses y categories; maker solo se rellena si ambos títulos llevan exactamente la misma cadena de maker.

similarity es una mezcla de 0 a 1, sobre todo actrices compartidas (0.34) y categorías (0.26), más el mismo maker (0.1), duración (0.06) y cercanía de fecha (0.06), redondeada a 3 decimales. Si falta un código, ese lado es found: false, shared queda vacío y similarity es 0. Nunca 404.

GET /resolve/provenance

Muestra la fuente de cada campo, cuánto confía la API en ella y qué dijeron las demás.

ParámetroTipoObligatorioSignificado
qstringsíEl código o la forma de escribirlo que hay que resolver. Al menos 2 caracteres.
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 cubre title, titleJa, releaseDate, runtimeMins, maker, label, series, categories, actresses, cover y rating.

Los escalares van a la fuente de mayor peso; arrays como categories y actresses se unen, no se reemplazan. candidates lista cada fuente que ofreció un valor, mejor primero, así que las discrepancias quedan visibles.

confidence es el peso ganador dividido por el mejor de la respuesta: 1 para la fuente principal, menos para el resto. Pesos, de mayor a menor: tiendas 1, javdatabase 0.85, javlibrary 0.8, javbus 0.7, missav 0.6, sextb 0.55. sources va alfabético; candidates, por confianza.

Código desconocido: 404 con el cuerpo de GET /resolve.

GET /resolve/streams

Devuelve dónde ver o descargar un título: streams HLS, muestras, imanes, subtítulos y tamaño de galería.

ParámetroTipoObligatorioSignificado
qstringsíEl código o la forma de escribirlo que hay que resolver. Al menos 2 caracteres.
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 responde en una línea: hls con stream, si no magnet con imanes, si no sample con solo muestra o tráiler, si no none.

availability añade detalle:

CampoSignificado
magnetsInfohashes de imán distintos en todas las fuentes.
streamHay un master HLS presente.
sampleHay un clip de muestra o un tráiler presente.
trailerUn tráiler específicamente.
galleryNúmero de imágenes de la galería de la fuente elegida para medios.
subtitlesIdiomas de subtítulos detectados en los metadatos. Hoy solo zh está etiquetado.
uncensoredLos metadatos marcan el título como sin censura.
scoreCompletitud de 0 a 1: imanes 0.35, stream 0.35, muestra 0.15, galería 0.1, subtítulos 0.05.

streams es {master, variants} con HLS, si no null. master es la lista para el reproductor; variants, las listas por resolución. sampleUrl es el clip de muestra si existe; galleryCount, el mayor visto entre fuentes.

Código desconocido: 404 con el cuerpo de GET /resolve.

Coste

Solo se cobra un 200 nuevo. Aciertos de caché (X-Cache: HIT), respuestas 4xx y respuestas degradadas (X-Degraded) gratis. Resolve, compare y provenance cachean 1 hora; streams, 15 minutos. Batch no cachea.

GET /resolve cuesta $1.20 por 1000 llamadas porque genera la tarjeta; los demás endpoints, $0.40 por 1000 llamadas.

Batch factura los códigos que quedan tras recortar y deduplicar, en grupos iniciados de 10:

Códigos únicosPor 1000 llamadas
1–10$0.40
11–20$0.80
21–30$1.20
100$4.00

Códigos de estado

EndpointCódigos
GET /resolve200, 400, 401, 402, 404, 429
POST /resolve/batch200, 400, 401, 402, 429
GET /resolve/compare200, 400, 401, 402, 429
GET /resolve/provenance200, 400, 401, 402, 404, 429
GET /resolve/streams200, 400, 401, 402, 404, 429

Un q de menos de 2 caracteres, un format desconocido y los fallos de batch de arriba son 400.

Errores comunes

Sin clave o con clave incorrecta: 401, con cuerpos distintos.

# 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 significa que el saldo está por debajo del precio de la llamada. No se cobra nada; Retry-After: 3600 es una pista para clientes automatizados.

{
  "defined": false,
  "code": "PAYMENT_REQUIRED",
  "status": 402,
  "message": "insufficient balance"
}

429 es el tope por cuenta y minuto; Retry-After da los segundos de espera.

{ "error": "rate limit exceeded" }

Cuenta: Límites de tasa y facturación y Errores. Referencia generada: /docs/api/discovery/resolve.

En esta página