# Check Invoice Status & Polling by Payment Hash

## OpenAPI Specification

```yaml
openapi: 3.0.1
info:
  title: ''
  description: ''
  version: 1.0.0
paths:
  /api/public/v1/subscription/{paymentHash}:
    get:
      summary: Check Invoice Status & Polling by Payment Hash
      deprecated: false
      description: >-
        Poll this endpoint after payment to check invoice settlement status.
        Returns subscription details once paid. Also accepts bandwidth-reset
        payment hashes: those return a BandwidthResetPaymentStatus (type
        "bandwidth_reset"), and a paid reset whose webhook was missed is applied
        on the poll. Rate limit: 60 requests/min per IP.
      tags:
        - ⚡ Purchase
        - ⚡ Purchase
      parameters:
        - name: paymentHash
          in: path
          description: Payment hash of the invoice (64-character hex string).
          required: true
          example: ''
          schema:
            type: string
        - name: Accept
          in: header
          description: Expected response media type.
          required: false
          example: ''
          schema:
            type: string
            default: application/json
            examples:
              - application/json
      responses:
        '200':
          description: Subscription/Invoice status
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/SubscriptionStatus'
                  - $ref: '#/components/schemas/BandwidthResetPaymentStatus'
              examples:
                subscription:
                  summary: Subscription order
                  value:
                    status: paid
                    subscriptionEnd: '2026-10-15T12:00:00Z'
                    bandwidthUsed: 0
                    server:
                      id: eu-de
                      domain: de2.tunnelsats.com
                      endpoint: de2.tunnelsats.com:51820
                bandwidthReset:
                  summary: Bandwidth reset applied
                  value:
                    paymentHash: >-
                      c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
                    type: bandwidth_reset
                    status: paid
                    resetId: d7b2277f-5990-4721-a565-6816babadc59
                    expiresAt: '2026-09-27T11:00:00.000Z'
                    message: Bandwidth reset applied.
          headers: {}
          x-apidog-name: ''
        '202':
          description: >-
            Paid; the subscription is being provisioned, the renewal or the
            bandwidth reset is being applied. Poll again.
          content:
            application/json:
              schema:
                type: object
                properties:
                  paymentHash:
                    type: string
                  status:
                    type: string
                    enum:
                      - processing
                  message:
                    type: string
                x-apidog-orders:
                  - paymentHash
                  - status
                  - message
                x-apidog-ignore-properties: []
          headers: {}
          x-apidog-name: ''
        '404':
          description: Subscription not found
          content:
            application/json:
              schema: &ref_0
                $ref: '#/components/schemas/ApiError'
          headers: {}
          x-apidog-name: ''
        '503':
          description: >-
            Payment state could not be verified right now (e.g. the Lightning
            backend is unreachable). Retry later; never treat as unpaid.
          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-4204017-run
components:
  schemas:
    BandwidthResetPaymentStatus:
      type: object
      required:
        - paymentHash
        - type
        - status
        - resetId
        - expiresAt
        - message
      properties:
        paymentHash:
          type: string
          examples:
            - c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
        type:
          type: string
          enum:
            - bandwidth_reset
          description: >-
            Distinguishes a bandwidth-reset payment from a subscription order or
            renewal.
        status:
          type: string
          enum:
            - unpaid
            - processing
            - paid
            - failed
            - expired
          description: >-
            unpaid: waiting for payment. processing (HTTP 202): paid, reset
            being applied; poll again. paid: the reset was applied. failed:
            paid, but the reset could not be applied; contact support with the
            payment hash. expired: the invoice expired unpaid.
        resetId:
          type: string
          format: uuid
          examples:
            - d7b2277f-5990-4721-a565-6816babadc59
        expiresAt:
          type: string
          format: date-time
          examples:
            - '2026-09-27T11:00:00.000Z'
          nullable: true
        message:
          type: string
          examples:
            - Bandwidth reset applied.
      x-apidog-orders:
        - paymentHash
        - type
        - status
        - resetId
        - expiresAt
        - message
      x-apidog-ignore-properties: []
      x-apidog-folder: ''
    SubscriptionStatus:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - pending
            - paid
            - expired
            - active
          examples:
            - paid
        subscriptionEnd:
          type: string
          format: date-time
          examples:
            - '2026-10-15T12:00:00Z'
          nullable: true
        bandwidthUsed:
          type: number
          description: Bandwidth used in bytes.
          examples:
            - 45000000000
          nullable: true
        server:
          type: object
          properties:
            id:
              type: string
              examples:
                - us-east
            domain:
              type: string
              examples:
                - us3.tunnelsats.com
            endpoint:
              type: string
              examples:
                - us3.tunnelsats.com:51820
          x-apidog-orders:
            - id
            - domain
            - endpoint
          x-apidog-ignore-properties: []
          nullable: true
      x-apidog-orders:
        - status
        - subscriptionEnd
        - bandwidthUsed
        - server
      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: []

```