Unofficial Python SDK for the Hack The Box (labs.hackthebox.com) API, reverse-engineered from live traffic.
Project description
htb-sdk
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b47cbab7d26ebbbc09317f9ae2043e00c22c6ea4805c63e42539116af0d81781
|
|
| MD5 |
e7f66720f34071d7bffc833576c2b0ef
|
|
| BLAKE2b-256 |
5987ddc60aa81459e9c7e4616f605066a91814cca235808cc2c0fe8859f7a663
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
754cc48bf5524c7c75da6be4e8d70e3dedbe3e3f0c1014ad2776696e8ddddbff
|
|
| MD5 |
6b82e9fceb2ccef7093af39c63e59ed3
|
|
| BLAKE2b-256 |
7b32862cb127b7e27a62045804aa9b632b99ffdecd9242f76a553a35f78cc208
|