{"openapi":"3.1.0","info":{"title":"JVID Public API","version":"1.0.0","summary":"Curated public, read-only API surface of JVID (www.jvid.com)","description":"Public read-only endpoints of the JVID platform (adult content, 18+). This is a curated specification: write, payment, and account-management endpoints are intentionally not exposed here. Public operations can be called anonymously; an optional JVID member Bearer token may provide personalized results. Operations tagged member read the signed-in member's own data and require a member token with the security role \"member\". OAuth2 delegated authorization and named OAuth scopes are not currently published. See https://www.jvid.com/llms.txt for a site overview.","contact":{"url":"https://www.jvid.com/support"},"license":{"name":"Proprietary","url":"https://www.jvid.com/privacypolicy/tos"},"x-audience":"adults-only (18+)","x-authentication-notes":{"anonymousAccess":true,"optionalAuthentication":"HTTP Bearer token","oauth2Available":false,"scopesAvailable":false,"roles":{"member":"Any signed-in JVID member account (bearer token from www.jvid.com sign-in). Grants read access to the member's own collections, follows, and browsing history."}}},"servers":[{"url":"https://ser.jvid.com","description":"JVID production API"}],"tags":[{"name":"product","description":"Products (videos, photo albums)"},{"name":"search","description":"Site-wide search"},{"name":"profile","description":"Model / creator public profiles"},{"name":"misc","description":"Banners, playlists, tags"},{"name":"member","description":"Signed-in member's own data (requires role member)"}],"paths":{"/api/product/index":{"get":{"tags":["product"],"operationId":"listProducts","summary":"List products","description":"Returns a paginated list of published products (photo albums, videos, official videos). Use category to choose the product type, userId to list one model's or creator's works, and sort, genre, boundary, or countryCode to filter. Product pages are https://www.jvid.com/v/{id}.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer","default":20},"description":"Items per page"},{"name":"userId","in":"query","required":false,"schema":{"type":"integer"},"description":"Filter by model or author ID"},{"name":"category","in":"query","required":true,"schema":{"type":"string","enum":["All","pics","vids","official_vids"]},"description":"Product category"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["publish_at_asc","publish_at_desc","price_asc","price_desc","view_times_asc","view_times_desc"]},"description":"Sort order"},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by model country code"},{"name":"genre","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by genre/style tag"},{"name":"boundary","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated rating-tag IDs, e.g. \"32,31,39\""}],"responses":{"200":{"description":"Product list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/product/detail":{"get":{"tags":["product"],"operationId":"getProductDetail","summary":"Get product detail","description":"Returns the public detail of a single product, such as title, price (USD), cover media, models, tags, and content size. productId is the ID used in product URLs such as https://www.jvid.com/v/{productId}.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"},"description":"Product ID"}],"responses":{"200":{"description":"Product detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid product ID or parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/product/trending/index":{"get":{"tags":["product"],"operationId":"listTrendingProducts","summary":"List trending products","description":"Returns trending products used by the homepage rankings. Categories include TrendingNow, TopTrending, and RecentUploads. Pass the resultKey returned by the first page to later pages to keep pagination stable.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"Trending category, e.g. TrendingNow, TopTrending, RecentUploads"},{"name":"resultKey","in":"query","required":false,"schema":{"type":"string"},"description":"Deduplication key returned by the first page"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer"},"description":"Items per page"}],"responses":{"200":{"description":"Trending product list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/tag/index":{"get":{"tags":["misc"],"operationId":"listTags","summary":"List product tags","description":"Returns the product tag taxonomy (genres, styles, and rating tags) for a usage context. Tag values can be used as genre or boundary filters in listProducts and searchProducts.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"usedType","in":"query","required":false,"schema":{"type":"string","default":"ProductList"},"description":"Tag usage context"},{"name":"productCategory","in":"query","required":false,"schema":{"type":"string"},"description":"Product category to scope tags (only with usedType=ProductList)"}],"responses":{"200":{"description":"Tag list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/banner/index":{"get":{"tags":["misc"],"operationId":"listBanners","summary":"List homepage banners","description":"Returns the promotional banners for a placement such as the homepage. Each banner has a target url (event page, playlist, or product) and localized button text.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","default":"index_top"},"description":"Banner placement type"}],"responses":{"200":{"description":"Banner list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid banner type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/playList/index":{"get":{"tags":["misc"],"operationId":"listPlaylists","summary":"List playlists","description":"Returns curated playlists (themed collections of products) for a placement such as the homepage. Playlist pages are https://www.jvid.com/playlist/{id}.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","default":"index_top"},"description":"Playlist placement type"}],"responses":{"200":{"description":"Playlist list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid playlist type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/search/index":{"get":{"tags":["search"],"operationId":"searchProducts","summary":"Search products","description":"Site-wide keyword search. Returns results grouped by type (for example products and playlists). Use searchByType to page through a single result type.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"keyword","in":"query","required":false,"schema":{"type":"string"},"description":"Search keyword"},{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"Product category filter"},{"name":"genre","in":"query","required":false,"schema":{"type":"string"},"description":"Genre/style tag filter"},{"name":"boundary","in":"query","required":false,"schema":{"type":"string"},"description":"Rating-tag filter"},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"},"description":"Country filter"},{"name":"sort","in":"query","required":false,"schema":{"type":"string"},"description":"Sort key, e.g. PublishAtDesc, PriceAsc, ViewTimesDesc, SaleTimesDesc"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer"},"description":"Items per page"}],"responses":{"200":{"description":"Search results grouped by type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid search parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/search/{searchType}":{"get":{"tags":["search"],"operationId":"searchByType","summary":"Search within a single result type","description":"Searches one result type (product or playList) with pagination. Use it after searchProducts to fetch more results of a single type.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"searchType","in":"path","required":true,"schema":{"type":"string","enum":["product","playList"]},"description":"Result type to search. Note the camelCase \"playList\" value."},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"},"description":"Search keyword"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer","minimum":10},"description":"Items per page (backend requires at least 10 for playList)"}],"responses":{"200":{"description":"Search results of the requested type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"400":{"description":"Invalid search parameters or search type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}},"404":{"description":"Search endpoint not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/user/profile":{"get":{"tags":["profile"],"operationId":"getUserProfile","summary":"Get public model/creator profile","description":"Returns the public profile information and badges of a model or creator by the userName used in profile URLs such as https://www.jvid.com/{userName}.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"userName","in":"query","required":true,"schema":{"type":"string"},"description":"Profile user name (URL slug)"}],"responses":{"200":{"description":"Public profile info and badges","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"404":{"description":"Profile not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/user/me/playList/collection":{"get":{"tags":["member"],"operationId":"listMyCollectedPlaylists","summary":"List my collected playlists","description":"Returns the playlists the signed-in member has added to their collection. Requires a member token (role member); anonymous calls return 401 with error.type PleaseLogin.","security":[{"bearerAuth":["member"]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer"},"description":"Items per page"}],"responses":{"200":{"description":"The member's collected playlists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"401":{"description":"Missing or invalid member token (error.type PleaseLogin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/user/me/follow":{"get":{"tags":["member"],"operationId":"listMyFollows","summary":"List models or creators I follow","description":"Returns the models (type=Model) or creators (type=Author) the signed-in member follows. Requires a member token (role member); anonymous calls return 401 with error.type PleaseLogin.","security":[{"bearerAuth":["member"]}],"parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","enum":["Model","Author"]},"description":"Followed account type"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer"},"description":"Items per page"}],"responses":{"200":{"description":"Followed models or creators","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"401":{"description":"Missing or invalid member token (error.type PleaseLogin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}},"/api/user/me/browsingProductHistory":{"get":{"tags":["member"],"operationId":"listMyBrowsingHistory","summary":"List my recently viewed products","description":"Returns the signed-in member's product browsing history, most recent first. Requires a member token (role member); anonymous calls return 401 with error.type PleaseLogin.","security":[{"bearerAuth":["member"]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number"},{"name":"size","in":"query","required":false,"schema":{"type":"integer","default":10},"description":"Items per page"}],"responses":{"200":{"description":"Recently viewed products","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiEnvelope"}}}},"401":{"description":"Missing or invalid member token (error.type PleaseLogin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendError"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"JVID member access token (HTTP bearer) issued when a user signs in on www.jvid.com. Public operations accept it optionally for personalized results. Operations tagged member require it; their security requirement lists the role name \"member\" (OpenAPI 3.1 role names for non-OAuth schemes), meaning any signed-in JVID member account. No OAuth2 delegated authorization, named OAuth scopes, or agent token issuance is currently published."}},"schemas":{"ApiEnvelope":{"type":"object","description":"Standard JVID API response envelope","properties":{"data":{"description":"Response payload"}},"additionalProperties":true},"BackendError":{"type":"object","description":"Error envelope returned by the JVID backend API","examples":[{"success":false,"message":"page must be greater than or equal to 1","error":{"data":null,"type":"requestParameterValidatedError","i18nErrorContentKey":"requestParameterValidatedErrorContent","i18nErrorTitleKey":"requestParameterValidatedErrorTitle"}},{"data":null,"success":false,"message":"User does not exist"},{"success":false,"error":{"i18nErrorTitleKey":"friendlyReminder","type":"PleaseLogin","i18nErrorContentKey":"pleaseLogin","data":{"code":"401"}},"message":"Please login first"}],"required":["success","message"],"properties":{"success":{"type":"boolean","const":false,"description":"Whether the request succeeded"},"message":{"type":"string","description":"Human-readable error message"},"data":{"description":"Optional response data; usually null for errors"},"error":{"type":["object","null"],"description":"Optional backend error metadata","properties":{"data":{"description":"Optional error-specific data"},"type":{"type":"string","description":"Backend error type, e.g. requestParameterValidatedError, NoHandlerFoundException, or PleaseLogin (401)"},"i18nErrorContentKey":{"type":"string","description":"Optional localization key for the error content"},"i18nErrorTitleKey":{"type":"string","description":"Optional localization key for the error title"}},"additionalProperties":true}},"additionalProperties":true}}}}