Skip to content
javinfo

Discover endpoints

Browse the catalogue without a seed code: trending, similar titles, releases by day, studios, series, genres and random picks.

Thirteen GET endpoints over the catalogue, not one code. All use x-javinfo-key and are metered; most return meta with sources, documents scanned and latency.

Base price is $0.40 per 1,000 calls. Above 10, price scales with page size, so num matters: num=20 costs $0.80. Formula in Rate limits & billing.

EndpointUse it forPer 1,000 at default
/discover/trendingRecent releases, ranked$0.80 (num=20)
/discover/underratedHigh-rated older titles$0.80 (num=20)
/discover/suggestionTypeahead across codes, performers, tags and studios$0.40 (num=8)
/discover/similarTitles like one seed code$0.48 (num=12)
/discover/duelA seeded A/B pair$0.40
/discover/calendarReleases bucketed by day$0.40
/discover/tagsTag counts in a time window$1.20 (num=30)
/discover/studiosStudio directory, or one studio's catalogue$1.20 / $0.80
/discover/seriesOne series, newest first$0.80 (num=20)
/discover/genresGenre counts for the whole catalogue$2.40 (num=60)
/discover/randomRandom titles matching filters$0.40 (num=10)
/discover/for-youPicks from the account's own search history$0.80 (num=20)
/discover/statsCatalogue totals per source$0.40

Movie card

Every title in a discovery response has this shape. One card, one renderer, every endpoint below.

FieldTypeNotes
codestringNormalised title code, e.g. ABP-002
titlestring | nullEnglish title only; null when the source has none. javbus rows often have title: null with the Japanese title in titleJa
titleJastring | nullJapanese title
releaseDatestring | nullYYYY-MM-DD
runtimeMinsnumber | nullMinutes
makerstring | nullStudio / maker
labelstring | nullLabel
seriesstring | nullSeries, as the source spells it
categoriesstring[]Genre tags
actressesstring[]Cast, English names where a source has them
coverstring | nullJacket URL
ratingnumber | nulljavlibrary only, 1–10; null on every other source
sourcestringWhich source supplied this card: fanza, javdatabase, javlibrary, javbus or missav
urlstring | nullPage on the source site, when the source stores one

Cards collapse by code across indexes; the first in preference order supplies metadata. rating is the exception: only javlibrary has ratings, so other sources return null even for rated titles.

meta:

FieldTypeNotes
sourcesstring[]Public source names that answered with hits or facet counts. An empty array usually means the catalogue could not be reached
scannednumberDocuments read before ranking or filtering. 0 on facet-only endpoints
latencyMsnumberServer-side time

Examples are trimmed: first items, "…" for repeats, long titles cut. Values are real.

/discover/trending

API: /discover/trending

Recent releases ranked by quality, not just date. For a home page or a "new this week" rail.

ParameterTypeDefaultRange
rangeinteger301–365, days back to look
numinteger201–50
genrestringnoneExact category name

Price: $0.80 per 1,000 at num=20; $0.40 at num ≤ 10.

The handler reads the last range days, newest first, then re-ranks on recency, rating, gallery size, previews and cast size. No upper date bound, so future-dated announcements appear.

curl -s 'https://api.javinfo.dev/discover/trending?range=7&num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:trending",
  "count": 3,
  "results": [
    {
      "code": "FCDSS-120",
      "title": "4 Hours of the Best Anal Licking Service: Sticking My Tongue in Your Asshole! [FALENO Maniac Special Selection]",
      "titleJa": null,
      "releaseDate": "2026-12-03",
      "runtimeMins": 240,
      "maker": "Faleno",
      "label": "Faleno",
      "series": "FALENO Compilation",
      "categories": ["Anal Play", "Beautiful Girl", "…"],
      "actresses": ["Ayaka Tomoda", "Chiharu Mitsuha", "…"],
      "cover": "https://www.javdatabase.com/covers/full/1f/1fcdss00120pl.webp",
      "rating": null,
      "source": "javdatabase",
      "url": "https://www.javdatabase.com/movies/fcdss-120/"
    },
    "…"
  ],
  "meta": {
    "sources": ["fanza", "javdatabase", "…"],
    "scanned": 45,
    "latencyMs": 23
  }
}

