API Documentation

Learn how to integrate your separate SaaS applications with the central Paddle billing platform.

Overview & Authentication

All external SaaS integrations communicate with the billing engine via secure HTTPS requests. To authenticate your client app, generate an API Key inside the **Admin Dashboard** (`/admin`), and send it with every request in the headers:

x-api-key: sb_live_your_saas_product_key_here
Alternatively, you can use the Bearer token scheme:
Authorization: Bearer sb_live_your_saas_product_key_here

E-Commerce & SaaS Checkout Integration Flow

Integrating an external SaaS or e-commerce website with this central billing platform follows a secure, simple two-track process:

1. Initiate Checkout Session
  • Dynamic API Call: Your backend makes a secure request to /api/public/create-checkout with the product price, customer email, and custom tracking IDs.
  • Redirect to Billing: You receive a unique checkoutUrl to which you redirect your customer.
  • Complete Purchase: The user completes the secure credit card or PayPal payment via the Paddle checkout overlay.
2. Return & Verify (Optional)
  • Return to E-Commerce: Once successful, Paddle automatically redirects the customer back to your successUrl.
  • Verify Securely: If you need to verify they actually paid (preventing fake requests to your successUrl), make a secure post request to /api/public/validate-subscription using your API Key.
  • Fulfill Order: If the response confirms hasActiveSubscription: true, approve the order on your database.
3. Payment Failures & Revocation
  • Checkout Failures: Paddle checkout handles failure messaging inside the modal (e.g. card declined). The overlay is not closed until success or manual cancellation.
  • Recurring Failures: If a renewal payment fails, Paddle fires a webhook. The engine marks the subscription as past_due and blocks API access.
  • Grace & Dunning: An automated background email job triggers to notify the customer, containing a secure link to update their payment methods in /portal.
POST/api/public/validate-subscription

Validates if a customer has an active subscription to the calling SaaS product using their email address.

Request Parameters

FieldTypeRequiredDescription
emailstringYesThe customer email to lookup on the billing engine.
Example cURL
curl -X POST http://localhost:3000/api/public/validate-subscription \
  -H "x-api-key: sb_live_analytics_saas_key_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{"email": "customer@example.com"}'
Response JSON
{
  "hasActiveSubscription": true,
  "subscription": {
    "paddleSubscriptionId": "sub_mock_subscription_123",
    "status": "active",
    "currentPeriodStartsAt": "2026-04-26T20:00:00.000Z",
    "currentPeriodEndsAt": "2026-06-26T20:00:00.000Z",
    "cancelAtPeriodEnd": false,
    "plan": {
      "name": "Hobby Plan",
      "slug": "hobby",
      "billingInterval": "monthly",
      "features": {
        "export_pdf": false,
        "api_calls": 1000
      }
    }
  }
}
POST/api/public/verify-license

Validates a customer's alphanumeric license key. Perfect for desktop apps, integrations, or plugins.

Request Parameters

FieldTypeRequiredDescription
licenseKeystringYesThe license key to verify (e.g. LIC-XXXX-XXXX).
Example cURL
curl -X POST http://localhost:3000/api/public/verify-license \
  -H "x-api-key: sb_live_analytics_saas_key_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{"licenseKey": "LIC-ANALYTICS-MOCK-KEY-789"}'
Response JSON
{
  "isValid": true,
  "status": "active",
  "expiresAt": "2026-06-26T20:00:00.000Z",
  "featuresAllowed": {},
  "user": {
    "email": "customer@example.com"
  },
  "subscription": {
    "paddleSubscriptionId": "sub_mock_subscription_123",
    "status": "active",
    "currentPeriodEndsAt": "2026-06-26T20:00:00.000Z"
  }
}
POST/api/public/get-feature-access

Checks if a customer has access to a specific feature and dynamically increments metrics (e.g. API limit counters) on the central engine.

Request Parameters

FieldTypeRequiredDescription
licenseKeystringYesThe customer license key.
featureKeystringNoThe specific limit mapping to inspect (e.g., `api_calls`).
incrementUsagenumberNoSpecify an amount (e.g. `1`) to increment the metered usage inside this billing cycle.
Example cURL
curl -X POST http://localhost:3000/api/public/get-feature-access \
  -H "x-api-key: sb_live_analytics_saas_key_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "licenseKey": "LIC-ANALYTICS-MOCK-KEY-789",
    "featureKey": "api_calls",
    "incrementUsage": 1
  }'
Response JSON
{
  "isAllowed": true,
  "featureValue": 1000,
  "type": "metered",
  "limit": 1000,
  "currentUsage": 1,
  "remaining": 999,
  "resetAt": "2026-06-26T20:00:00.000Z"
}
POST/api/public/create-checkout

Dynamically initiate a checkout session. Your SaaS app dictates the price, currency, and intervals, allowing you to bypass Paddle's catalog completely. A hosted checkout link is returned.

Request Parameters

FieldTypeRequiredDescription
emailstringYesThe customer email.
amountnumberYesPrice amount (e.g. 49.99).
currencystringNoCurrency code (e.g. USD, EUR). Defaults to USD.
titlestringYesProduct title displayed to customer.
intervalstringNoSet to 'month' or 'year' for recurring. Leave blank for one-time.
sourcestringNoThe origin SaaS app domain (e.g., my-saas.com).
referencestringNoYour internal Order ID to track the payment.
successUrlstringYesThe URL to redirect the user back to after purchase.
Example cURL
curl -X POST http://localhost:3000/api/public/create-checkout \
  -H "x-api-key: sb_live_analytics_saas_key_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "customer@example.com",
    "amount": 49.99,
    "currency": "USD",
    "title": "Pro License (1-Time)",
    "description": "Unlimited access for life.",
    "source": "my-cool-saas.com",
    "reference": "order_001",
    "successUrl": "https://my-cool-saas.com/thank-you"
  }'
Response JSON
{
  "success": true,
  "transactionId": "txn_01abc...",
  "checkoutUrl": "http://localhost:3000/checkout/txn_01abc..."
}