Skip to main content

Unofficial Python SDK for the Hack The Box (labs.hackthebox.com) API, reverse-engineered from live traffic.

Project description

htb-sdk

CI PyPI Python

Unofficial Python SDK for the Hack The Box platform.

Hack The Box ships no official SDK and no public API docs. This library is reverse-engineered from the live traffic the real web app (app.hackthebox.com) sends to its backend (labs.hackthebox.com). The whole capture → analyze → generate pipeline is committed, so when HTB changes their API you can re-run it and regenerate an up-to-date map (see Refreshing the API map).

⚠️ Unofficial. Use against your own account, respect HTB's Terms of Service, and don't hammer the API.

Install

This project is managed with uv.

uv sync                  # runtime only (just the SDK + httpx)
uv sync --all-groups     # + dev tools (pytest, ruff) and the capture pipeline (playwright)

Then run things with uv run (e.g. uv run python ..., uv run pytest). Dependency groups: dev (pytest, respx, ruff) and capture (playwright, for the traffic-capture tooling under capture/).

Authentication

The SDK authenticates with an App Token (sent as Authorization: Bearer …), exactly like the web app's own JWT. Create one at Profile → Settings → App Tokens → Create App Token on app.hackthebox.com.

from htb import HTBClient

client = HTBClient(token="YOUR_APP_TOKEN")
# or:  export HTB_TOKEN=...   then HTBClient()

me = client.user.me()
print(me)

Quick start

from htb import HTBClient, Difficulty

client = HTBClient()  # reads HTB_TOKEN from the environment

# Machines
for m in client.machines.list(per_page=20):
    print(m["name"], m["difficultyText"])

box = client.machines.list(per_page=1)[0]
client.machines.spawn(box["id"])                      # start an instance
client.machines.submit_flag(box["id"], flag="HTB{...}", difficulty=Difficulty.MEDIUM)
client.machines.terminate(box["id"])

# Challenges
chal = client.challenges.get(806)
client.challenges.download(chal["id"], "challenge.zip")

# Anything not yet wrapped — raw access to any captured endpoint:
data = client.get("/api/v4/season/list")

What's covered

Everything that showed up in the captured traffic — see docs/ENDPOINTS.md for the complete, auto-generated map. Typed resource wrappers — 17 namespaces, ~104 methods, one module per API area: machines, challenges, sherlocks, fortresses, prolabs, endgames, tracks, seasons, user, teams, universities, rankings, connection (VPN), pwnbox, tokens (App Tokens), walkthroughs, platform (badges/tags/notices/...). For anything else, use the raw client.get/post/put/delete(...) escape hatch.

Types & enums

The package ships py.typed. Methods carry precise parameter and return annotations; responses are typed with TypedDicts in htb.models, and fixed-value fields have enums in htb.enums (Difficulty, MachineDifficulty, ChallengeDifficulty, OS, MachineState, ProductType, SubscriptionType). Enums subclass str/int so they serialize transparently and compare equal to the raw API values.

Project layout

src/htb/
  client.py            HTBClient — wires the resource namespaces
  _http.py             Transport: Bearer auth, retries, pagination
  errors.py            exception hierarchy
  enums.py             enums for fixed-value fields
  models/              TypedDict response models (one file per entity)
  resources/           one module per API area (machines, challenges, ...)
capture/               re-runnable capture → analyze → generate pipeline
docs/ENDPOINTS.md      generated API reference
tests/{unit,integration,e2e}/

Testing

uv run pytest                 # unit + integration (offline, respx-mocked)
uv run pytest --e2e           # + live end-to-end tests (needs HTB_TOKEN)
  • unit — transport, errors, enums in isolation
  • integration — every resource method against a mocked HTTP layer
  • e2e — read-only calls against the real API (skipped without --e2e)

Refreshing the API map

When HTB changes their API, recapture and regenerate (all read traffic + authorized write actions, captured from a real session):

uv run python capture/login_isolated.py     # isolated browser -> you log in once
uv run python capture/grab_token.py         # save the fresh session token
uv run python capture/extract_js_endpoints.py /tmp/htbjs/assets  # full map from frontend JS
DO_WRITES=1 uv run python capture/probe_full.py   # exercise every endpoint (GET + writes)
uv run python capture/analyze_har.py        # traffic.jsonl -> endpoints.json
uv run python capture/generate_reference.py # endpoints.json -> docs/ENDPOINTS.md

Capture runs in an isolated throwaway browser profile — it never touches your real Microsoft Edge / Google / Microsoft sessions. See capture/README.md for the full pipeline.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htb_sdk-0.1.0.tar.gz (68.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

htb_sdk-0.1.0-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file htb_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: htb_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 68.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for htb_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b47cbab7d26ebbbc09317f9ae2043e00c22c6ea4805c63e42539116af0d81781
MD5 e7f66720f34071d7bffc833576c2b0ef
BLAKE2b-256 5987ddc60aa81459e9c7e4616f605066a91814cca235808cc2c0fe8859f7a663

See more details on using hashes here.

File details

Details for the file htb_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: htb_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for htb_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 754cc48bf5524c7c75da6be4e8d70e3dedbe3e3f0c1014ad2776696e8ddddbff
MD5 6b82e9fceb2ccef7093af39c63e59ed3
BLAKE2b-256 7b32862cb127b7e27a62045804aa9b632b99ffdecd9242f76a553a35f78cc208

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page