Status: 200, 400, 401, 402, 429.

/discover/underrated

API: /discover/underrated

Older titles that were missed, ranked more by rating than date. For an "overlooked" shelf.

ParameterTypeDefaultRange
minAgeDaysinteger36530–3650, minimum age in days
numinteger201–50

Price: $0.80 per 1,000 at num=20; $0.40 at num ≤ 10.

Only javlibrary has ratings, so the pool is that index alone: eight random 30-day slices over the 12 years before the cutoff. Unrated titles drop out; the score favours older, higher-rated, more complete records.

curl -s 'https://api.javinfo.dev/discover/underrated?num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:underrated",
  "count": 3,
  "results": [
    {
      "code": "IRCP-016",
      "title": "The Price Of Chigasaki Lion Compliant With Me Naked",
      "titleJa": "裸のわたしと言いなりの値段 茅ヶ崎りおん",
      "releaseDate": "2014-07-13",
      "runtimeMins": 120,
      "maker": "Iromegane",
      "label": "Iromegane",
      "series": null,
      "categories": ["Solowork", "Girl", "…"],
      "actresses": ["Shiina Mayu (Chigasaki Rion)"],
      "cover": "https://pics.dmm.co.jp/mono/movie/adult/ircp016/ircp016pl.jpg",
      "rating": 10,
      "source": "javlibrary",
      "url": "https://www.javlibrary.com/en/javlijya24.html"
    },
    "…"
  ],
  "meta": {
    "sources": ["javlibrary"],
    "scanned": 640,
    "latencyMs": 63
  }
}

Status: 200, 400, 401, 402, 429.

/discover/suggestion

API: /discover/suggestion

Typeahead for a search box: codes, performers, tags and studios, deduplicated, codes first.

ParameterTypeDefaultRange
qstringrequiredat least 1 character
numinteger81–20

Price: $0.40 per 1,000 at num=8; $0.80 at num=20.

Each entry says what it is and what to show:

kindvaluelabelextra
codeTitle codeSame codeEnglish title, or the Japanese one when there is no English title
idolPerformer idNameImage URL
tagTag slugSame slugCount
studioStudio nameSame nameCount

extra is nullable. Search reuses the movie indexes' prefix match; no separate n-gram index. Suggestions build by kind (codes, performers, tags, studios), then cut to num.

curl -s 'https://api.javinfo.dev/discover/suggestion?q=ABP&num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "q": "ABP",
  "count": 3,
  "results": [
    {
      "kind": "code",
      "value": "ABP-001",
      "label": "ABP-001",
      "extra": "Lola Misaki at Your Service Newest Beauty Salon Addict"
    },
    {
      "kind": "code",
      "value": "ABP-002",
      "label": "ABP-002",
      "extra": "NEW TOKYO Style 01 - Aikarin"
    },
    "…"
  ]
}

A missing q is rejected before the handler runs:

curl -s 'https://api.javinfo.dev/discover/suggestion' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "defined": false,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Input validation failed",
  "data": {
    "issues": [
      {
        "expected": "string",
        "code": "invalid_type",
        "path": ["q"],
        "message": "Invalid input: expected string, received undefined"
      }
    ]
  }
}

Status: 200, 400, 401, 402, 429.

/discover/similar

API: /discover/similar

"More like this." One code in, ranked neighbours, the seed card and the scores out. For a detail page.

ParameterTypeDefaultRange
qstringrequiredA title code
numinteger121–50

Price: $0.48 per 1,000 at num=12; $0.40 at num ≤ 10.

The seed resolves across movie indexes. Candidates share its first performer or one of its first three tags, then rank on cast, tags, maker, label, series, runtime and date. The seed is excluded from results; scores aligns with results by code, 0–1, three decimals.

