Your miners, in your own tools.
Read your rented miners’ hashrate, shares and best difficulty from a script, a spreadsheet or Home Assistant. With a read-write key you can also rent, extend and manage miners using your WildWatts credit.
https://wildwatts.io/api/v1Get started in a minute
1. Sign in, open Account and find API keys. Give the key a name and confirm with your password, plus your authenticator code if you have two-factor on. Tick Allow rentals and changes only if the key needs to rent or change things.
2. Copy the key. It starts wwk_ and is shown only once.
3. Send it with every request:
curl https://wildwatts.io/api/v1/miners \
-H "Authorization: Bearer wwk_your_key_here"
Treat the key like a password. If it leaks, open Account and Rotate it: you get a new key and the old one stops working immediately. Delete removes it altogether. You can have up to 5 keys, for example one per app.
Endpoints
| Method and path | Key needed | What it does |
|---|---|---|
GET /v1/me | Any | Your username, credit balance and number of rentals |
GET /v1/miners | Any | All your rented miners with live stats |
GET /v1/miners/{id} | Any | One miner |
GET /v1/miners/{id}/history?hours=24 | Any | Hashrate, temperature and shares over time (1 to 168 hours, up to 500 points; set max_points for more) |
GET /v1/blocks | Any | Blocks your rentals have found |
GET /v1/stock | Any | What’s available to rent right now, with prices |
GET /v1/queue | Any | Your places in the queue for sold-out models |
POST /v1/rentals | Read-write | Rent a miner from your credit: {"model": "Avalon Q", "days": 7} |
POST /v1/miners/{id}/extend | Read-write | Extend a rental from your credit: {"days": 7} |
PUT /v1/miners/{id}/pool | Read-write | Point a miner at a pool: {"url", "wallet", "worker", "password"}, plus optional fallback_url, fallback_wallet, fallback_worker, fallback_password. The same safety checks as the website run first; add "skip_safety_checks": true to override them, as with the website’s “skip safety checks” box |
POST /v1/miners/{id}/restart | Read-write | Restart a miner |
POST /v1/queue | Read-write | Join the queue for a sold-out model: {"model": "Avalon Q", "days": 7}. The price is held from your credit |
DELETE /v1/queue/{id} | Read-write | Leave the queue; the held credit is refunded |
About the pool safety checks. Before a pool change is queued, WildWatts checks the address, the wallet and that the pool will actually accept your login, so a typo can’t leave your miner idle for the whole rental. skip_safety_checks turns those checks off for that one change. Only use it for a pool you know works: if the pool refuses the miner, it earns nothing until you change it back. Pool addresses and logins must still be plain text (no spaces, quotes or < >).
Rentals and extensions use the same prices, durations and credit balance as the website. Top-ups are made on the website. Model names and durations are the ones /v1/stock lists.
What a miner looks like
{
"id": 524,
"name": "Avalon Q 8",
"model": "Avalon Q",
"state": "mining",
"hashrate_ths": 93.1,
"hashrate_1h_avg_ths": 92.4,
"hashrate_24h_avg_ths": 92.9,
"temperature_c": 61.5,
"shares_accepted": 18422,
"shares_rejected": 12,
"best_difficulty": "1.24G",
"blocks_found": 0,
"pool": {
"url": "stratum+tcp://solo.ckpool.org:3333",
"user": "bc1q...your-address.worker",
"fallback_url": null,
"fallback_user": null,
"change_pending": false
},
"rental": {
"product": "Avalon Q 14 days",
"started_at": "2026-11-06T01:21:25Z",
"ends_at": "2026-11-20T01:26:25Z",
"hours_left": 316.2
},
"last_seen": "2026-11-06T15:29:13Z"
}
state is one of mining, starting (just rented, or a pool change on its way), paused or offline.
More examples
Python: print each miner’s hashrate
import requests
KEY = "wwk_your_key_here"
r = requests.get("https://wildwatts.io/api/v1/miners",
headers={"Authorization": f"Bearer {KEY}"}, timeout=20)
for m in r.json()["miners"]:
print(m["name"], m["hashrate_ths"], "TH/s", m["rental"]["hours_left"], "hours left")
Extend a rental by 7 days (read-write key)
curl -X POST https://wildwatts.io/api/v1/miners/524/extend \
-H "Authorization: Bearer wwk_your_key_here" \
-H "Content-Type: application/json" -d '{"days": 7}'
Home Assistant (configuration.yaml)
rest:
- resource: https://wildwatts.io/api/v1/miners
headers:
Authorization: "Bearer wwk_your_key_here"
scan_interval: 120
sensor:
- name: "WildWatts hashrate"
unit_of_measurement: "TH/s"
value_template: "{{ value_json.miners | sum(attribute='hashrate_ths') | round(2) }}"
Errors and limits
| Status | Meaning |
|---|---|
| 401 | No key, or the key was rotated or deleted |
| 402 | Not enough credit for that rental or extension |
| 403 | The key is read-only, or that action isn’t allowed |
| 404 | No such miner or queue entry on your account |
| 400 / 409 | The request can’t be done as asked; the detail field says why (for example a pool or wallet that won’t work) |
| 429 | Over 60 calls a minute. Wait the number of seconds in the Retry-After header |
Every error is JSON with a plain-English detail message. Stats refresh about every 30 seconds, so polling more often than that gains nothing.
Questions or ideas for the API? Get in touch.
Webhooks
Rather than asking every few minutes, let WildWatts tell you. Add up to 3 webhooks in Account (under API keys), choose which events each one receives, and we send an HTTPS POST to your address as soon as something happens. You get a signing secret (it starts whsec_) to check each request really came from us.
| Event | Sent when |
|---|---|
rental.started | A rental starts: from credit, from the queue, or a free session. data.source says which |
rental.extended | A rental is extended, including time we credit back |
rental.ending | A rental has 24 hours left (2 hours for rentals of a day or less) |
rental.ended | A rental has ended |
miner.offline | A miner stops reporting |
miner.online | It is back |
miner.paused | A miner stops producing shares; its rental clock is paused so you don’t lose time |
miner.resumed | It is producing again and its clock has resumed |
pool.applied | New pool settings have reached the miner |
block.found | One of your miners finds a block |
test | You press Send test in Account |
What we send
POST /your/endpoint
Content-Type: application/json
User-Agent: WildWatts-Webhooks/1.0
X-WildWatts-Event: miner.offline
X-WildWatts-Delivery: 1842
X-WildWatts-Signature: t=1793990000,v1=5f2c...e81a
{
"id": "evt_9c41d0b2a7e64f1d3b8a0c55",
"type": "miner.offline",
"created_at": "2026-11-06T18:02:11Z",
"data": {
"miner": {"id": 524, "name": "Avalon Q 8", "model": "Avalon Q"},
"message": "Avalon Q 8 has stopped reporting."
}
}
Check the signature, using the raw request body exactly as received:
import hmac, hashlib, time
def is_from_wildwatts(secret, signature_header, raw_body):
parts = dict(p.split("=", 1) for p in signature_header.split(","))
t, sent = parts["t"], parts["v1"]
if abs(time.time() - int(t)) > 300: # reject old or replayed requests
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sent)
Retries. Answer with any 2xx status within 10 seconds. Anything else is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours. If 10 deliveries in a row fail all their retries, the webhook is switched off and we email you; switch it back on in Account once your endpoint is fixed. The same event can occasionally arrive twice, so use id to ignore repeats.
Webhook addresses must use https:// and be reachable on the public internet. Requests are never redirected. Each delivery shows in Account under Deliveries, with the status your endpoint returned.
No miner yet?
Free sessions when available, paid miners from £1 a day.