Subscription Management using the Lemon Squeezy API
Learn how to effectively manage subscriptions using the Lemon Squeezy API, including changing plans, cancelling, pausing, and resuming subscriptions.
This guide covers essential subscription management tasks using the Lemon Squeezy Subscriptions API. You’ll learn how to programmatically change subscription plans, handle cancellations, implement pausing and resuming functionality, and manage other key aspects of your subscription-based service.
Creating subscriptions
Read the “Taking payments” guide to learn how to create checkouts and let customers sign up to your subscription products.
Saving product data in your database
To enable plan switching within your app, you need to store your Lemon Squeezy product data locally. This builds on the information covered in the “Saving checkout and subscription data in your database” section of the “Taking payments” guide, where we discussed essential data to store in your app.
Make a GET
request to the list all variants endpoint to return a list of all Variants.
To populate your app with product and variant data, you have two main options:
- Manually call the list all variants endpoint whenever you edit or add products.
- Set up a background job to fetch this data regularly.
We recommend storing the following key information for each variant:
product_id
variant_id
name
price
Storing these details allows you to easily display and manage product information within your app.
Changing plans
To change a subscription’s plan (variant):
- Send a
PATCH
request to the specific subscription endpoint - Include the new variant ID in the request body.
The subscription will be instantly moved to the new product variant and you will be able to verify this by checking the response (which will contain a Subscription object).
You can also manage subscription plans in the dashboard.
Handling proration
When changing a subscription’s plan (variant), proration occurs by default.
”Proration” is the term used for calculating the price difference between plans, ensuring customers are charged correctly for the time spent on each plan.
For example:
- A customer moves from a $19/month plan to a $99/month plan
- A prorated amount is charged based on the time already spent on the $19 plan
- By default, this extra amount is added to the next renewal
You have two options to control how proration is handled:
"invoice_immediately": true
- Creates a new invoice during the plan change
- If the new plan is cheaper, the invoice total will be zero
- If the new plan is more expensive, an immediate payment for the difference is attempted
"disable_prorations": true
- Completely disables proration
- The customer moves to the new plan’s price at the next renewal without any additional charges
Important notes:
- If both options are used in the same request,
disable_prorations
overridesinvoice_immediately
- The plan change takes effect immediately, regardless of the proration option chosen
For more information, see the Subscriptions API documentation.
Cancelling and resuming subscriptions
To cancel a subscription:
- Send a
DELETE
request to the specific subscription endpoint. - The response will contain an updated Subscription object with:
cancelled
set totrue
status
set to"cancelled"
For more information see the Subscription API documentation.
Grace period
If a subscription is cancelled mid billing period (either by the customer or by the store owner), it will enter a “grace period” before it expires at the next scheduled renewal date (refected in a subscription’s ends_at
value). The customer should still have access to your app or product until this date because they have paid for that time period.
During this cancelled
grace period, it’s possible to resume the subscription with a quick API call with cancelled
set to false
.
Resuming a subscription in grace period
If a subscription is resumed like this, the subscription is changed back to active
and the original payment schedule will continue.
Expired subscriptions
If a subscription is cancelled and then reaches its next renewal date (ends_at
) without being resumed, it will instead expire (its status will change to expired
).
When a subscription is in the expired state, your customer should no longer have access to your app and the subscription is no longer resumable.
Pausing and unpausing subscriptions
Pausing a subscription is a great option if you want to keep a subscription active but pause regular payment collection. Maybe this is because your app will be inaccessible for a temporary period or you will be on holiday during a service-based retainer. Alternatively you may want to let your customers pause subscriptions if they won;t be able to make full use of your product for a certain period of time.
A paused subscription with have a status
of paused
.
Pausing a subscription
To pause a subscription, send a PATCH
request containing a pause
object:
When pausing a subscription, you can choose between two mode values:
free
: Use this when you want to offer your product or service at no cost during the pause period.void
: Use this when you cannot provide your services during the pause period.
Both modes temporarily stop payment collection.
You can also optionally pass resumes_at
to specify a date to automatically unpause the subscription.
Manually unpausing a paused subscription
- Send a
PATCH
request to the specific subscription endpoint. - Include
pause
attribute withnull
value.
Similarly to resuming a cancelled subscription, the subscription will be changed to active and payment collection will resume on its original schedule.
For more information, see the Subscriptions API reference.
Updating billing details
Letting your customers update their payment details during a subscription is an essential feature, especially when cards expire or if payments fail for any reason.
We provide a signed URL in every Subscription-related API request and webhook event in urls.update_payment_method
, which customers can use to easily update their billing details. We suggest you make this URL easily available to your customers, for example in your app’s billing pages.
If you have a custom domain set up, update_payment_method
will contain your custom domain.
During our payment recovery process any subscriptions with failed payments will have four retries before entering the (optional) dunning flow. After each payment retry and for each of the dunning series emails, we will send the same URL to the customer to update their billing details.
For security, the URLs returned by the API expire after 24 hours. You will need to query the subscription over the API for a refreshed URL.
Update payment method modal
To make the URL open in a more seamless overlay on top of your app (similar to the checkout overlay), use Lemon.js to open the URL with the LemonSqueezy.Url.Open()
method.
Changing the billing date
- Send a
PATCH
request to the specific subscription endpoint. - Include
billing_anchor
attribute.
By default, a subscription’s billing_anchor
will match the date the customer initially signed up, but you can easily change it to any other day of the month. As an example, some businesses like to charge all customers on the first of each month.
When changing the billing_anchor
value of a subscription, a proration will occur to make sure the customer is not overcharged or undercharged when the length of their billing period changes.
If the current month doesn’t contain the day that matches your billing_anchor
(for example, if the billing_anchor
is 31 and the month is November), the customer will be charged on the last day of the month.
You can use null
or 0
to easily change the billing anchor to the current date. Doing this will also remove any active trial period.
For more information please refer to the API reference
Update a subscription’s quantity
Go to the Usage-based billing guide to find out how to update a subscription’s quantity or usage.
And that’s it! You’re now equipped to set up, manage, and modify subscriptions using the Lemon Squeezy API, enabling you to provide a flexible and user-friendly subscription experience for your customers.
Looking for SDKs?
Lemon Squeezy offers official SDKs for several programming languages to make API integration even easier. Check out our available SDKs to find one that suits your development needs.