A code no index knows is a 404, not an empty 200. A typo is never billed.

curl -s 'https://api.javinfo.dev/discover/similar?q=ABP-002&num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:similar",
  "count": 3,
  "results": [
    {
      "code": "WPC-013",
      "title": "WPC-013 WATER POLE Aikarin",
      "titleJa": "WPC-013 WATER POLE あいかりん",
      "releaseDate": "2023-03-20",
      "runtimeMins": 128,
      "maker": "Prestige",
      "label": "WPC",
      "series": "WATER POLE",
      "categories": ["Hot Girl", "Sailor Suit", "…"],
      "actresses": ["Aikarin"],
      "cover": null,
      "rating": null,
      "source": "missav",
      "url": null
    },
    "…"
  ],
  "meta": {
    "sources": ["fanza", "javdatabase", "…"],
    "scanned": 180,
    "latencyMs": 72
  },
  "seed": {
    "code": "ABP-002",
    "title": "NEW TOKYO Style 01 - Aikarin",
    "titleJa": null,
    "releaseDate": "2013-06-01",
    "runtimeMins": 127,
    "maker": "Prestige",
    "label": "ABSOLUTELY PERFECT",
    "series": "Tokyo Style",
    "categories": ["Facial", "Handjob"],
    "actresses": ["Aikarin"],
    "cover": "https://pics.dmm.co.jp/digital/video/118abp00002/118abp00002pl.jpg",
    "rating": null,
    "source": "fanza",
    "url": null
  },
  "scores": [
    { "code": "WPC-013", "score": 0.5 },
    { "code": "MAS-110", "score": 0.496 },
    "…"
  ]
}

Unknown code, same request:

curl -s 'https://api.javinfo.dev/discover/similar?q=ZZZZ-99999&num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "defined": false,
  "code": "NOT_FOUND",
  "status": 404,
  "message": "no title found for \"ZZZZ-99999\""
}

Status: 200, 400, 401, 402, 404, 429.

/discover/duel

API: /discover/duel

A/B pair for a "which one" game. One seed, the same two cards for everyone.

ParameterTypeDefaultRange
seedstringtoday's UTC dateany string
genrestringnoneExact category name
performerstringnoneExact performer name

Price: $0.40 per 1,000, flat. No page-size knob.

The pool is the newest 40 titles from DMM + FANZA, javdatabase and javlibrary, deduplicated by code, released and with a cast. genre and performer narrow it. A seeded PRNG picks two and orders by code, so a and b land on the same sides for everyone. The pool moves with new releases, so a seed holds only for that window. a and b are nullable if fewer than two candidates match.

curl -s 'https://api.javinfo.dev/discover/duel?seed=42' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "seed": "42",
  "a": {
    "code": "DSOD-124",
    "title": "That absolute, total fatso made me come so many times it was embarrassing…",
    "titleJa": "最低最悪なあのデブに恥ずかしいほど何度もイカされて…ションベン垂れ流す肉便器調教された言いなり美人清掃員 天川そら",
    "releaseDate": "2026-11-06",
    "runtimeMins": 141,
    "maker": "Das",
    "label": "Das",
    "series": null,
    "categories": ["Deep Throat", "Embarrassment", "…"],
    "actresses": ["Sora Amakawa"],
    "cover": "https://pics.dmm.co.jp/digital/video/dsod00124/dsod00124pl.jpg",
    "rating": null,
    "source": "fanza",
    "url": null
  },
  "b": {
    "code": "VRKM-1944",
    "title": "[VR] Getting Hooked on Sora Amakawa",
    "titleJa": null,
    "releaseDate": "2026-11-06",
    "runtimeMins": 84,
    "maker": "K M Produce",
    "label": "K M Produce",
    "series": "pond",
    "categories": ["8KVR", "Beautiful Tits", "…"],
    "actresses": ["Sora Amakawa"],
    "cover": "https://www.javdatabase.com/covers/full/vr/vrkm01944pl.webp",
    "rating": null,
    "source": "javdatabase",
    "url": "https://www.javdatabase.com/movies/vrkm-1944/"
  }
}

