Skip to content

Data Models

Reference for data structures returned by the API.

PaginatedResponse

All list endpoints return a paginated wrapper:

typescript
interface PaginatedResponse<T> {
  items: T[]       // Page of results
  total: number    // Total items matching the query
  limit: number    // Maximum items per page
  offset: number   // Number of items skipped
}

Example:

json
{
  "items": [ ... ],
  "total": 142,
  "limit": 50,
  "offset": 0
}

SubscribeRequest

Request body for POST /public/subscribe:

typescript
interface SubscribeRequest {
  plan_id: string                    // Plan to subscribe to
  payment_method: PaymentMethod      // Desired payment method
  email?: string                     // Subscriber email
  name?: string                      // Subscriber display name
  telegram?: string                  // Telegram username
  nostr?: string                     // Nostr npub or NIP-05
  receive_confirmations?: boolean    // Opt in to confirmations (default: true)
  receive_reminders?: boolean        // Opt in to reminders (default: true)
}

Plan

typescript
interface Plan {
  id: string
  wallet: string
  name: string
  description?: string
  amount_sats: number
  interval: 'weekly' | 'monthly' | 'yearly'
  trial_days: number
  grace_period_days: number
  // Payment method flags
  allow_lightning: boolean
  allow_onchain: boolean
  allow_nwc: boolean         // NWC automatic payments
  allow_stripe: boolean      // Cards, Apple Pay, Google Pay
  allow_paypal: boolean      // PayPal payments
  // Optional configuration
  watchonly_wallet_id?: string
  stripe_account_id?: string
  paypal_merchant_id?: string
  created_at: number
  updated_at: number
  is_deleted: boolean
}

Subscription

typescript
interface Subscription {
  id: string
  plan_id: string
  subscriber_id: string
  status: SubscriptionStatus
  current_period_start: number
  current_period_end: number
  trial_end?: number
  cancelled_at?: number
  created_at: number
  updated_at: number
}

type SubscriptionStatus =
  | 'pending'
  | 'active'
  | 'paused'
  | 'past_due'
  | 'payment_failed'
  | 'cancelled'
  | 'expired'

Subscriber

typescript
interface Subscriber {
  id: string
  email?: string
  telegram?: string
  nostr?: string
  name?: string
  access_token: string
  created_at: number
}

Payment

typescript
interface Payment {
  id: string
  subscription_id: string
  amount_sats: number
  amount_fiat?: number        // For Stripe/PayPal payments
  currency?: string           // 'usd', 'eur', etc.
  status: PaymentStatus
  payment_method: PaymentMethod
  // Bitcoin-specific
  payment_request?: string    // Lightning invoice
  payment_hash?: string       // Lightning payment hash
  onchain_address?: string    // On-chain address
  onchain_txid?: string       // On-chain transaction ID
  // Fiat-specific
  stripe_payment_id?: string  // Stripe payment intent ID
  paypal_order_id?: string    // PayPal order ID
  created_at: number
  paid_at?: number
}

type PaymentMethod =
  | 'lightning'    // Lightning Network
  | 'onchain'      // On-chain Bitcoin
  | 'nwc'          // NWC automatic payment
  | 'stripe'       // Stripe (cards, Apple Pay, Google Pay)
  | 'paypal'       // PayPal

type PaymentStatus = 'pending' | 'paid' | 'failed' | 'expired'

NWC Models

Models for Nostr Wallet Connect integration.

NWC Validate Request

typescript
interface NWCValidateRequest {
  nwc_string: string  // The full NWC connection string
}

NWC Validate Response

typescript
interface NWCValidateResponse {
  valid: boolean
  error?: string  // Human-readable error if invalid
}

NWC Subscription Create

typescript
interface NWCSubscriptionCreate {
  plan_id: string
  email?: string
  name?: string
  nwc_connection_string: string
  contact_preference?: 'email' | 'telegram' | 'nostr'
}

NWC Subscription Response

typescript
interface NWCSubscriptionResponse {
  subscription_id: string
  status: 'active' | 'pending'
  message: string
  error_code?: string  // Only if payment failed
}

NWC Connection

Internal model for stored NWC connections:

typescript
interface NWCConnection {
  id: string
  subscriber_id: string
  wallet_pubkey: string      // First 8 chars shown to user
  relay_url: string
  max_amount_sats?: number
  is_active: boolean
  last_used_at?: number
  last_error?: string
  consecutive_failures: number
  created_at: number
  updated_at?: number
}

Webhook Event

typescript
interface WebhookEvent {
  event: string
  timestamp: number
  data: {
    subscription_id: string
    plan_id: string
    plan_name: string
    subscriber_email?: string
    subscriber_name?: string
    status: string
    amount_sats?: number
    [key: string]: any
  }
}

API Response Models

Common response structures returned by specific endpoints.

CheckoutResponse

Returned by POST /public/subscribe for paid plans:

typescript
interface CheckoutResponse {
  payment_id: string            // Use this to poll payment status
  payment_method: PaymentMethod
  // Lightning
  payment_request?: string      // BOLT11 invoice
  payment_hash?: string         // Lightning payment hash
  // On-chain
  onchain_address?: string      // Bitcoin address
  satspay_charge_id?: string    // SatsPay charge ID
  bip21_uri?: string            // BIP21 unified payment URI
  // Fiat (Stripe/PayPal)
  checkout_url?: string         // Redirect URL for fiat checkout
  // QR codes (pre-generated SVG strings)
  qr_codes?: Record<string, string>  // Keyed by mode: 'lightning', 'onchain', 'bip21'
  // Expiry
  expires_at: number            // Unix timestamp
}

TrialSubscriptionResponse

Returned by POST /public/subscribe for plans with free trials:

typescript
interface TrialSubscriptionResponse {
  subscription_id: string   // New subscription ID
  status: 'active'          // Trials are immediately active
  trial: true               // Always true for trial responses
  trial_days: number        // Length of the trial period
  message: string           // e.g. "Your 7-day free trial has started!"
}

PaymentStatusResponse

Returned by GET /public/payment/{id}/status:

typescript
interface PaymentStatusResponse {
  payment_id: string
  status: string        // 'pending', 'paid', 'expired'
  paid_at?: number      // Unix timestamp when paid
  subscription_id: string
}

ManageLinkResponse

Returned by GET /subscriptions/{id}/manage-link:

typescript
interface ManageLinkResponse {
  subscription_id: string
  subscriber_email: string
  manage_url: string
}

SuccessMessageResponse

Returned by cancel, disconnect, and similar operations:

typescript
interface SuccessMessageResponse {
  success: boolean
  message: string
}

Timestamps

All timestamps are Unix timestamps (seconds since epoch).

javascript
// Convert to Date
const date = new Date(timestamp * 1000)

// Current timestamp
const now = Math.floor(Date.now() / 1000)