$ guides / tiered-licensing

Tiered Licensing with License Variables

Implement Basic, Pro, and Enterprise plan tiers using license variables for per-user feature gating.

Guide

License variables let you attach per-user metadata to each license key. By setting a plan variable (and feature-specific limits), you can gate functionality in your application based on the customer’s subscription tier.

Architecture

flowchart LR
    A["Stripe Payment"] --> B["Your Server"]
    B --> C["AuthForge API: Create License"]
    B --> D["AuthForge API: Set License Variables"]
    D --> E["SDK reads licenseVariables"]
    E --> F["App enables tier features"]

Step 1: Define your tiers

Decide what each tier includes:

FeatureBasicProEnterprise
Max projects31050
ExportNoYesYes
API accessNoYesYes
Priority supportNoNoYes
SSONoNoYes

This maps to license variables:

// Basic
{ "plan": "basic", "maxProjects": 3 }

// Pro
{ "plan": "pro", "maxProjects": 10, "features": "export,api" }

// Enterprise
{ "plan": "enterprise", "maxProjects": 50, "features": "export,api,priority-support,sso" }

Step 2: Create licenses with tier variables

When a customer subscribes, create a license and set the variables:

const PLAN_PRESETS = {
  basic: { plan: "basic", maxProjects: 3 },
  pro: { plan: "pro", maxProjects: 10, features: "export,api" },
  enterprise: {
    plan: "enterprise",
    maxProjects: 50,
    features: "export,api,priority-support,sso",
  },
};

async function createTieredLicense(appId, plan, label) {
  // Create the license
  const createRes = await fetch("https://api.authforge.cc/v1/licenses", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AUTHFORGE_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      appId,
      quantity: 1,
      maxHwidSlots: plan === "enterprise" ? 5 : 1,
      label,
    }),
  });

  const { licenses } = await createRes.json();
  const licenseKey = licenses[0].licenseKey;

  // Set tier variables
  await fetch(
    `https://api.authforge.cc/v1/licenses/${licenseKey}/variables`,
    {
      method: "PUT",
      headers: {
        Authorization: `Bearer ${process.env.AUTHFORGE_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(PLAN_PRESETS[plan]),
    }
  );

  return licenseKey;
}

Step 3: Read tier variables in the SDK

Python
if client.login(license_key):
    plan = client.license_variables.get("plan", "basic")
    max_projects = int(client.license_variables.get("maxProjects", 3))
    features = client.license_variables.get("features", "").split(",")

    print(f"Plan: {plan} | Max projects: {max_projects}")

    if "export" in features:
        enable_export()

    if "api" in features:
        enable_api_access()

    if "sso" in features:
        enable_sso()
C#
if (client.Login(licenseKey))
{
    var vars = client.LicenseVariables;
    var plan = vars.GetValueOrDefault("plan", "basic")?.ToString() ?? "basic";
    var maxProjects = int.Parse(vars.GetValueOrDefault("maxProjects", "3")?.ToString() ?? "3");
    var features = (vars.GetValueOrDefault("features", "")?.ToString() ?? "").Split(',');

    Console.WriteLine($"Plan: {plan} | Max projects: {maxProjects}");

    if (features.Contains("export")) EnableExport();
    if (features.Contains("api")) EnableApiAccess();
    if (features.Contains("sso")) EnableSso();
}

Step 4: Handle plan upgrades

When a customer upgrades (e.g., Basic → Pro), update their license variables:

async function upgradePlan(licenseKey, newPlan) {
  await fetch(
    `https://api.authforge.cc/v1/licenses/${licenseKey}/variables`,
    {
      method: "PUT",
      headers: {
        Authorization: `Bearer ${process.env.AUTHFORGE_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(PLAN_PRESETS[newPlan]),
    }
  );
}

The user picks up the new plan the next time they authenticate.

Stripe integration

Map Stripe price IDs to plan tiers:

const PRICE_TO_PLAN = {
  price_basic_monthly: "basic",
  price_basic_yearly: "basic",
  price_pro_monthly: "pro",
  price_pro_yearly: "pro",
  price_enterprise_monthly: "enterprise",
  price_enterprise_yearly: "enterprise",
};

async function handleCheckoutCompleted(session) {
  const lineItems = await stripe.checkout.sessions.listLineItems(session.id);
  const priceId = lineItems.data[0].price.id;
  const plan = PRICE_TO_PLAN[priceId] || "basic";

  const licenseKey = await createTieredLicense(
    process.env.AUTHFORGE_APP_ID,
    plan,
    `Stripe ${session.id}`
  );

  await db.saveSubscription({
    customerId: session.customer,
    subscriptionId: session.subscription,
    licenseKey,
    plan,
  });

  await sendLicenseEmail(session.customer_details.email, licenseKey);
}

Displaying tier info in the app

Show users what their plan includes and offer upgrade prompts:

if client.login(license_key):
    plan = client.license_variables.get("plan", "basic")

    if plan == "basic":
        show_upgrade_banner(
            "Upgrade to Pro for export, API access, and 10 projects.",
            url="https://yoursite.com/upgrade"
        )

Next steps

Contact support

Feel free to reach out if you have questions, need help getting set up, or run into something unexpected. We'll get back to you as soon as we can.

Email us at support@authforge.cc