Status: 200, 401, 402, 429.

/discover/calendar

API: /discover/calendar

Releases between two dates, bucketed by day. For a release calendar.

ParameterTypeDefaultRange
fromstringtodayYYYY-MM-DD
tostringtoday + 30 daysYYYY-MM-DD

Price: $0.40 per 1,000, flat. Each loop call below is a separate call.

Both dates are inclusive. Defaults are independent: from alone still ends 30 days out, so pass both for a past window. Empty days are omitted; buckets ascend. Each release is a full card.

Long ranges stop early

At 1,000 rows per source per call, a busy range fills in about 5 days. Only complete days return; it reports where it stopped:

FieldMeaning
throughThe last day fully covered, YYYY-MM-DD. Equals to unless the answer was cut.
truncatedtrue when days after through were cut.

from=2026-11-01&to=2026-11-14 is too long for one call:

curl -s 'https://api.javinfo.dev/discover/calendar?from=2026-11-01&to=2026-11-14' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "from": "2026-11-01",
  "to": "2026-11-14",
  "through": "2026-11-05",
  "truncated": true,
  "count": 1011,
  "days": [
    {
      "date": "2026-11-01",
      "count": 109,
      "releases": [
        {
          "code": "DANDYA-045",
          "title": null,
          "titleJa": "母親と行った銭湯でコッソリおちんちんをいじってくるお姉さんに逃げても追いかけられ何度も精子を飲まれてしまいました",
          "releaseDate": "2026-11-01",
          "runtimeMins": 175,
          "maker": "DANDY",
          "label": null,
          "series": null,
          "categories": [
            "4K",
            "Big Asses",
            "Big Tits",
            "…"
          ],
          "actresses": [],
          "cover": "https://pics.dmm.co.jp/digital/video/1dandya00045/1dandya00045pl.jpg",
          "rating": null,
          "source": "fanza",
          "url": null
        },
        "…"
      ]
    },
    "…"
  ],
  "meta": {
    "sources": [
      "fanza",
      "javdatabase",
      "javlibrary",
      "javbus",
      "missav"
    ],
    "scanned": 3136,
    "latencyMs": 352
  }
}

That answer holds 1,011 titles for November 1–5. A range that fits returns whole: from=2026-11-01&to=2026-11-03 gives "through": "2026-11-03" and "truncated": false.

For the rest, call again with from on the day after through and repeat until truncated is false. The second call here is from=2026-11-06&to=2026-11-14:

{
  "from": "2026-11-06",
  "to": "2026-11-14",
  "through": "2026-11-14",
  "truncated": false,
  "count": 1101,
  "days": [
    "…"
  ],
  "meta": {
    "sources": [
      "fanza",
      "javdatabase",
      "javbus",
      "missav"
    ],
    "scanned": 1957,
    "latencyMs": 627
  }
}

The same loop in code:

let from = '2026-11-01';
const to = '2026-11-14';
const days = [];

while (from <= to) {
  const res = await fetch(
    `https://api.javinfo.dev/discover/calendar?from=${from}&to=${to}`,
    { headers: { 'x-javinfo-key': KEY } },
  );
  const page = await res.json();
  days.push(...page.days);
  if (!page.truncated) break;

  const next = new Date(`${page.through}T00:00:00Z`);
  next.setUTCDate(next.getUTCDate() + 1);
  from = next.toISOString().slice(0, 10);
}

A single day over the cap returns partly filled, with through on that day; the loop moves on.

Status: 200, 400, 401, 402, 429.

/discover/tags

API: /discover/tags

Tag counts over a recent window, highest first. For a "trending tags" block.

ParameterTypeDefaultRange
rangeinteger301–365, days back
numinteger301–100

