{"_id":"@bogdanpet/hltv","_rev":"4-234136f78008e54b46e9f263bccdfdb9","name":"@bogdanpet/hltv","dist-tags":{"latest":"1.2.1"},"versions":{"1.0.0":{"name":"@bogdanpet/hltv","version":"1.0.0","keywords":["hltv","api","crawler","parser","csgo","cs2"],"author":{"name":"Bogdan Petrović"},"license":"MIT","_id":"@bogdanpet/hltv@1.0.0","maintainers":[{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"}],"homepage":"https://github.com/bogdanpetrovi/HLTV#readme","bugs":{"url":"https://github.com/bogdanpetrovi/HLTV/issues"},"dist":{"shasum":"f63d64e51095855c350601cc549ecd2475f256a2","tarball":"https://registry.npmjs.org/@bogdanpet/hltv/-/hltv-1.0.0.tgz","fileCount":35,"integrity":"sha512-GS6CJxyvUL6uzW8QY+JnSHijoiTTcyz8jHUTUVMP68RXyJXpxeXp5e45SLThgfjFl7tgMnH7uGphpAan+5R4kw==","signatures":[{"sig":"MEUCIAN+r2WdyyBlhtvLTwqCL8lJ/x8OAybF4aqA81jmvbDMAiEA5+qKd7aH4ZhJGFe9EsyU0CoJ0801nk8Qq/exf9dm0sU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32956},"jest":{"testRegex":"(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$","transform":{"^.+\\.tsx?$":"ts-jest"},"moduleFileExtensions":["ts","tsx","js","jsx","json","node"]},"main":"lib/index.js","types":"lib/index.d.ts","gitHead":"95781ba67e1efa11e965321d71b94bb3987b65bd","scripts":{"test":"jest --runInBand","build":"tsc -p tsconfig.release.json","start":"ts-node src/playground","pretty":"prettier --write \"**/*.ts\"","test:approve":"jest --runInBand --updateSnapshot"},"_npmUser":{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"},"repository":{"url":"git+https://github.com/bogdanpetrovi/HLTV.git","type":"git"},"_npmVersion":"11.9.0","description":"The unofficial HLTV Node.js API","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cheerio":"1.2.0","domhandler":"^6.0.1","playwright":"^1.60.0","playwright-extra":"^4.3.6","puppeteer-extra-plugin-stealth":"^2.11.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"29.7.0","ts-jest":"29.2.6","ts-node":"10.9.2","prettier":"3.5.3","typescript":"5.8.2","@types/jest":"29.5.14","@types/node":"18.19.79"},"_npmOperationalInternal":{"tmp":"tmp/hltv_1.0.0_1781730527121_0.6947317608540726","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@bogdanpet/hltv","version":"1.1.0","keywords":["hltv","api","crawler","parser","csgo","cs2"],"author":{"name":"Bogdan Petrović"},"license":"MIT","_id":"@bogdanpet/hltv@1.1.0","maintainers":[{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"}],"homepage":"https://github.com/bogdanpetrovi/HLTV#readme","bugs":{"url":"https://github.com/bogdanpetrovi/HLTV/issues"},"dist":{"shasum":"0ab9fdcd7c2de7bdd08799738c6986c46e2969f8","tarball":"https://registry.npmjs.org/@bogdanpet/hltv/-/hltv-1.1.0.tgz","fileCount":35,"integrity":"sha512-vVf6vauOl0H43CvSQ+g6Q6tsLSOHEwEKgrElxqwpTnmxSrZ8rHu+WnUoKEOUhVlyrIHVsXLebD6JN6/vJBcHow==","signatures":[{"sig":"MEUCIQCvGETkIzYaQhKOYywKZ5htXP3gjlOccK8Laddk0qzeRQIgEQB91h1IK5lZSn3kYq+guXCxZXF0QY1Xx8sGHkvaZ/0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDxfavE6qfQEntBUrSdI6NOh8Vl96xl7o9IhC7YdrBjgQIgEAWEFVzx2BfSYMmjJs08MhuE7Mk95yG1JmetybEs88U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44915},"jest":{"testRegex":"(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$","transform":{"^.+\\.tsx?$":"ts-jest"},"moduleFileExtensions":["ts","tsx","js","jsx","json","node"]},"main":"lib/index.js","types":"lib/index.d.ts","gitHead":"0419da4dbd53a7f67bbed6d6c4d8b4eff925e6f4","scripts":{"test":"jest --runInBand","build":"tsc -p tsconfig.release.json","start":"ts-node src/playground","pretty":"prettier --write \"**/*.ts\"","test:approve":"jest --runInBand --updateSnapshot"},"_npmUser":{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"},"repository":{"url":"git+https://github.com/bogdanpetrovi/HLTV.git","type":"git"},"_npmVersion":"11.9.0","description":"The unofficial HLTV Node.js API","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cheerio":"1.2.0","domhandler":"^6.0.1","playwright":"^1.60.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"29.7.0","ts-jest":"29.2.6","ts-node":"10.9.2","prettier":"3.5.3","typescript":"5.8.2","@types/jest":"29.5.14","@types/node":"18.19.79"},"_npmOperationalInternal":{"tmp":"tmp/hltv_1.1.0_1789732382271_0.8668035182835854","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bogdanpet/hltv","version":"1.2.0","keywords":["hltv","api","crawler","parser","csgo","cs2"],"author":{"name":"Bogdan Petrović"},"license":"MIT","_id":"@bogdanpet/hltv@1.2.0","maintainers":[{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"}],"homepage":"https://github.com/bogdanpetrovi/HLTV#readme","bugs":{"url":"https://github.com/bogdanpetrovi/HLTV/issues"},"dist":{"shasum":"6a3795f2d9e0bd132f41c123d65b636a5bcdfe11","tarball":"https://registry.npmjs.org/@bogdanpet/hltv/-/hltv-1.2.0.tgz","fileCount":35,"integrity":"sha512-o5QIzA4kuDf/BLKr2Rm5npcZQSTiebbfhy7XZaR9MFT+54g8oSXLXrNoz08IcWiLNZ6SmM8OPTdX9gEacQs95w==","signatures":[{"sig":"MEQCIA/fIqb/jR4j4eYaRuqjJkxLBLnl9LcVggypoFn2OG2yAiBf8KH/1RPv9Z9IfTcW6ufpyQYt6IOpw6wEfgl6XFE5rw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGhMG/gQEi9q1xHCI5LSPlCotZkvEPIAC6b46YiE9KtnAiEA/uxoX0/+4XHSchv/a56x7Z9MbwgIikb57oBjXiOplsE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45607},"jest":{"testRegex":"(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$","transform":{"^.+\\.tsx?$":"ts-jest"},"moduleFileExtensions":["ts","tsx","js","jsx","json","node"]},"main":"lib/index.js","types":"lib/index.d.ts","gitHead":"b1b9bec1f5129ff6789417ad6887b847b17d24e6","scripts":{"test":"jest --runInBand","build":"tsc -p tsconfig.release.json","start":"ts-node src/playground","pretty":"prettier --write \"**/*.ts\"","test:approve":"jest --runInBand --updateSnapshot"},"_npmUser":{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"},"repository":{"url":"git+https://github.com/bogdanpetrovi/HLTV.git","type":"git"},"_npmVersion":"11.9.0","description":"The unofficial HLTV Node.js API","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cheerio":"1.2.0","domhandler":"^6.0.1","playwright":"^1.60.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"29.7.0","ts-jest":"29.2.6","ts-node":"10.9.2","prettier":"3.5.3","typescript":"5.8.2","@types/jest":"29.5.14","@types/node":"18.19.79"},"_npmOperationalInternal":{"tmp":"tmp/hltv_1.2.0_1790689191411_0.25468755721586067","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"_id":"@bogdanpet/hltv@1.2.1","bugs":{"url":"https://github.com/bogdanpetrovi/HLTV/issues"},"dist":{"shasum":"2b9b2f4515cf2a191d80f2c8338bb8502af58319","tarball":"https://registry.npmjs.org/@bogdanpet/hltv/-/hltv-1.2.1.tgz","fileCount":35,"integrity":"sha512-gKWlgGkKTK8JQotU/h3+7VtkmqkfkES+W9ybT3HBiHTXjiU3ryhLt6BnBJ0N7rTi5uWGQMRqiCLkR2I5o1o2IA==","signatures":[{"sig":"MEUCIQD8mDAiKl9xidYHzSu+q5v0dqZRP1ylXVEiUXLbKJ787gIgWZb+lb/Y2jXuDhFPIfyjf5xS2zYWjvGWbBs8iT+01pY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFaZuu5Wer4HV7xaBeW4J3zuJkdnllAWWz9+U3pFcyd8AiEA7U59cn/0OANAdCHR+z8+el2dYILeFGg7grptnJLF7sQ="}],"unpackedSize":44304},"jest":{"testRegex":"(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$","transform":{"^.+\\.tsx?$":"ts-jest"},"moduleFileExtensions":["ts","tsx","js","jsx","json","node"]},"main":"lib/index.js","name":"@bogdanpet/hltv","types":"lib/index.d.ts","author":{"name":"Bogdan Petrović"},"gitHead":"ea367b2c27db9356b51ac610112c00fc52d4f912","license":"MIT","scripts":{"test":"jest --runInBand","build":"tsc -p tsconfig.release.json","start":"ts-node src/playground","pretty":"prettier --write \"**/*.ts\"","test:approve":"jest --runInBand --updateSnapshot"},"version":"1.2.1","_npmUser":{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"},"homepage":"https://github.com/bogdanpetrovi/HLTV#readme","keywords":["hltv","api","crawler","parser","csgo","cs2"],"repository":{"url":"git+https://github.com/bogdanpetrovi/HLTV.git","type":"git"},"_npmVersion":"11.9.0","description":"The unofficial HLTV Node.js API","directories":{},"maintainers":[{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"}],"_nodeVersion":"24.14.0","dependencies":{"cheerio":"1.2.0","domhandler":"^6.0.1","playwright":"^1.60.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"29.7.0","ts-jest":"29.2.6","ts-node":"10.9.2","prettier":"3.5.3","typescript":"5.8.2","@types/jest":"29.5.14","@types/node":"18.19.79"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/hltv_1.2.1_1790691931293_0.6713225541481083"}}},"time":{"created":"2026-06-17T21:08:46.930Z","modified":"2026-09-29T14:25:31.562Z","1.0.0":"2026-06-17T21:08:47.381Z","1.1.0":"2026-09-18T11:53:02.354Z","1.2.0":"2026-09-29T13:39:51.507Z","1.2.1":"2026-09-29T14:25:31.398Z"},"bugs":{"url":"https://github.com/bogdanpetrovi/HLTV/issues"},"author":{"name":"Bogdan Petrović"},"license":"MIT","homepage":"https://github.com/bogdanpetrovi/HLTV#readme","keywords":["hltv","api","crawler","parser","csgo","cs2"],"repository":{"url":"git+https://github.com/bogdanpetrovi/HLTV.git","type":"git"},"description":"The unofficial HLTV Node.js API","maintainers":[{"name":"bogdanpet","email":"bogdan.pettrovic@gmail.com"}],"readme":"<h1 align=\"center\">\r\n  <img src=\"https://www.hltv.org/img/static/TopLogo2x.png\" alt=\"HLTV logo\" width=\"200\">\r\n  <br>\r\n  The unofficial HLTV Node.js API\r\n  <br>\r\n</h1>\r\n\r\n> **IMPORTANT** \\\r\n> This project is a fork of [gigobyte/HLTV](https://github.com/gigobyte/HLTV), originally created by [gigobyte](https://github.com/gigobyte).\r\n> The original package is no longer maintained. This fork uses **Playwright** driving a real Google Chrome instead of `got-scraping` to get past Cloudflare bot protection. Only a subset of the original API is currently exposed. These are the endpoints that were required for my use case, but I'm open to adding more endpoints if there is interest or a need for them.\r\n\r\n## Table of contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#usage)\r\n- [API](#api)\r\n  - [getEvent](#getevent)\r\n  - [getMatches](#getmatches)\r\n  - [getResults](#getresults)\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @bogdanpet/hltv\r\nnpx playwright install chrome   # Google Chrome stable; the most reliable against Cloudflare\r\n```\r\n\r\nIf Google Chrome can't be installed (no root on the machine), install Playwright's bundled Chromium instead — the library falls back to it automatically:\r\n\r\n```bash\r\nnpx playwright install --with-deps chromium\r\n```\r\n\r\n> **WARNING** \\\r\n> Abusing this library will likely result in an IP ban from HLTV due to Cloudflare bot protection. Use with caution and limit the rate of your requests.\r\n\r\n## Usage\r\n\r\n```javascript\r\n// ESM\r\nimport HLTV from '@bogdanpet/hltv'\r\n\r\n// CommonJS\r\nconst { HLTV } = require('@bogdanpet/hltv')\r\n```\r\n\r\n### Custom configuration\r\n\r\nYou can create a custom instance if you want to provide your own page loader:\r\n\r\n```javascript\r\nconst myHLTV = HLTV.createInstance({\r\n  loadPage: async (url) => {\r\n    // your custom fetch logic\r\n  }\r\n})\r\n```\r\n\r\nBy default, the library uses **Playwright** with the system Google Chrome (falling back to Playwright's bundled Chromium) to load pages. Cookies — including Cloudflare's `cf_clearance` — are persisted to disk and reused across requests and restarts, and a Cloudflare challenge is given up to 30s (`challengeTimeout`) to resolve on its own.\r\n\r\nRequests are **not retried**: if a page is still blocked after that, the error is thrown to the caller immediately. Retrying from the same IP rarely helps and only adds to the IP's bad reputation, so retry policy (if any) is left to your application.\r\n\r\nThe browser can be tuned through `createLoadPage` or through environment variables (useful when the app itself can't be changed):\r\n\r\n```javascript\r\nimport HLTV, { createLoadPage } from '@bogdanpet/hltv'\r\n\r\nconst myHLTV = HLTV.createInstance({\r\n  loadPage: createLoadPage({\r\n    channel: 'chrome', // 'chrome' | 'chromium' | 'msedge'\r\n    headless: false, // run headed\r\n    proxy: 'http://user:pass@host:port', // or socks5://host:port\r\n    locale: 'de-DE',\r\n    timezoneId: 'Europe/Berlin',\r\n    stateFile: '/var/lib/myapp/hltv-state.json', // false to disable cookie persistence\r\n    challengeTimeout: 30000\r\n  })\r\n})\r\n```\r\n\r\n| Option             | Env variable           | Default                                      |\r\n| ------------------ | ---------------------- | -------------------------------------------- |\r\n| `channel`          | `HLTV_BROWSER_CHANNEL` | `chrome` → `chromium` → headless shell       |\r\n| `headless`         | `HLTV_HEADLESS`        | `true` (`false` to run headed)               |\r\n| `proxy`            | `HLTV_PROXY`           | none                                         |\r\n| `locale`           | `HLTV_LOCALE`          | `de-DE`                                      |\r\n| `timezoneId`       | `HLTV_TIMEZONE`        | system timezone                              |\r\n| `stateFile`        | `HLTV_STATE_FILE`      | `<tmpdir>/hltv-scraper/storage-state.json`   |\r\n| `challengeTimeout` | –                      | `30000`                                      |\r\n\r\nWhen a request is blocked the library throws a `CloudflareBlockedError` (message `CF_BLOCKED`) whose `details` carry the HTTP status, the `cf-mitigated` / `cf-ray` headers and the text that was matched, so you can tell a challenge (`cf-mitigated=challenge`) from a hard WAF block. After a block (or a navigation timeout) the saved cookies are discarded and the browser is relaunched, so the next call starts with a clean session.\r\n\r\n```javascript\r\nimport HLTV, { CloudflareBlockedError } from '@bogdanpet/hltv'\r\n\r\ntry {\r\n  const event = await HLTV.getEvent({ id: 7033 })\r\n} catch (err) {\r\n  if (err instanceof CloudflareBlockedError) {\r\n    console.error('Blocked by Cloudflare', err.details)\r\n  } else {\r\n    throw err\r\n  }\r\n}\r\n```\r\n\r\n## API\r\n\r\n---\r\n\r\n### getEvent\r\n\r\nParses info from the `hltv.org/events/*` page. (1 request)\r\n\r\n| Option | Type   | Description  |\r\n| ------ | ------ | ------------ |\r\n| id     | number | The event ID |\r\n\r\n```javascript\r\nconst event = await HLTV.getEvent({ id: 7033 })\r\n```\r\n\r\n**Returns:**\r\n\r\n```typescript\r\n{\r\n  id: number\r\n  name: string\r\n  logo: string\r\n  dateStart?: number  // unix timestamp\r\n  dateEnd?: number    // unix timestamp\r\n}\r\n```\r\n\r\n---\r\n\r\n### getMatches\r\n\r\nParses all upcoming and live matches for a given event from `hltv.org/events/:id/matches`. (1 request)\r\n\r\n| Option  | Type   | Description  |\r\n| ------- | ------ | ------------ |\r\n| eventId | number | The event ID |\r\n\r\n```javascript\r\nconst matches = await HLTV.getMatches(7033)\r\n```\r\n\r\n**Returns** an array of:\r\n\r\n```typescript\r\n{\r\n  id: number\r\n  date?: number       // unix timestamp, undefined for live matches\r\n  team1?: {\r\n    id?: number\r\n    name: string\r\n    logo?: string\r\n  }\r\n  team2?: {\r\n    id?: number\r\n    name: string\r\n    logo?: string\r\n  }\r\n  format?: string     // e.g. \"Bo3\"\r\n  event?: {\r\n    id: number\r\n  }\r\n  live: boolean\r\n}\r\n```\r\n\r\n---\r\n\r\n### getResults\r\n\r\nParses match results for a given event from `hltv.org/results?event=:id`. (1 request per page)\r\n\r\n| Option  | Type   | Description  |\r\n| ------- | ------ | ------------ |\r\n| eventId | number | The event ID |\r\n\r\n```javascript\r\nconst results = await HLTV.getResults(7033)\r\n```\r\n\r\n**Returns** an array of:\r\n\r\n```typescript\r\n{\r\n  id: number\r\n  result: {\r\n    team1: number // maps won\r\n    team2: number // maps won\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n## Credits\r\n\r\nOriginal package by [gigobyte](https://github.com/gigobyte/HLTV). This fork adds Playwright-based scraping to work around Cloudflare restrictions that broke the original implementation.\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}