{"id":27085360,"url":"https://github.com/gin337/chatgptreversed","last_synced_at":"2025-04-06T04:26:03.845Z","repository":{"id":244538516,"uuid":"815541659","full_name":"gin337/ChatGPTReversed","owner":"gin337","description":"Dependency Free ChatGPT API reversed and simplified","archived":false,"fork":false,"pushed_at":"2025-02-03T17:56:07.000Z","size":88,"stargazers_count":28,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-04T12:52:21.827Z","etag":null,"topics":["ai","api","chatgpt","chatgpt-api","chatgptnodejs","chatgptproxy","freechatgpt","freechatgpt4","freeopenai","js","nodejs","openai","openai-api","openaiapi","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/chatgptreversed","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gin337.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-06-15T12:24:55.000Z","updated_at":"2025-03-29T17:02:18.000Z","dependencies_parsed_at":"2024-06-15T13:51:53.829Z","dependency_job_id":"d81e7a40-a548-44cb-9d6b-f35256b07b81","html_url":"https://github.com/gin337/ChatGPTReversed","commit_stats":null,"previous_names":["gin337/chatgptreversed"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin337%2FChatGPTReversed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin337%2FChatGPTReversed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin337%2FChatGPTReversed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin337%2FChatGPTReversed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gin337","download_url":"https://codeload.github.com/gin337/ChatGPTReversed/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247432623,"owners_count":20938186,"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":["ai","api","chatgpt","chatgpt-api","chatgptnodejs","chatgptproxy","freechatgpt","freechatgpt4","freeopenai","js","nodejs","openai","openai-api","openaiapi","typescript"],"created_at":"2025-04-06T04:26:03.183Z","updated_at":"2025-04-06T04:26:03.839Z","avatar_url":"https://github.com/gin337.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ChatGPTReversed - Educational project\n\n## **Update 02.02.2025**: The `ChatGPTReversed` instance doesn't need any params anymore. Scroll to the End for documentation\n\nLets keep it simple, this is a educational project to learn to reverse complex API's and understand how they communicate with the frontend.\nIn this case we take a look at the ChatGPT frontend and reverse engineer the API used to communicate with the LLM.\n\nOpenAi uses several techniques to prevent malicious use of their API, eg. rate limiting, token expiration, hashing, proof of work, continious calls, proxies, captchas, etc.\n\nWe take a look at the ChatGPT webapp as starting point and only use the chromium devtools to understand the process.\n\n![step1](https://i.imgur.com/FbvbKML.png)\nWe start by opening the ChatGPT webapp and open the devtools to see the network requests.\n\n![step2](https://i.imgur.com/SSXA50s.png)\n`https://chatgpt.com/backend-api/conversation` endpoint is called with a POST request, we can see the payload and type of response. (In this case its a EventStream)\n\n![step3](https://i.imgur.com/52qYDXC.png)\n![step4](https://i.imgur.com/p3eRbQ8.png)\nSeveral Identifing headers and cookies are used to prevent abuse, in this case:\n`Authorization(JWT Token)`, `csrf-token(CSRF protection)`, `session-token (Same as the JWT token)`, `Requirements-Token \u0026 Proof Token`\n\n![step5](https://i.imgur.com/CwCzpnV.png)\n`https://chatgpt.com/backend-api/sentinel/chat-requirements` endpoint is called before the conversation starts, it passes in the token x and returns the token y.\n\n```json\n{\n  \"persona\": \"chatgpt-freeaccount\",\n  \"token\": \"y\",\n  \"arkose\": {},\n  \"turnstile\": {},\n  \"proofofwork\": {\n    \"required\": true,\n    \"seed\": \"0.81186133b2821174\",\n    \"difficulty\": \"073682\"\n  }\n}\n```\n\nTo find out how x is retrieved we need to take a look at the minified source code of the frontend.\n\n![step6](https://i.imgur.com/XuWosqk.png)\nToken x in this case is variable e which is passed as callback from variable n which uses the function `getRequirementsToken` to retrieve the token.\n![step7](https://i.imgur.com/hJfvHKS.png)\nThe function `getRequirementsToken` in this case returns the token x by checking if the value is already in a map called `answers`, if not it calls the function \\_generateAnswer which returns the token x by using a hash function provided by the hashing library `hash-wasm`.\n\n![step8](https://i.imgur.com/Ld0al4b.png)\nWe place a breakpoint right after the `getRequirementsToken` function is called and check the returned value which is the token x.\n\nSo we have the token x (Requirements token), we need to pass to the endpoint, we also have the token y (Required Requirements Token) which is returned by the endpoint. The last thing we need is the token z (Proof token) which as we find out is also generated with `_generateAnswer`.\n\n`_generateAnswer` function is called with the seed and difficulty returned by the endpoint, it uses the seed and also multiple parameters retrieved by the `getConfig` such as screen size, timezone, cpu cores, etc. to generate a hash and satisfy the difficulty condition. If no hash is found it will increment the step and try again. It falls back to a specified value after multiple steps.\n\nIn this case the function `_generateAnswer` is called with the seed and difficulty returned by the endpoint and that returns the token z.\n\nSo we have all the required tokens to call the conversation endpoint and start a conversation with the LLM.\nTo recap:\n\n- Session Token (JWT Token) is returned by `https://chatgpt.com/api/auth/session` in field `accessToken`\n\n- CSRF Token is returned by `https://chatgpt.com/api/auth/csrf` in field `csrfToken`\n\n- Requirements Token (Token x) is returned by `getRequirementsToken` function\n\n- Required Requirements Token (Token y) is returned by the endpoint `https://chatgpt.com/backend-api/sentinel/chat-requirements`\n\n- Proof Token (Token z) is returned by `_generateAnswer` function with the seed and difficulty returned by the `https://chatgpt.com/backend-api/sentinel/chat-requirements` endpoint\n\nThe rest is basic web communication knowledge.\n\n## Documentation\n\n```typescript\nimport {ChatGPTReversed} from \"chatgptreversed\"; // const {ChatGPTReversed} = require(\"chatgptreversed\");\n\nconst chatgpt = new ChatGPTReversed();\n\nconst result = await chatgpt.complete(\"Hello, how are you?\");\nconsole.log(result);\n\n// Output: Hello! I'm here and ready to assist you. How can I help you today?\n```\n\n```typescript\nimport {ChatGPTReversed} from \"chatgptreversed\"; // const {ChatGPTReversed} = require(\"chatgptreversed\");\n\nconst chatgpt = new ChatGPTReversed();\n\nasync function main() {\n  const result = await chatgpt.complete(\"Hello, how are you?\");\n  console.log(result);\n}\n\nmain();\n\n// Output: Hello! I'm here and ready to assist you. How can I help you today?\n```\n\nLike this project? Leave a star! 💫⭐\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgin337%2Fchatgptreversed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgin337%2Fchatgptreversed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgin337%2Fchatgptreversed/lists"}