Price: $1.20 per 1,000 at num=30; $0.40 at num ≤ 10.

Counts come from facets on DMM + FANZA and javdatabase. Tags are canonicalised first, so variants merge. Values are slugs, not display names.

curl -s 'https://api.javinfo.dev/discover/tags?range=7&num=5' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:tags",
  "count": 5,
  "results": [
    { "tag": "featured-actress", "count": 3476 },
    { "tag": "hi-def", "count": 2834 },
    "…"
  ],
  "meta": {
    "sources": ["fanza", "javdatabase"],
    "scanned": 0,
    "latencyMs": 117
  }
}

Status: 200, 400, 401, 402, 429.

/discover/studios

API: /discover/studios

One route, two shapes. Without q, a studio directory ranked by output in range; with q, that studio's catalogue, newest first. kind says which: directory or catalogue.

ParameterTypeDefaultRange
qstringnoneExact studio name; switches to catalogue mode
rangeinteger36530–3650, directory mode only
numinteger30 directory, 20 catalogue1–100 directory; catalogue is capped at 50
pageinteger11 and up, catalogue mode only

Price: directory $1.20 per 1,000 at num=30; catalogue $0.80 at num=20. Catalogue caps num at 50, so its top price is $2.00.

range is ignored with q; page is ignored without it. Catalogue total estimates the studio's titles, so page against it.

curl -s 'https://api.javinfo.dev/discover/studios?num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "kind": "directory",
  "source": "discover:studios",
  "count": 3,
  "results": [
    { "studio": "MOODYZ", "count": 2688 },
    { "studio": "S1 NO.1 STYLE", "count": 2382 },
    "…"
  ],
  "meta": {
    "sources": ["fanza"],
    "scanned": 0,
    "latencyMs": 416
  }
}
curl -s 'https://api.javinfo.dev/discover/studios?q=S1%20NO.1%20STYLE&num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "kind": "catalogue",
  "source": "discover:studio",
  "studio": "S1 NO.1 STYLE",
  "total": 25713,
  "count": 3,
  "results": [
    {
      "code": "K9SNOS349",
      "title": null,
      "titleJa": "【数量限定】特大号新人 希望みう 104cm Iの素顔 濃厚なキスして、本能で交わって、ありのままを曝け出す。 (ブルーレイディスク) 生写真3枚セット",
      "releaseDate": "2026-11-25",
      "runtimeMins": 120,
      "maker": "S1 NO.1 STYLE",
      "label": "S1 NO.1 STYLE",
      "series": null,
      "categories": ["Big Tits", "Featured Actress", "…"],
      "actresses": ["希望みう"],
      "cover": "https://pics.dmm.co.jp/mono/movie/adult/k9snos349/k9snos349ps.jpg",
      "rating": null,
      "source": "fanza",
      "url": null
    },
    "…"
  ],
  "meta": {
    "sources": ["fanza"],
    "scanned": 3,
    "latencyMs": 7
  }
}

Status: 200, 400, 401, 402, 429.

/discover/series

API: /discover/series

One series' catalogue, newest first. Use it to list the rest when a caller opens a title.

ParameterTypeDefaultRange
qstringrequiredExact series name
numinteger201–50
pageinteger11 and up

Price: $0.80 per 1,000 at num=20; $0.40 at num ≤ 10.

q is an exact series-name match on the DMM + FANZA index, not a search. Pass the stored string, readable from any title's series. A partial name or different spelling returns 200 with count: 0, not 404. total estimates the series' titles.

