1. Cookbook
TunnelSats Public Wireguard API
  • Announcements
    • 👋 About our team
    • 💫 What is TunnelSats?
    • 🚀 Introducing the TunnelSats Public API v1
    • 🧩 How the TunnelSats StartOS Package Uses the Public API
    • How TunnelSats Leverages Public APIs for Confined VPN Management
  • 📡 Discovery
    • List Available WireGuard Servers & Regions
      GET
  • ⚡ Purchase
    • Create a New WireGuard Subscription (Invoice Generation)
      POST
    • Check Invoice Status & Polling by Payment Hash
      GET
    • Claim WireGuard Configuration After Payment Settlement
      POST
  • 🔄 Lifecycle
    • Get Subscription & Bandwidth Status by WireGuard Public Key
      POST
    • Sync Subscription (Real-Time Server Refresh)
      POST
    • Renew an Existing VPN Subscription (Anonymous)
      POST
    • Request Bandwidth Top-Up ($1 Usage Reset)
      POST
  • 🔑 Account
    • List Account Subscriptions (Authenticated)
      GET
    • Create Referral Code
      POST
    • Get Referral Code
      GET
    • Referral History
      GET
  • 🔧 Tools
    • Lightning Node Network Address Discovery
    • Universal Connectivity & Latency Probe
  • Cookbook
    • 🛠️ Automation & Code Examples
    • 🐚 Bash One-Liners
    • 🚑 Node Health & Upkeep
    • ⚡ Bandwidth Top-Up ($1 Usage Reset)
    • 🛡️ Security & Authentication
    • 🎁 Referral Program: Earn Bonus Months
    • 🛑 Error Codes & Troubleshooting
  • Schemas
    • Server
    • InvoiceOrder
    • SubscriptionStatus
    • NodeLookup
    • ConnectivityResult
    • ApiError
    • ClaimResult
    • BandwidthResetResponse
    • PublicKeyStatusResponse
    • SubscriptionListItem
    • ReferralCode
    • ReferralHistory
    • BandwidthResetPaymentStatus
    • RenewalOrder
    • SyncResult
Tunnelsats Github
Tunnelsats Telegram
  1. Cookbook

⚡ Bandwidth Top-Up ($1 Usage Reset)

This guide provides complete instructions and production-ready code examples to programmatically purchase and trigger an instant bandwidth reset for your active WireGuard tunnel: this month's usage counter goes back to 0 GB, so the full allowance is available again.

🎯 Overview#

Each TunnelSats subscription includes 100 GB of bandwidth per calendar month. At any usage, including after the peer was disabled for exceeding its allowance, you can buy a $1 USD bandwidth reset in Bitcoin Lightning (sats) instead of waiting for the free reset on the 1st. A reset sets the usage counter back to 0 GB, so you get back what you used so far. It does not add allowance on top, and unused allowance does not carry over, so a reset is worth most when usage is high.
Node management packages (e.g., RaspiBlitz, Umbrel, Start9, Baremetal, LNDg) and automation daemons can monitor usage via /api/public/v1/subscription/status and request a reset when their own usage policy says so, for example at 90% of the allowance.
/subscription/status also tells you whether a reset is available before you request one: it returns bandwidth_used_gb, bandwidth_limit_gb, bandwidth_resets_this_month and max_resets_per_month. bandwidth_resets_this_month is the same count this endpoint checks: once it reaches max_resets_per_month, a request gets HTTP 429, unless one of those slots is an open reset invoice, which is then returned again (an open invoice holds its slot until it is paid or expires; independently, requests in the last ~90 seconds of a UTC month also get 429). There is no usage threshold: the API accepts a reset at any usage, so apply your own policy before paying automatically.

📡 Endpoint Specification#

POST /api/public/v1/subscription/bandwidth-reset#

Authentication: None (Anonymous / Public API)
Rate Limit: 10 requests / minute per IP

Request Headers#

Request Payload#

{
  "wgPublicKey": "pWyZTQx8C4gzzgMVJHiN1ptI46wDtyJSMRa+wxtkXOM=",
  "serverId": "us-east"
}
FieldTypeRequiredDescription
wgPublicKeystringYes44-character Base64 WireGuard public key of your node.
serverIdstringYesServer identifier, group domain (eu-de, us-east), or domain (us3.tunnelsats.com).

