Faucet JSON API
Everything the page does, you can do from a script: read status, solve a small proof-of-work, request testnet3 coins or a Lightning channel. No key, no account. Base URL https://faucet.satloot.com.
GET/api/status
Faucet address, on-chain balance and what is left of today's quota.
curl -s https://faucet.satloot.com/api/status
{"address":"tb1q…","balance_sat":1234567,"payout_sat":10000,"daily_remaining_sat":9876543}
GET/api/challenge
Get a proof-of-work challenge. Find a nonce so that sha256(token + ':' + nonce) starts with at least bits zero bits. The token is single-use and expires after 10 minutes.
curl -s https://faucet.satloot.com/api/challenge
{"token":"3f9a….1789200000.17","sig":"…","bits":17}
Reference solver (Python): iterate nonce from 0 until hashlib.sha256(f'{token}:{nonce}'.encode()).digest() has ≥ bits leading zero bits. Each claim needs its own challenge.
POST/api/claim
Send testnet3 coins to an address. Form-encoded body.
| Field | Meaning |
|---|---|
| address | Your testnet3 address (tb1…, m…, n…, 2…). |
| amount_sat | Optional. Clamped to 10000–50000 sat. |
| token, sig, nonce | From /api/challenge plus the nonce you found. |
| lang | Optional, en or zh: language of error messages. |
curl -s -X POST https://faucet.satloot.com/api/claim \
-d address=tb1q… -d amount_sat=10000 -d token=… -d sig=… -d nonce=12345 -d lang=en
{"ok":true,"txid":"…","amount_sat":10000,"explorer":"https://mempool.space/testnet/tx/…"}
Errors come back as {"ok":false,"error":"…"} with 400 (bad input / bad proof), 403 (recipient already holds more than 0.02 tBTC), 429 (cooldown or ban) or 503 (busy, empty, daily cap reached). Repeated bad requests earn a temporary ban.
GET/api/addrbalance?address=…
Confirmed + unconfirmed balance of any testnet3 address (via Esplora).
curl -s "https://faucet.satloot.com/api/addrbalance?address=tb1q…"
{"ok":true,"balance_sat":50000}
GET/api/txs
The faucet wallet's last 25 on-chain transactions, cached 45 s. net_sat is from the faucet's point of view (negative = payout).
[{"txid":"…","net_sat":-10000,"confirmations":3,"time":1789200000}, …]
GET/api/lninfo
Lightning faucet node URI and whether it can open a channel right now (synced and funded).
{"enabled":true,"node_uri":"03…@…:9735","synced":true,"capacity_sat":250000,"push_sat":100000}
POST/api/lnclaim
Open a 250,000 sat channel from the faucet to your testnet3 Lightning node and push 100,000 sat to your side. Same proof-of-work as /api/claim; your node must be reachable from the internet.
| Field | Meaning |
|---|---|
| node_uri | pubkey@host:port of your node. |
| token, sig, nonce | A fresh challenge and its solution. |
curl -s -X POST https://faucet.satloot.com/api/lnclaim -d node_uri=03…@1.2.3.4:9735 -d token=… -d sig=… -d nonce=…
{"ok":true,"txid":"…","push_sat":100000,"capacity_sat":250000,"explorer":"https://mempool.space/testnet/tx/…"}
Limits: one channel per node every 7 days, one per IP every 24 h, 20 channels a day in total. A node we cannot dial counts as a failed attempt.
Test coins have no value. Please send leftovers back to the address on the faucet page. Questions: [email protected].