curl -s 'https://api.javinfo.dev/discover/series?q=Unfaithful%20Housewife&num=2' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:series",
  "count": 2,
  "results": [
    {
      "code": "JUKD-481",
      "title": "Unfaithful Housewife 5",
      "titleJa": "不倫妻5",
      "releaseDate": "2006-12-25",
      "runtimeMins": 87,
      "maker": "MADONNA",
      "label": "Madonna",
      "series": "Unfaithful Housewife",
      "categories": ["69", "Adultery", "…"],
      "actresses": ["Anna Muto", "Hiromi Yuki", "…"],
      "cover": "https://pics.dmm.co.jp/digital/video/jukd00481/jukd00481pl.jpg",
      "rating": null,
      "source": "fanza",
      "url": null
    },
    "…"
  ],
  "meta": {
    "sources": ["fanza"],
    "scanned": 2,
    "latencyMs": 14
  },
  "series": "Unfaithful Housewife",
  "total": 7
}

Status: 200, 400, 401, 402, 429.

/discover/genres

API: /discover/genres

The genre taxonomy with counts across the catalogue. Use it to seed a filter menu.

ParameterTypeDefaultRange
numinteger601–200

Price: $2.40 per 1,000 at num=60; $0.40 at num ≤ 10; $8.00 at num=200.

Values are display labels (Featured Actress), unlike /discover/tags slugs. Counts come from DMM + FANZA only; a title listed on another source adds nothing.

curl -s 'https://api.javinfo.dev/discover/genres?num=5' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:genres",
  "count": 5,
  "results": [
    { "genre": "Featured Actress", "count": 589656 },
    { "genre": "Creampie", "count": 438721 },
    "…"
  ],
  "meta": {
    "sources": ["fanza"],
    "scanned": 0,
    "latencyMs": 163
  }
}

Status: 200, 400, 401, 402, 429.

/discover/random

API: /discover/random

Random titles matching optional filters. For a "surprise me" button.

ParameterTypeDefaultRange
genrestringnoneExact category name
performerstringnoneExact performer name
studiostringnoneExact studio name
censoredstringnonecensored or uncensored
numinteger101–50

Price: $0.40 per 1,000 at num=10; $2.00 at num=50.

Filters combine with AND. The draw is not uniform: the handler reads five random months, takes a random offset in each, shuffles and tops up when a narrow filter leaves it short. Consecutive calls return unrelated titles, not consecutive codes.

censored only matters as uncensored, which reads javbus's uncensored section instead of DMM + FANZA. Passing censored equals omitting it. No cache: every call samples again. The response has no meta and no source.

curl -s 'https://api.javinfo.dev/discover/random?num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "count": 3,
  "results": [
    {
      "code": "JUY-689",
      "title": "A Former Race Queen Married Woman Ai Izumi 32 Years Old Her Adult Video Debut!!",
      "titleJa": "元レースクイーンの人妻 和泉藍 32歳 AVDebut!!",
      "releaseDate": "2018-11-25",
      "runtimeMins": 120,
      "maker": "MADONNA",
      "label": "Madonna",
      "series": null,
      "categories": ["Debut", "Digital Mosaic", "…"],
      "actresses": ["Ai Izumi"],
      "cover": "https://pics.dmm.co.jp/digital/video/juy00689/juy00689pl.jpg",
      "rating": null,
      "source": "fanza",
      "url": null
    },
    "…"
  ]
}

And with the uncensored filter:

curl -s 'https://api.javinfo.dev/discover/random?censored=uncensored&num=2' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "count": 2,
  "results": [
    {
      "code": "KING-1009",
      "title": null,
      "titleJa": "Computer Fantasy",
      "releaseDate": "2004-08-24",
      "runtimeMins": 90,
      "maker": "POPMedia",
      "label": null,
      "series": null,
      "categories": [],
      "actresses": [],
      "cover": "https://www.javbus.com/imgs/cover/qq6_b.jpg",
      "rating": null,
      "source": "javbus",
      "url": "https://www.javbus.com/en/KING1009"
    },
    "…"
  ]
}

Status: 200, 400, 401, 402, 429.

/discover/for-you

API: /discover/for-you

Recommendations from the account's search history. Two keys on one account share it; history is per user, not per key.

ParameterTypeDefaultRange
numinteger201–50
lookbackinteger201–100, how many recent searches to read

