License Key for Subscription: Website Credits Use Case

You’ve built an AI copywriter, an image generator, an SEO analyser, or a conversion rate tool. Subscribers pay monthly and receive a credit allowance: 100 AI generations or 50 site audits per month. When they run out of credits, they can’t generate more until the next billing cycle. When they cancel, their credit access ends entirely.

The license key for subscription model handles the access layer cleanly. Vandly generates a unique key when someone subscribes and emails it to them. Your website validates the key on each session or each credit-consuming action. When the subscription lapses, Vandly revokes the key. The next validation returns invalid and access is blocked without any action from you.

This article covers the full integration: how to set it up in Vandly, how to validate the key in a web app, how to combine key validation with your credit system, and what to do after setup to make it production-ready.

The Use Case: Website Credits

A website credit system typically works like this: subscribers pay for a plan that includes a monthly credit allowance. Each action they take (generating content, running a scan, exporting a file) consumes one or more credits. When the allowance is exhausted, they’re blocked until it resets or they upgrade.

The license key for subscription model handles the subscription gate, confirming the user has an active plan. Your own database handles the credit balance. Together, they give you a complete access control system with minimal infrastructure:

LayerHandled By
Subscription access gateVandly license key validation, one API call confirms the key is active
Credit balanceYour database, you store and decrement credits per action
Credit resetTriggered by currentPeriodEnd from the key validation response
Access revocationVandly revokes the key automatically on cancellation or payment failure

You don’t need webhooks to make this work. The currentPeriodEnd field in a valid key response tells you when the current billing period ends, use it to reset credits on the client or server side without needing to receive a renewal event. If you want real-time renewal handling, you can add a webhook alongside the key validation, but it’s not required.

How to Set Up a License Key Subscription Product on Vandly

Setting up a license key for subscription product in Vandly takes 5 steps in the product wizard.

Step 1: Product Type

From the Products page, click + New Product. On the Create New Product screen:

  • Under ‘How will customers pay?’, select Subscription
  • Under ‘How do you want to manage subscriber access?’, select License key. Vandly generates a unique license key for each purchase, no extra setup needed

No URL or server configuration required for the access method. Vandly handles key generation and email delivery automatically.

Step 2: Details and Pricing

  • Product Name: e.g. ‘ContentAI Pro’ or ‘SiteAudit Monthly’
  • Description: describe the credit allowance per plan: how many credits, what each credit does, what happens when credits run out
  • Category: select the category that best fits your tool
  • Billing model: Recurring (monthly and/or yearly) or Lifetime
  • If Recurring: check Monthly, Yearly, or both and set prices for each
  • If Lifetime: set the price for customers pay once and keep access forever
  • Delivery Method — Email Delivery (the license key is sent in the purchase confirmation email)

Step 3: Policy

Vandly auto-configures three subscription policies:

  • Refund Policy: No Partial Refunds — subscribers can cancel anytime; access continues until the end of the current billing period
  • Access Duration: Active Subscription — access ends automatically if a renewal fails or the subscription is canceled
  • Delivery Failure Policy: A new license key is issued automatically on every successful renewal. If a key fails to arrive, Vandly’s support team will resend it or issue a replacement

No action needed. Click Next.

Step 4: Additional Information

  • Previous Platform URL: if you’ve sold this tool elsewhere
  • Demo Link: link to a live demo of your tool
  • Embedded URL: iframe-friendly preview URL if available
  • Expected Monthly Sales: helps Vandly optimise your product page

Step 5: Review and Confirm

  • Confirm product name, price, and billing model are correct
  • Delivery Information: Delivery Method: Email, Access Duration: Subscription
  • Pricing & Policy: Fulfillment shows Subscription · License key
  • Tick all three confirmations: No illegal or harmful content, Accurate information, I own the rights
  • Click Save Changes to submit for review

After approval, go to Product Details > Overview & Settings. Configure your Payment Link to generate the checkout URL to share with subscribers. The Subscriptions tab shows all active subscribers and a Show License Keys button to view and look up individual keys for support.

How Validation Works in a Web App

Unlike plugins or desktop apps, a web app has a backend. That backend is the right place to validate the license key for subscription. Keep validation server-side so the key and the API response never touch the browser.

Where the key lives

When a subscriber activates their account, ask them to enter their license key. Store it in your database against their user record, not in localStorage or a cookie. Every subsequent request that consumes a credit validates the key server-side before proceeding.

The validation request

// Server-side — Node.js / Express example

async function validateLicenseKey(key) {

  const res = await fetch(“https://api.vandly.co/license-keys/validate”, {

    method: “POST”,

    headers: { “Content-Type”: “application/json” },

    body: JSON.stringify({ key }),

  });

  return await res.json();

}

app.post(“/api/generate”, requireAuth, async (req, res) => {

  const user = await db.users.findById(req.user.id);

  // 1. Validate subscription

  const license = await validateLicenseKey(user.vandlyKey);

  if (!license.valid || license.productId !== YOUR_PRODUCT_ID) {

    return res.status(403).json({ error: “subscription_required” });

  }

  // 2. Check credit balance

  if (user.creditsRemaining <= 0) {

    return res.status(403).json({ error: “no_credits” });

  }

  // 3. Decrement credits and perform action

  await db.users.decrement(user.id, “creditsRemaining”, 1);

  const result = await runAction(req.body);

  return res.json({ result });

});

