Skip to main content

Denpasoft: Age Verification

This site contains content intended for adults. Please confirm you are at least 18 years old to continue.

Developers

Public, machine-readable interfaces to the Denpasoft catalog.

Overview

The Denpasoft public API is a free, read-only set of HTTP endpoints serving the published catalog directly from the edge. No API keys, no authentication, no per-user state: every documented endpoint returns the same data to every caller. Use it to build search tools, catalog browsers, feed readers, or link previews.

A machine-readable description of the JSON endpoints is published at /openapi.json (OpenAPI 3.1).

Stability policy

Endpoints documented on this page follow a stable-contract rule:

  • Publicly documented means identity-free (the response never depends on who is asking) and edge-terminated (served from our edge, not proxied per-request to a backend).
  • Changes are additive only: new optional fields may appear in responses at any time; existing fields will not change meaning or type.
  • Breaking changes get a new path. Existing paths keep their contract.

Anything not documented on this page — including other paths under /api/ — is internal and may change or disappear without notice. Do not build against it.

Conventions

  • All endpoints are GET.
  • Errors are JSON: { "code": string, "message": string }.
  • Rate-limited requests return 429.
  • Most product-list responses share one envelope: { "results": SearchHit[] }. The paginated catalog listing (/api/public/v1/catalog/list) is the exception — it returns { products, total, totalPages }.
  • The product page for a hit is https://denpasoft.com/product/{slug}.

A SearchHit is a product card object:

{
  "databaseId": 123,            // number — stable product id
  "slug": "example-title",      // string — /product/{slug}
  "name": "Example Title",      // string
  "imageUrl": "https://…",      // string | null — cover image
  "regularPrice": "24.99",      // string | null
  "salePrice": "19.99",         // string | null
  "onSale": false               // boolean
}

New optional fields may be added to SearchHit over time (additive-only policy); ignore fields you do not recognize.

Endpoints

GET /api/search

Instant text search over the published catalog. Example: https://denpasoft.com/api/search?q=clover&limit=8

Parameter Description
q Search text. Queries shorter than 2 characters return an empty result list (still 200).
limit Optional. Maximum hits to return: 1–12, default 8. Out-of-range values are clamped, not rejected.
  • The parameter set is closed: any query parameter other than q and limit returns 400.
  • Response: { "results": SearchHit[] }. A query with no matches returns an empty list, not an error.
  • Errors: 400 (unknown parameter), 429 (rate limited).
  • Caching: no-store — do not cache responses.

GET /api/catalog/by-ids

Hydrate a list of product ids into SearchHit objects. Example: https://denpasoft.com/api/catalog/by-ids?ids=101,102,103

Parameter Description
ids Required. Comma-separated positive integers. Duplicates are removed (first occurrence wins; input order is preserved in the response). At most 20 ids are used — extras are silently ignored. If no valid id survives parsing (missing, empty, or wholly malformed), the request is rejected with 400.
  • The parameter set is closed: only ids is accepted; any other parameter returns 400.
  • Response: { "results": SearchHit[] }. Ids that do not resolve to a published product are dropped silently; surviving hits keep the input order.
  • Errors: 400, 429.
  • Caching: no-store.

GET /api/public/v1/catalog/list

Page through the published catalog — everything, newest, on sale, featured, or filtered by category, brand, or developer. This is the stable third-party catalog listing. Example: https://denpasoft.com/api/public/v1/catalog/list?scope=new&page=1&per_page=24

Parameter Description
scope Optional. One of all, new, sale, featured, category, brand, or developer. An unsupported value — or a scope whose required slug is missing — yields an empty page (still 200).
category Category slug. Required when scope=category.
publisher Brand/publisher slug. Required when scope=brand, or pass it on any scope as a cross-axis filter.
developer Developer slug. Required when scope=developer, or pass it on any scope as a cross-axis filter.
page Optional. 1-based page number; out-of-range or non-numeric values fall back to 1.
per_page Optional. Page size, clamped to 1–48 (default 24).
  • The parameter set is closed: any query parameter other than scope, category, publisher, developer, page, and per_page returns 400.
  • Response is the paginated envelope (not the shared results one): { "products": SearchHit[], "total": number, "totalPages": number }.
  • Fail-open: an unavailable or incomplete catalog mirror returns 200 { "products": [], "total": 0, "totalPages": 0 } — treat an empty page as "no results", not an error.
  • Errors: 400 (unknown parameter), 429 (rate limited).
  • Caching: no-store.

