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
    • 🤖 Autonomous Agent Payments (L402 & x402) & Level 5 Agent-Native Architecture
  • 📡 Discovery
    • List Available WireGuard Servers & Regions
      GET
    • L402 Agent Payment Gateway Discovery Metadata
      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
    • Autonomous Agent HTTP 402 Gateway (L402 Purchase + Claim)
      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
    • 🤖 Agent Payments: L402 & x402 Protocol
  • Schemas
    • Server
    • InvoiceOrder
    • SubscriptionStatus
    • NodeLookup
    • ConnectivityResult
    • ApiError
    • ClaimResult
    • BandwidthResetResponse
    • PublicKeyStatusResponse
    • SubscriptionListItem
    • ReferralCode
    • ReferralHistory
    • BandwidthResetPaymentStatus
    • RenewalOrder
    • SyncResult
Tunnelsats Github
Tunnelsats Telegram
  1. Cookbook

🛑 Error Codes & Troubleshooting

TunnelSats uses standardized machine-readable error codes. Since our API involves real-world Lightning transactions, understanding these codes is the difference between a smooth automation and a broken one.

📊 Machine-Readable Error Codes#

All error responses follow the ApiError schema: {"error": "CODE", "message": "Reason"}.
CodeHTTPMeaningMitigation
ERR_INVALID_INPUT400Invalid serverId, duration, malformed pubkey, or expired subscription.Check request payload and verify subscription status.
ERR_UNAUTHORIZED401Missing or invalid Authorization header.Use Bearer <api_key> or Nostr <token>.
ERR_PAYMENT_REQUIRED402Subscription exists but hasn't been paid yet.Poll the status until it returns paid.
ERR_MIGRATION_REQUIRED403Attempting to renew, or to buy a bandwidth reset, on the legacy server (us1).Use the migration tool to move to us3.
ERR_FORBIDDEN403On /bandwidth-reset: the key was disabled for a reason other than its bandwidth limit (for example after a migration), so a reset would not restore it.Don't retry; contact support.
ERR_RESOURCE_NOT_FOUND404No subscription found for that paymentHash, or (on /status, /renew, /bandwidth-reset) every VPN server answered and none holds the key.Verify your hash from the /create call, or the WireGuard public key.
ERR_RATE_LIMIT_EXCEEDED429Rate limit exceeded or maximum monthly bandwidth resets reached (max 2/month).Implement exponential backoff or wait for monthly reset counter to refresh.
ERR_INTERNAL_ERROR500Internal server error.Wait 30 seconds and retry.
ERR_SERVICE_UNAVAILABLE503A VPN server could not be checked, so the key could be neither found nor ruled out (/status, /renew, /bandwidth-reset). Sent with a Retry-After header.Retry after Retry-After seconds. Never treat it as "key unknown".
503503Backend VPN server unavailable or syncing (retryable).Retry with exponential backoff. This is common during bandwidth-reset webhook processing if the VPN manager is temporarily unreachable.

⏱️ Rate Limits by Endpoint (Source Code)#

Two layers protect the API: a Cloudflare WAF burst limiter (10 req/10s per IP across all /api/public/*) and per-endpoint application limits:
EndpointLimitWindowKey
GET /servers60/min60sPer IP
POST /create10/min60sPer IP
POST /claim10/min60sPer IP
GET /{paymentHash}60/min60sPer IP
POST /status30/min60sPer IP
POST /renew20/min60sPer IP
POST /bandwidth-reset10/min60sPer IP
POST /{paymentHash}/sync5/min60sPer subscription
GET /list30/min60sPer account
POST /ping/lookup5/min60sPer IP
POST /ping/test3/min60sPer IP

🔍 Specific Scenarios#

Invoice Expiration
Rate Limiting (429)
Development Envs (dev2)
402 vs. 404
If a user waits too long to pay, the invoice will expire.
Scenario: You poll and keep getting ERR_PAYMENT_REQUIRED.
Expiry: If the invoice expires, the paymentHash may eventually return ERR_RESOURCE_NOT_FOUND.
Action: Generate a new subscription request via /create.
Modified at 2026-10-16 19:18:24
Previous
🎁 Referral Program: Earn Bonus Months
Next
🤖 Agent Payments: L402 & x402 Protocol
Built with