Always check productId, not just valid. The endpoint returns valid: true for any active Vandly key. Without the productId check, a subscriber from a different Vandly product could access your tool.

Resetting Credits on Renewal

Credits need to reset at the start of each new billing period using currentPeriodEnd.

The currentPeriodEnd field in a valid key response tells you when the current period ends. Store it alongside the user’s credit balance. On each validation, compare the stored period end to the one in the response, if it’s changed, a renewal has occurred and you should reset credits.

const license = await validateLicenseKey(user.vandlyKey);

if (license.valid) {

  const newPeriodEnd = license.currentPeriodEnd;

  // If the period has rolled over, reset credits

  if (newPeriodEnd !== user.currentPeriodEnd) {

    await db.users.update(user.id, {

      creditsRemaining: MONTHLY_CREDIT_ALLOWANCE,

      currentPeriodEnd: newPeriodEnd,

    });

  }

}

Validation Response Fields

FieldWhat It Tells You
validtrue if the key is active right now. Gate all credit-consuming actions on this.
statusactive, revoked (canceled or lapsed), or expired. Only present when valid is true.
productIdThe Vandly product this key belongs to. Always verify it matches your product ID.
productNameThe name of the product on Vandly.
currentPeriodEndWhen the current billing period ends in UTC. Use to detect renewals and reset credits.

Error Messages by Failure Case

Return clear, actionable errors from your API so the frontend can show the right message:

What HappenedWhat to Show the User
valid: false, status: revoked“Your subscription has ended. Renew at [your site] to restore access and credits.”
valid: true, wrong productId“Your license key is not valid for this product.”
valid: false (no status)“License key not recognised. Check your purchase confirmation email.”
creditsRemaining: 0“You’ve used all your credits for this period. They reset on [currentPeriodEnd date].”
Network error on validation“Could not verify your subscription. Please try again in a moment.”

What to Do After Setup

1. Decide where and how often to validate

For a credit-based tool, the right validation points are:

  • On sign-in: confirm the user has an active subscription before showing the app
  • Before each credit-consuming action: prevent a revoked key from consuming credits
  • On the credits display: show live subscription status alongside remaining credits

Validating before every action adds a small latency overhead per request. If that’s a concern, validate on sign-in and cache the result for the session, then check credits only per action, and re-validate the subscription at session start the next time the user logs in.

2. Show credits and renewal date in the UI

Use the currentPeriodEnd from a valid response to show subscribers when their credits reset. This reduces support requests and churn:

const periodEnd = new Date(license.currentPeriodEnd);

const formatted = periodEnd.toLocaleDateString(“en-US”, {

  month: “long”, day: “numeric”

});

// e.g. “You have 43 credits remaining. They reset on August 25.”

showCreditsDisplay(user.creditsRemaining, formatted);

3. Test all scenarios before launch

Test ScenarioWhat to Verify
Valid key, correct productId, credits availableAction runs, credit is decremented
Valid key, correct productId, zero creditsAction blocked, reset date shown
Valid key, wrong productIdAction blocked with subscription error
Revoked keyAction blocked, renewal message shown
currentPeriodEnd changed (renewal detected)Credits reset to monthly allowance
End-to-end: subscribe, receive key, activate, use creditsFull flow works in production

4. Use the Subscriptions tab for support

When a subscriber says their credits didn’t reset or their key isn’t working, go to Product Details > Subscriptions tab > Show License Keys. Look up their key status, active or revoked, without writing any code. If the key is active but your app shows an error, check your productId logic and your credit reset detection.

5. Handle the activation flow clearly

When a new subscriber arrives on your site, they need to know where to find their key and how to enter it. The key is in the purchase confirmation email from Vandly. Your activation screen should:

  • Include a text input labelled ‘License key from your purchase email’
  • Show a ‘Check your Vandly purchase confirmation email’ prompt
  • On successful validation, store the key server-side and redirect to the app
  • On failure, show the specific error (revoked vs invalid vs wrong product) so the user knows what to do next

Frequently Asked Questions

Do credits carry over to the next billing period?

That’s your policy to define. Vandly doesn’t manage credit balances. If you want credits to expire at period end, reset them when currentPeriodEnd changes. If you want them to roll over, accumulate instead of resetting.

What happens to a user’s credits when their subscription is canceled?

Vandly revokes the key automatically. Your next validation returns valid: false. At that point, block any further credit-consuming actions. Whether you retain the remaining credit balance in your database is your decision, most tools clear it on cancellation.

Can a user share their license key with others?

The validation endpoint doesn’t track who is using the key or from where. If you need to limit a key to one user, enforce that on your side. For example, by storing the key against a specific user account and rejecting validation requests from any other account using the same key.

Do I need webhooks as well as license key validation?

Not necessarily. For most credit-based tools, detecting renewal via currentPeriodEnd change is sufficient. Add a webhook only if you need credits to reset at the exact moment of renewal, rather than at the user’s next sign-in.

How do I handle a subscriber who upgrades to a higher plan mid-month?

Vandly would generate a new subscription with a new key for the higher plan. Handle it as a new subscription.created event if you’re using webhooks, or detect the productId change during validation and update their credit allowance accordingly.

Where do I find my productId?

It appears in your product’s URL on Vandly and in the productId field of a valid validation response. Hard-code it on your server, it doesn’t change.


Start selling credit-based subscriptions on Vandly → Your first sale is free.

Need real-time renewal handling with server-side events? See Webhook for SaaS Subscription: SaaS Use Case Guide.