GET /api/recommend

Similar titles by example: pass a seed of product ids you like and get back catalog picks in the same vein. Example: https://denpasoft.com/api/recommend?ids=101,102

Parameter Description
ids Required. Comma-separated positive integers — the seed titles. Same parsing rules as by-ids, but capped at 10 seed ids. Missing or wholly invalid → 400.
  • Response: { "results": SearchHit[] } with up to 8 picks. Seed titles are excluded from the results.
  • Fail-open: when no picks are available, the response is 200 { "results": [] } — treat an empty list as "no suggestions", not an error.
  • Errors: 400, 429.
  • Caching: no-store.

GET /api/oembed

oEmbed 1.0 provider (link type) for the storefront's embeddable pages — public user profiles and product pages. Embeddable pages advertise this endpoint via a <link rel="alternate" type="application/json+oembed"> discovery tag. Example: https://denpasoft.com/api/oembed?url=https://denpasoft.com/profile/{publicId}&format=json

Parameter Description
url Required. Absolute URL of the page to embed. Must be on the same host as the request; a missing or unparseable value returns 400.
format Optional. Only json is supported; any other value returns 501.
  • Response: an oEmbed 1.0 link payload — version, type, title, provider_name, provider_url, plus optional author_name, author_url, and thumbnail_url.
  • A URL that is not embeddable — wrong host, unknown page, a private profile, or an unindexed product — returns the same 404 in every case.
  • thumbnail_url is intentionally a blurred preview image.
  • Caching: no-store.

Feeds

Catalog and news feeds for readers, aggregators, and bulk consumers:

Path Format Contents
/feed/ RSS 2.0 Site news (latest 20 posts).
/feed/new-releases RSS 2.0 Newest catalog releases.
/feed/new-releases.json JSON Newest releases, JSON product envelope.
/feed/products.json JSON Published-catalog product snapshot.
/feed/products.csv CSV Same data as products.json, one row per product.
/feed/sales.json JSON Titles currently on sale.
/feed/theme/{term}
/feed/brand/{term}
/feed/developer/{term}
RSS 2.0 Per-theme / per-brand / per-developer release feeds.

The JSON feeds share one envelope: { "schemaVersion", "feed", "count", "products": [...] }, where each product carries id, slug, canonical URL, name, image, prices, and taxonomy terms. schemaVersion only changes on breaking revisions; new optional fields may appear within a version. JSON feeds are CORS-enabled (Access-Control-Allow-Origin: *).

Feeds are publicly cacheable (Cache-Control: public, max-age=1800, s-maxage=3600) — honor these headers and poll no more than the cache lifetime. Degraded responses use a short retry TTL.

Discovery surfaces

  • /sitemap-index.xml — sitemap index linking the per-section sub-sitemaps (products, categories, brands, developers, news, and more).
  • /robots.txt — crawl policy and sitemap pointer.
  • /opensearch.xml — OpenSearch description for browser search integration.
  • Catalog pages embed schema.org JSON-LD structured data.

Fair use

  • All endpoints are rate-limited per IP. Sustained excess traffic receives 429 responses — back off and retry later.
  • Cache responses wherever the headers allow it; prefer the bulk feeds over hammering the per-request endpoints.
  • Identify your client with a descriptive User-Agent (project name plus a contact URL or email).
  • Security issues: see /.well-known/security.txt.

Data licensing

Parts of the catalog's tag/metadata vocabulary (e.g. the themeTags fields in the JSON feeds) contain information from VNDB, made available under the Open Database License (ODbL) v1.0 with contents under the DbCL v1.0. JSON envelopes carry a machine-readable license stanza with the attribution notice.

If you redistribute that tag data, preserve the attribution and see /policy/data-licenses/ for scope and full terms. Everything else in the catalog (products, prices, descriptions, images) is not openly licensed.

Install denpasoft for one-tap access and offline browsing.

Install denpasoft: tap Share, then Add to Home Screen.

Installing to your PC

Queued