1. Announcements
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 for +100GB)
      POST
  • 🔑 Account
    • List Account Subscriptions (Authenticated)
      GET
    • Create Referral Code
      POST
    • Get Referral Code
      GET
    • Referral History
      GET
  • 🔧 Tools
    • Lightning Node Network Address Discovery
      POST
    • Universal Connectivity & Latency Probe
      POST
  • Cookbook
    • 🛠️ Automation & Code Examples
    • 🐚 Bash One-Liners
    • 🚑 Node Health & Upkeep
    • ⚡ Bandwidth Top-Up ($1 for +100GB)
    • 🛡️ Security & Authentication
    • 🎁 Referral Program: Earn Bonus Months
    • 🛑 Error Codes & Troubleshooting
  • Schemas
    • Server
    • InvoiceOrder
    • SubscriptionStatus
    • NodeLookup
    • ConnectivityResult
    • ApiError
    • ClaimResult
    • BandwidthResetResponse
    • PublicKeyStatusResponse
    • ReferralCode
    • ReferralHistory
    • BandwidthResetPaymentStatus
    • RenewalOrder
    • SubscriptionListItem
    • SyncResult
Tunnelsats Github
Tunnelsats Telegram
  1. Announcements

🧩 How the TunnelSats StartOS Package Uses the Public API

The TunnelSats package for StartOS 0.4 is a native storefront and manager for LND, Core Lightning and Eclair. It buys and renews subscriptions over the public API v1, keeps the WireGuard private key on the device, and hands the finished configuration to the Lightning node, which runs the tunnel inside its own container. This page explains the architecture, which endpoints it calls, what data it sends, and how payments stay at-most-once.

Architecture#

ComponentRuns whereRole
TunnelSats packageIts own StartOS containerActions (Buy, Renew, Reset Bandwidth, Import, Export, Configure, Connect Wallet), background sync daemon, web dashboard
Lightning node package (LND, Core Lightning, Eclair)Its own StartOS containerPays invoices through its Pay Invoice action; runs the WireGuard tunnel wg0 and its routing when the clearnet-vpn task is accepted
TunnelSats public API v1https://tunnelsats.com/api/public/v1Servers, orders, payment status, config claim, status sync, inbound ping test
NWC wallet (optional)Your wallet, over Nostr relaysPays renewal invoices automatically when Connect Wallet is set up
Key points:
Client-held keys. The package generates a Curve25519 keypair in-process and sends only wgPublicKey. Orders created with wgPublicKey are provisioned for that key only; the server never generates or stores a private key for them, and /claim returns the tunnel parameters with fullConfig: null. The package assembles the .conf locally and rejects a claim whose peer key differs from its own.
Tunnel in the node container. On the clearnet-vpn task, the node brings up wg0, listens for inbound peers on the tunnel address and announces <server>:<vpnPort>. Policy routing (table 51820) sends clearnet peer traffic through wg0 while it is up; Tor traffic keeps using the container bridge.
Control plane outside the tunnel. The package's own API calls must work while the tunnel is down or expired, so they leave through the StartOS outbound gateway configured for the TunnelSats service (or the system default connection), not through wg0.

Buy → pay → claim → clearnet-vpn handoff#

Renewal, reminders and NWC auto-renew#

Endpoints the package calls#

All calls go to https://tunnelsats.com/api/public/v1. Purchase endpoints need no authentication.
EndpointWhenData sent
GET /serversBuy action opens; dashboard region cards (cached 60 s, retried after 15 s on failure)Nothing node-specific
POST /subscription/create (docs)Buy SubscriptionserverId, duration, wgPublicKey
GET /subscription/{paymentHash} (docs)Settlement polling for Buy / Renew / ResetPayment hash
POST /subscription/claim (docs)After a Buy settlespaymentHash, wgPublicKey (optional referral code)
POST /subscription/renewRenew Subscription, NWC auto-renewserverId, duration, wgPublicKey
POST /subscription/bandwidth-reset (guide)Reset Bandwidth (usage at 70% or more)wgPublicKey, serverId
POST /subscription/statusBackground syncwgPublicKey; receives expiry, bandwidth used, monthly limit, paid reset count
POST /ping/testOnly when the user presses Check inbound reachability (max 2 per 60 s)Node public key, server address and port from the config
Notes:
The node public key for the reachability check is kept only in the browser's local storage, never on the node. The check shows that inbound connections reach the node; it does not verify outbound VPN egress.
With NWC enabled, Nostr relay traffic uses the TunnelSats service's outbound gateway, unless Route Wallet Traffic Through Tor is on (or the relay is a .onion); then it goes through the StartOS Tor SOCKS5 proxy and fails if Tor is unreachable.
Full endpoint reference: api.tunnelsats.com.