Response (200 OK)#

{
  "invoice": "lnbc30000n1p...",
  "paymentHash": "a1b2c3d4e5f6...",
  "resetId": "d7b2277f-5990-4721-a565-6816babadc59",
  "amountSats": 3000,
  "amountUsd": "1.00",
  "expiresAt": "2026-09-27T11:00:00.000Z",
  "currentUsagePercent": "85.4",
  "resetsThisMonth": 0,
  "maxResetsPerMonth": 2
}
FieldTypeDescription
invoicestringBOLT11 Lightning invoice for $1 USD equivalent in sats.
paymentHashstringSHA256 payment hash for tracking invoice settlement.
resetIdstringUnique UUID tracking this bandwidth reset request.
amountSatsnumberInvoice amount in satoshis calculated dynamically from real-time BTC price.
amountUsdstringFixed price ("1.00").
expiresAtstringISO 8601 invoice expiry. Until then the invoice stays payable and its monthly slot stays reserved; requesting a reset again before then returns this same invoice.
currentUsagePercentstringCurrent bandwidth consumption percentage on the VPN manager, for information only.
resetsThisMonthnumberNumber of confirmed resets applied to this key in the current calendar month.
maxResetsPerMonthnumberMaximum allowed resets per month (2).

🛑 Business Rules & Validation#

RuleConstraintError CodeHTTP Status
UsageNone: a reset is available at any usagen/an/a
Open InvoiceWhile an unpaid reset invoice for the key is open, a new request returns it (same paymentHash and resetId, no extra slot)n/a200
Active SubscriptionSubscription must not be expiredERR_INVALID_INPUT400
Monthly LimitMaximum 2 resets per UTC calendar month per key; an open, unpaid invoice holds a slot until it is paid or expiresERR_RATE_LIMIT_EXCEEDED429
Server & KeyKey must exist on target serverERR_RESOURCE_NOT_FOUND404
Public Key FormatMust be a valid 44-character Base64 stringERR_INVALID_INPUT400
Legacy ServerNo resets on the legacy server us1; migrate to us3 firstERR_MIGRATION_REQUIRED403
Restorable KeyA key disabled for a reason other than its bandwidth limit (for example after a migration) can't be reset: a reset would not restore itERR_FORBIDDEN403

⚡ Settlement & Auto-Reenablement#

Once the Lightning invoice is settled:
1.
LNBits Webhook fires automatically to /api/webhooks/bandwidth-reset.
2.
The backend contacts the respective WireGuard server manager and resets the bandwidth counter (bwReset: true).
3.
If the peer key was disabled due to bandwidth exhaustion, it is automatically re-enabled immediately. A key disabled for any other reason is never re-enabled by a reset.

Polling settlement: GET /api/public/v1/subscription/{paymentHash}#

Poll with the reset's paymentHash to learn the outcome. If the webhook was missed, the poll applies the paid reset itself, so a paid reset cannot stay unapplied.
{
  "paymentHash": "a1b2c3d4e5f6...",
  "type": "bandwidth_reset",
  "status": "paid",
  "resetId": "d7b2277f-5990-4721-a565-6816babadc59",
  "expiresAt": "2026-09-27T11:00:00.000Z",
  "message": "Bandwidth reset applied."
}
statusHTTPMeaning
unpaid200Waiting for payment.
processing202Paid; the reset is being applied. Poll again.
paid200The reset was applied.
failed200Paid, but the reset could not be applied. Contact support with the payment hash.
expired200The invoice expired unpaid.
—503Payment state could not be verified right now. Retry later; never treat as unpaid.
Always check type == "bandwidth_reset": it distinguishes the reset from subscription orders and renewals polled on the same endpoint.

💻 Code Examples#

Apply your own reset policy
Always apply your own usage policy before paying. Don't rely on the API to reject resets you don't need. Every paid reset uses one of your monthly resets, so an automated client should check usage and remaining resets first and cap the amount it pays, as the Bash example does.
Bash (cURL + jq + lncli)
Python (Requests)
Prerequisites
Requires curl, jq, and an active Lightning CLI (e.g. lncli, cln, alby-cli, or WebLN).
Modified at 2026-10-10 22:09:33
Previous
🚑 Node Health & Upkeep
Next
🛡️ Security & Authentication
Built with