Skip to content

Lemon Squeezy setup

Keylight integrates with Lemon Squeezy through a one-way signed webhook: every order, subscription state change, and refund hits Keylight, and Keylight mints, renews, or refunds the matching license. There is no OAuth and no outbound API call from Keylight — just the signed webhook with a shared HMAC secret.

From your dashboard, go to Settings → Integrations → Lemon Squeezy and click Enable Lemon Squeezy. Keylight reveals the webhook URL:

https://api.keylight.dev/webhooks/lemonsqueezy/<your-tenant-id>

Copy it — you’ll paste it into Lemon Squeezy’s webhook settings in step 3.

2. Map Lemon Squeezy Variant IDs to Keylight apps

Section titled “2. Map Lemon Squeezy Variant IDs to Keylight apps”

In Settings → Integrations → Lemon Squeezy, add one row per variant.

Lemon Squeezy Variant IDKeylight appKey type
123456myapppro-monthly
123457myapppro-annual

Keylight reads data.attributes.first_order_item.variant_id from each order_created event to pick the row. Unmapped variants are rejected with 400 unmapped_variant instead of being minted against an unknown app.

In the Lemon Squeezy dashboard:

  1. Go to Settings → Webhooks.
  2. Click + Create new webhook.
  3. Paste the Keylight URL from step 1 into Callback URL.
  4. Set a Signing secret of your choice (any random string — copy it).
  5. Check these event types:
    • order_created
    • order_refunded
    • subscription_payment_success
    • subscription_payment_failed
    • subscription_payment_recovered
    • subscription_updated
    • subscription_resumed
    • subscription_paused
    • subscription_cancelled
    • subscription_expired
  6. Save.

Back in Keylight (Settings → Integrations → Lemon Squeezy), paste the signing secret into Webhook signing secret and save. Keylight uses it to verify the X-Signature HMAC-SHA256 header on every delivery.

Lemon Squeezy’s webhook editor has a Send test dropdown — pick order_created.

  • 200 OK from Keylight with a new license record in Dashboard → Licenses means signature, variant map, and routing all work.
  • 400 invalid_signature → secret mismatch; re-copy from Lemon Squeezy.
  • 400 unmapped_variant → the test variant ID isn’t in your map; add a row.

When a customer checks out, Lemon Squeezy fires order_created. Keylight verifies X-Signature, looks up the Keylight app + key type from the variant ID, mints a license, and records the payment. For subscriptions: the first order arrives as order_created (that’s when provisioning happens — not subscription_created, which Keylight deliberately ignores). Renewals come as subscription_payment_success and re-extend the license. subscription_cancelled flips it to cancelled at period end.

To send a customer to a Lemon Squeezy checkout that upgrades their existing license, append checkout[custom][keylight_upgrade_key]=<license-key> to the Upgrade checkout URL you set on the key type. Lemon Squeezy echoes the custom field back in meta.custom_data and Keylight links the new order to the existing license.

Settings → Integrations → Lemon Squeezy → Disconnect clears the signing secret and the variant map. Existing licenses are untouched — only new webhook deliveries stop minting.