Key handling#

Keypair generated in-process on the device; the private key is stored in the package's data volume and never sent to TunnelSats.
The WireGuard configuration and subscription metadata are part of encrypted StartOS backups. The NWC spending credential is excluded from backups; after a restore, a Connect Wallet task asks you to reconnect.
Export WireGuard Configuration shows the stored .conf in a masked, copyable field.

Idempotency and at-most-once payments#

One payment at a time. Buy, Renew and Reset Bandwidth run through one serialized payment queue, so two purchases cannot interleave between recording an order and raising its task.
Invoice reuse. Running Buy again with the same selection while the invoice is still payable shows the same invoice and re-raises the same Pay Invoice task instead of creating a new order. A paid but not yet claimed order is finished by the settlement tick, never re-ordered. Reset Bandwidth likewise shows the pending invoice while it is payable.
One task per payment. Pay Invoice tasks use a replay ID unique to the payment hash; a replaced or settled payment's task is cleared, so the node never keeps offering an invoice the package no longer tracks.
NWC. Renewal checks are serialized with a lock, reuse one renewal invoice per period, and ask the wallet (lookup_invoice) whether it is already settled before paying. After 3 failed attempts (or insufficient budget/balance) automatic retries stop for that period and the user pays through a Pay Invoice task.
Server side. Claims for an already-processed payment return the existing provisioning instead of provisioning twice, and a claim with a different key is rejected with HTTP 409.

Notifications and tasks#

TriggerWhat the user sees
Expiry in 7 days or lessStartOS notification; Renew Subscription task (important) only if NWC auto-renew is not active
Expiry in 3 days or lessNotification; task raised or updated only if NWC auto-renew is not active
ExpiredRenew Subscription task + notification (also with NWC connected); the server disables the tunnel until renewed
No subscription for the configured keyImport Subscription task + notification
NWC auto-renew succeededNotification with amount paid and new expiry
NWC fallbackPay Invoice task on the node (+ Connect Wallet task if the budget is short) + notification
Each notification is sent once per subscription period; none are sent while the package is stopped.

Limits and known caveats#

Kill switch belongs to the node package. The tunnel and its routing live in the Lightning node package, and the package requires LND 0.21.3-beta:10, Core Lightning 26.6.8:3 or Eclair 0.14.3:3 (or newer). While the tunnel is configured, those builds keep blackhole default metric 4294967295 in table 51820 for IPv4 and IPv6, so if wg0 goes down, is removed or loses its server, clearnet traffic is dropped instead of using the home connection. QA verified no leak window at boot and none when the endpoint's DNS fails at start (the node daemon waits for the tunnel). Verify on the node: wg show wg0, ip rule (lookup 51820), ip route show table 51820 (default dev wg0 plus the blackhole route), ip -6 route show table 51820 (blackhole route), curl -4 -s https://ifconfig.me (TunnelSats IPv4).
Intentional off: Configure → disable, then accepting the node's off-task removes the tunnel; the node's clearnet traffic then uses the home connection again, by design.
IPv6 routing is decided by the node package: current builds send IPv6 through the tunnel when AllowedIPs include ::/0 (TunnelSats configs do) and block it otherwise. Allow IPv6 Endpoint only lets TunnelSats hand the node an IPv6 server endpoint to announce.
Bandwidth: 100 GB per calendar month; Reset Bandwidth from 70% usage, limited resets per month.
Rate limits: the public API's burst and per-endpoint limits apply (see the API reference).
Server list status is not a live health check; see the TunnelSats status page.
Lapsed subscription: clearnet peer connections through TunnelSats stop until you renew or turn off the clearnet VPN on the node.
Modified at 2026-10-09 18:51:30
Previous
🚀 Introducing the TunnelSats Public API v1
Next
How TunnelSats Leverages Public APIs for Confined VPN Management
Built with