Price: $0.80 per 1,000 at num=20; $0.40 at num ≤ 10.

Only successful /movie, /query and /idols calls count. The handler reads the last lookback rows, keeps up to five distinct queries, takes their top hits' tags, then picks recent titles sharing them. The /discover/trending score orders the answer.

basis explains the pick for display: queries used, tags derived, and fallback. With no history, fallback is true and the answer is the newest titles of the last 30 days.

curl -s 'https://api.javinfo.dev/discover/for-you?num=3' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "source": "discover:for-you",
  "count": 1,
  "results": [
    {
      "code": "FC2-PPV-4973873",
      "title": "FC2-PPV-4973873 [50% OFF for one week] [First time] A 35-year-old married bank employee with a cold demeanor. She's unp…",
      "titleJa": "FC2-PPV-4973873 【一週間50%OFF】【初】35歳既婚の塩対応銀行員。近寄りがたいから一転、バキュームフェラで濃厚ザーメンを搾り取る。口内射精、ごっくん合計2発。",
      "releaseDate": "2026-09-09",
      "runtimeMins": 35,
      "maker": "Fc2",
      "label": null,
      "series": null,
      "categories": ["Wife", "Adultery", "…"],
      "actresses": [],
      "cover": null,
      "rating": null,
      "source": "missav",
      "url": null
    }
  ],
  "meta": {
    "sources": ["missav"],
    "scanned": 1,
    "latencyMs": 115
  },
  "basis": {
    "queries": ["JQJ-002", "JUR-851", "…"],
    "tags": ["featured-actress", "big-tits", "…"],
    "fallback": false
  }
}

Status: 200, 400, 401, 402, 429.

/discover/stats

API: /discover/stats

Catalogue totals per source, with a timestamp. No parameters.

Price: $0.40 per 1,000 calls, flat.

Counts are index documents, so a title on two sources counts twice. asOf is the read time. Public GET /stats needs no key and caches a day, but reports provider counts: FANZA and DMM split, no total.

curl -s 'https://api.javinfo.dev/discover/stats' \
  -H "x-javinfo-key: jvi_your_key_here"
{
  "total": 3980531,
  "sources": {
    "fanza": 1759469,
    "javdatabase": 505464,
    "javlibrary": 430950,
    "javbus": 663879,
    "missav": 519017,
    "idols": 101752
  },
  "asOf": "2026-11-06T18:30:56.778Z"
}

Status: 200, 401, 402, 429.

Errors

Input is validated first. A bad parameter returns 400 with code: "BAD_REQUEST", message: "Input validation failed" and an issues array naming it. This surface never returns 422: out-of-range is 400, and so is a wrong type. range counts days, so range=7 works and range=week is 400 with issues[].path of ["range"]. The body from /discover/trending?num=500, above 50:

{
  "defined": false,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Input validation failed",
  "data": {
    "issues": [
      {
        "origin": "number",
        "code": "too_big",
        "maximum": 50,
        "inclusive": true,
        "path": ["num"],
        "message": "Too big: expected number to be <=50"
      }
    ]
  }
}

A missing key and a rejected key differ. No key at all:

{
  "defined": false,
  "code": "UNAUTHORIZED",
  "status": 401,
  "message": "Unauthorized"
}

A key the gate does not accept:

{ "error": "invalid api key" }

No credit. Nothing is charged; Retry-After is an hour:

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

Over the per-minute cap for the account. Retry-After is in seconds:

{ "error": "rate limit exceeded" }

404 is specific to /discover/similar, shown above. No other discovery endpoint returns it.

What is free

Only a fresh 200 is charged. Free:

  • A cache hit: X-Cache: HIT, no credit. /discover/random has no cache, so it never hits.
  • Any 4xx. A failed request is never billed.
  • A degraded answer: an upstream read fails, the API serves what it has, sets X-Degraded to the failed reads, and neither charges nor caches. Check it when a response looks thin.

X-Balance-Remaining is the credit left after the call.

On this page