{"id":24261893,"url":"https://github.com/millenniumearl/f95api","last_synced_at":"2025-09-23T21:31:56.664Z","repository":{"id":37006283,"uuid":"299650339","full_name":"MillenniumEarl/F95API","owner":"MillenniumEarl","description":"Unofficial Node JS module for scraping F95Zone platform","archived":false,"fork":false,"pushed_at":"2024-05-18T00:24:24.000Z","size":2998,"stargazers_count":25,"open_issues_count":16,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-05-18T01:26:35.497Z","etag":null,"topics":["api","f95zone","game","games","login","nsfw","scraper","userdata"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MillenniumEarl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-29T14:55:57.000Z","updated_at":"2024-04-18T07:08:02.000Z","dependencies_parsed_at":"2024-04-26T17:42:36.343Z","dependency_job_id":"c6e62e5e-c1ac-42d9-b108-8aa60fe67ffc","html_url":"https://github.com/MillenniumEarl/F95API","commit_stats":{"total_commits":1371,"total_committers":13,"mean_commits":"105.46153846153847","dds":0.6360320933625091,"last_synced_commit":"b4ff1e05effc0e4cdfbbeab0bb3fdc17ae2ee3ee"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MillenniumEarl%2FF95API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MillenniumEarl%2FF95API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MillenniumEarl%2FF95API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MillenniumEarl%2FF95API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MillenniumEarl","download_url":"https://codeload.github.com/MillenniumEarl/F95API/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234001690,"owners_count":18764310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","f95zone","game","games","login","nsfw","scraper","userdata"],"created_at":"2025-01-15T06:49:33.136Z","updated_at":"2025-09-23T21:31:51.272Z","avatar_url":"https://github.com/MillenniumEarl.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CodeFactor](https://www.codefactor.io/repository/github/millenniumearl/f95api/badge)](https://www.codefactor.io/repository/github/millenniumearl/f95api)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FMillenniumEarl%2FF95API.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FMillenniumEarl%2FF95API?ref=badge_shield)\n[![Known Vulnerabilities](https://snyk.io/test/github/MillenniumEarl/F95API/badge.svg)](https://snyk.io/test/github/MillenniumEarl/F95API)\n[![codecov](https://codecov.io/gh/MillenniumEarl/F95API/branch/master/graph/badge.svg?token=KHN1TNIH7D)](https://codecov.io/gh/MillenniumEarl/F95API)\n[![npm](https://img.shields.io/npm/v/@millenniumearl/f95api.svg)](https://www.npmjs.com/package/@millenniumearl/f95api)\n\n# F95API\n\nUnofficial Typescript API used for data scraping from the F95Zone platform.\n\nThese APIs have been developed to support [this application](https://github.com/MillenniumEarl/YAM) and allow you to obtain data on games and mods on the platform [F95zone](https://f95zone.to/) (**NSFW**)\n\nA simple usage example can be found in [src/example.ts](https://github.com/MillenniumEarl/F95API/blob/master/src/example.ts)\n\n# Table of Contents\n\n- [Main features](#main-features)\n- [Login](#login)\n- [Data scraping](#data-scraping)\n- [Classes](#classes)\n  - [Handiwork](#handiwork)\n    - [Basic properties](#basic-properties)\n    - [Mixed properties](#mixed-properties)\n  - [Platform user](#platform-user)\n  - [User data](#user-data)\n  - [Login result](#login-result)\n- [Logging](#logging)\n- [Guidelines for errors](#guidelines-for-errors)\n\n# Main features\n- Support for two-factor authentication\n- Structured and typed data of games, mods, comics, assets and animations\n- Structured and typed data of the current user (threads followed, favorites...)\n- Structured and typed data of other users (titles, donations, registration date...)\n- Standard search, through the \"Latest Updates\" page or advanced\n- Saving of cookies to maintain the session\n\n# Login\nIn addition to traditional login, two-factor authentication via callback that returns the OTP value is also supported.\n\n```javascript\n// Normal login\nlet result = await F95API.login(username, password);\n\n// 2FA login\nlet 2faCallback = function () =\u003e Promise\u003cnumber\u003e;\nlet result = await F95API.login(username, password, 2faCallback);\n````\n\nRefer to [src/example.ts](https://github.com/MillenniumEarl/F95API/blob/master/src/example.ts#L35-L67) (lines 35-67) for a working example.\n\n# Data scraping\nEach game, mod, comic, animation or asset is identified as handiwork and obtaining this element is generic, it will then be up to the user to decide which property to use based on the type of handiwork that has been requested.\n\nHandiworks can be obtained by query or by URL.\n\n```javascript\n// With query\nconst query = {\n    category: \"games\";\n    keywords = \"Your game name\";\n    order = \"likes\";\n};\n\nlet listOfFoundGames = await F95API.searchHandiwork\u003cGame\u003e(query);\n\n// With URL\nlet specificGame = await F95API.getHandiworkFromURL\u003cGame\u003e(\"the URL of your game\");\n```\n\nWhile user data (after authenticating) with \n\n```javascript\nconst userdata = new UserProfile();\n\n// Fetch basic data (always necessary)\nawait userdata.fetch();\n\n// Fetch all data (may take a while)\nawait userdata.fetch(true);\n\n// Async properties\nconst threads = await userdata.watched;\nconst bookmarks = await userdata.bookmarks;\nconst alerts = await userdata.alerts;\nconst games = await userdata.featuredGames;\n```\n\n# Classes\n## Handiwork\nInformation about games, mods, etc... are stored in a [Handiwork](https://github.com/MillenniumEarl/F95API/blob/master/src/scripts/classes/handiwork/handiwork.ts) object with the following fields:\n\n### Basic properties\n\nThis list of properties is common to every handiwork, be it a game, a comic, etc...\n\n| Property              | Type         | Description   |\n| :--------------------:|:------------:|:--------------|\n| `id`                  |`number`      | Unique ID of the thread associated with the handiwork in the platform|\n| `name`                |`string`      | The handiwork name|\n| `overview`            |`string`      | Description of the handiwork|\n| `authors`             |`TAuthor[]`   | The developer of this handiwork including the platforms on which it can be found|\n| `category`            |`TCategory`   | The membership category|\n| `changelog`           |`TChangelog[]`| List of changes divided by version|\n| `cover`               |`string`      | URL of the possible cover of the handiwork (in case of multiple images the first available is taken)|\n| `lastThreadUpdate`    |`Date`        | Date of the last update of the thread associated with the handiwork|\n| `prefixes`            |`string[]`    | List of prefixes|\n| `rating`              |`TRating`     | Users' ratings on the handiwork (average, maximum, minimum, number of votes)|\n| `tags`                |`string[]`    | List of tags|\n| `threadPublishingDate`|`Date`        | Publication date of the thread associated with the handiwork|\n| `url`                 |`string`      | The URL that leads to the handiwork's thread on F95Zone|\n\n### Mixed properties\n\nEach property is specific to a particular type of handiwork.\n\n| Property            | Type     | Handiwork type    |Description   |\n| :------------------:|:--------:|:-----------------:|:--------------|\n| `genre`             |`string[]`|`Animation`/`Comic`/`Game`| List of genres represented in this work|\n| `pages`             |`string`  |`Animation`/`Comic`| Number of pages or elements of which the work is composed|\n| `resolution`        |`string[]`|`Animation`/`Comic`| List of resolutions available for the work |\n| `installation`      |`string`  |`Animation`        | Installation instructions|\n| `language`          |`string[]`|`Animation`        | List of available languages|\n| `length`            |`string`  |`Animation`        | Length of the animation |\n| `censored`          |`boolean` |`Animation`/`Game` | Are the NSFW parts censored?|\n| `engine`            |`TEngine` |`Game`             | Game engine (Unity, Ren'Py, RPGM...)|\n| `lastRelease`       |`Date`    |`Game`             | Date of the last update of this handiwork|\n| `mod`               |`boolean` |`Game`             | Specify if it is a mod or a real game|\n| `os`                |`string[]`|`Game`             | List of supported OS (Windows/Linux/Mac/Android...)|\n| `status`            |`TStatus` |`Game`             | State of development (Completed/Abandoned/Ongoing/Onhold)|\n| `version`           |`string`  |`Game`             | Version of the handiwork|\n| `assetLink`         |`string`  |`Asset`            | External URL of the asset (es. Daz3D store) |\n| `associatedAssets`  |`string[]`|`Asset`            | List of URLs of assets associated with the work (for example same collection) |\n| `compatibleSoftware`|`string[]`|`Asset`            | Software compatible with the work |\n| `includedAssets`    |`string[]`|`Asset`            | List of assets url included in the work or used to develop it |\n| `officialLinks`     |`string[]`|`Asset`            | List of official links of the work, external to the platform (es. Daz3D store) |\n| `sku`               |`string`  |`Asset`            | Unique SKU value of the work |\n\nThe serialization/deserialization in JSON format of this object is possible through `JSON.stringify()`/`JSON.parse()`.\n\n## Platform user\n\nA generic user registered on the platform is represented by a [PlatformUser](https://github.com/MillenniumEarl/F95API/blob/master/src/scripts/classes/mapping/platform-user.ts) object with the following fields:\n\n| Property         | Type      | Description   |\n| :---------------:|:---------:|:--------------|\n| `id`             | `number`  | Unique user ID |\n| `name`           | `string`  | Username |\n| `title`          | `string`  | Title assigned to the user by the platform |\n| `banners`        | `string[]`| List of banners assigned by the platform |\n| `messages`       | `number`  | Number of messages written by the user |\n| `reactionScore`  | `number`  | Total number of reactions received from other users |\n| `points`         | `number`  | Total number of points received after the acquisition of trophies |\n| `ratingsReceived`| `number`  | Number of ratings received |\n| `joined`         | `Date`    | Date of joining the platform |\n| `lastSeen`       | `Date`    | Date of the last connection to the platform |\n| `followed`       | `boolean` | Indicates whether the user is followed by the currently logged in user |\n| `ignored`        | `boolean` | Indicates whether the user is ignored by the currently logged on user |\n| `private`        | `boolean` | Indicates that the profile is private and not viewable by the user |\n| `avatar`         | `string`  | URL of the image used as the user's avatar |\n| `amountDonated`  | `number`  | Value ($) of donations made |\n\n## User data\n\nThe user data currently connected through this API extends the [PlatformUser](https://github.com/MillenniumEarl/F95API/blob/master/src/scripts/classes/mapping/platform-user.ts) class via the class [UserProfile](https://github.com/MillenniumEarl/F95API/blob/master/src/scripts/classes/mapping/user-profile.ts) and adds:\n\n| Property         | Type                        | Description   |\n| :---------------:|:---------------------------:|:--------------|\n| `watched`        | `Promise\u003cIWatchedThread[]\u003e` | List of followed thread data|\n| `bookmarks`      | `Promise\u003cIBookmarkedPost[]\u003e`| List of bookmarked posts data|\n| `alerts`         | `Promise\u003cIAlert[]\u003e`         | List of alerts|\n| `conversations`  | `Promise\u003cIConversation[]\u003e`  | List of conversations (only **without** labels)|\n| `featuredGames`  | `Promise\u003cGame[]\u003e`           | List of featured games from the platform (carousel, may not be available if disabled in settings)|\n\n## Login results\n\nThe outcome of the authentication process is represented by the [LoginResult](https://github.com/MillenniumEarl/F95API/blob/master/src/scripts/classes/login-result.ts) object:\n\n\n| Property | Type     | Description   |\n| :-------:|:--------:|:--------------|\n| `success`| `boolean`| List of followed thread data|\n| `code`   | `number` | Code associated with the result of the login operation|\n| `message`| `string` | Possible error message (unrecognized user, wrong password...) or authentication successful message|\n\n# Logging\nTo log the behavior of the application [log4js-api](https://github.com/log4js-node/log4js-api) is used with a default level of \"warn\". This option can be changed with the `loggerLevel` property.\n\n# Guidelines for errors\n\n- If you can, return a meaningful value\n- Return `null` only if the function should return a complex object (including strings)\n- Return an empty array if the function should return an array\n- Return `false`, `-1` when the function should return `boolean` or `number`\n- Throw an exception only if it is an error or if a wrong value could mess up the functioning of the library\n- For all network operations, return a `Result` object\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmillenniumearl%2Ff95api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmillenniumearl%2Ff95api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmillenniumearl%2Ff95api/lists"}