Back to roadmaps lemonsqueezy Course

License Key Activation and Verification

If you sell desktop software, IDE plugins, or downloadable tools, Lemon Squeezy provides a built-in licensing system. Let us look at how to activate and verify these keys.


1. Key Verification Lifecycle Flow

graph TD
    A[User inputs License Key in App] --> B[App calls /activate endpoint]
    B --> C[Lemon Squeezy saves hardware instance ID]
    C --> D[Subsequent launches call /validate endpoint]

2. Part 1: Activating a License Key

When a user enters a license key for the first time, associate their hardware or app instance:

// src/services/licensing.ts
interface LicenseResponse {
  activated: boolean;
  instanceId?: string;
  error?: string;
}

export async function activateLicense(licenseKey: string, instanceName: string): Promise<LicenseResponse> {
  try {
    const response = await fetch("https://api.lemonsqueezy.com/v1/licenses/activate", {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept": "application/json",
      },
      body: new URLSearchParams({
        license_key: licenseKey,
        instance_name: instanceName, // e.g. "Alex's MacBook Pro"
      }),
    });

    const data = await response.json();

    if (data.error) {
      return { activated: false, error: data.error };
    }

    return {
      activated: data.activated,
      instanceId: data.instance?.id,
    };
  } catch (err: any) {
    return { activated: false, error: err.message };
  }
}

3. Part 2: Validating an Active License

On subsequent app launches, verify that the license key is still valid and has not expired or been refunded:

export async function validateLicense(licenseKey: string, instanceId: string) {
  const response = await fetch("https://api.lemonsqueezy.com/v1/licenses/validate", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      "Accept": "application/json",
    },
    body: new URLSearchParams({
      license_key: licenseKey,
      instance_id: instanceId, // Verifies specifically this device
    }),
  });

  const data = await response.json();
  
  // Returns true if license is active and not revoked
  return data.valid && data.license_key.status === "active";
}
Published on Last updated: