# Create a New WireGuard Subscription (Invoice Generation)

## OpenAPI Specification

```yaml
openapi: 3.0.1
info:
  title: ''
  description: ''
  version: 1.0.0
paths:
  /api/public/v1/subscription/create:
    post:
      summary: Create a New WireGuard Subscription (Invoice Generation)
      deprecated: false
      description: >-
        Generates a Lightning invoice to purchase a 1, 3, 6, or 12-month
        WireGuard VPN tunnel in a chosen region. Rate limit: 10 requests/min per
        IP.
      tags:
        - ⚡ Purchase
        - ⚡ Purchase
      parameters:
        - name: Content-Type
          in: header
          description: Media type of the request payload. Must be application/json.
          required: true
          example: ''
          schema:
            type: string
            default: application/json
            examples:
              - application/json
        - name: Accept
          in: header
          description: Expected response media type.
          required: false
          example: ''
          schema:
            type: string
            default: application/json
            examples:
              - application/json
        - name: Authorization
          in: header
          description: >-
            Optional. Links purchase to your account for dashboard tracking.
            Bearer sk_live_... or Nostr <base64-event>.
          required: false
          example: ''
          schema:
            type: string
            examples:
              - Bearer sk_live_a1b2c3d4e5f6g7h8i9j0
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - serverId
                - duration
              properties:
                serverId:
                  type: string
                  description: Target server identifier (e.g. eu-de, us-east).
                  examples:
                    - eu-de
                duration:
                  type: integer
                  enum:
                    - 1
                    - 3
                    - 6
                    - 12
                  description: Subscription duration in months.
                  examples:
                    - 1
                referralCode:
                  type: string
                  description: >-
                    Optional partner referral code (e.g. REF-ABC123). Must be an
                    existing code: unknown codes, and your own code when you are
                    authenticated, are rejected with 400 before an invoice is
                    created (anonymous requests carry no account identity to
                    check for self-referral). When a 3, 6 or 12-month order with
                    a valid non-self-referral code is paid, both the new
                    subscription and the code owner receive +1, +2 or +3 bonus
                    months (the code owner is credited exactly once), whichever
                    path settles the order (payment webhook, status polling or
                    /claim).
                  examples:
                    - null
                  nullable: true
                wgPublicKey:
                  type: string
                  description: >-
                    Optional but recommended. Omit the field rather than sending
                    null. Your WireGuard public key (44-char Base64). When set,
                    every provisioning path (payment webhook, status polling,
                    /claim) uses this key only: the server never generates or
                    stores a private key for the order, and /claim must be
                    called with the same key.
                  examples:
                    - hnG/fWsNx7DiVbGUj3B/i0EtXvpIZdO5cuoQJCTWhRU=
              x-apidog-orders:
                - serverId
                - duration
                - referralCode
                - wgPublicKey
              x-apidog-ignore-properties: []
      responses:
        '200':
          description: Lightning invoice generated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceOrder'
              example:
                invoice: lnbc41130n1p5a4p2dpp5pwd0d2ua837kz...
                paymentHash: >-
                  0b9af6ab9d3c7d6146e3f28ca11bf4b830f4cab95330c5a5c9b25b7827afc44c
                amountSats: 4113
                orderId: ab897fc4-41ff-4a55-9bb6-0ce1623e7a87
          headers: {}
          x-apidog-name: ''
        '400':
          description: >-
            Invalid input (bad serverId or duration, unknown referralCode or
            self-referral, or invalid wgPublicKey)
          content:
            application/json:
              schema: &ref_0
                $ref: '#/components/schemas/ApiError'
          headers: {}
          x-apidog-name: ''
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema: *ref_0
          headers: {}
          x-apidog-name: ''
      security: []
      x-apidog-folder: ⚡ Purchase
      x-apidog-status: released
      x-run-in-apidog: https://app.eu.apidog.com/web/project/361232/apis/api-4063129-run
components:
  schemas:
    InvoiceOrder:
      type: object
      required:
        - invoice
        - paymentHash
        - amountSats
        - orderId
      properties:
        invoice:
          type: string
          description: BOLT11 Lightning Invoice string to be paid.
          examples:
            - lnbc41130n1p5a4p2dpp5pwd0d2ua837kz...
        paymentHash:
          type: string
          description: SHA256 Payment hash of the invoice.
          examples:
            - 0b9af6ab9d3c7d6146e3f28ca11bf4b830f4cab95330c5a5c9b25b7827afc44c
        amountSats:
          type: integer
          description: >-
            Price in satoshis (dynamically calculated from real-time BTC/USD
            rate).
          examples:
            - 4113
        orderId:
          type: string
          format: uuid
          description: Unique order identifier for tracking.
          examples:
            - ab897fc4-41ff-4a55-9bb6-0ce1623e7a87
      x-apidog-orders:
        - invoice
        - paymentHash
        - amountSats
        - orderId
      x-apidog-ignore-properties: []
      x-apidog-folder: ''
    ApiError:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Standard machine-readable error code.
          examples:
            - ERR_RATE_LIMIT_EXCEEDED
        message:
          type: string
          description: Human-readable error explanation.
          examples:
            - Rate limit exceeded. Please wait before retrying.
        details:
          type: object
          description: Optional validation error details or parameters.
          x-apidog-orders: []
          properties: {}
          x-apidog-ignore-properties: []
          nullable: true
      x-apidog-orders:
        - error
        - message
        - details
      x-apidog-ignore-properties: []
      x-apidog-folder: ''
  securitySchemes:
    ApiKeyAuth:
      type: bearer
      scheme: bearer
      description: Authenticate using your TunnelSats API Key (sk_live_...).
    NostrAuth:
      type: bearer
      scheme: bearer
      description: >-
        NIP-98 Nostr Authentication. The token is the base64-encoded NIP-98
        event JSON.
servers:
  - url: https://tunnelsats.com
    description: Prod Env
security: []

```