The Lemon Squeezy API lets you easily access and manage your store programatically but sometimes multiple API requests are needed to load related data.
In this quick tutorial, we'll go through some examples of using "includes" to load multiple data objects into a single API request.
Products and variants
This first example loads variant data when querying products. This is really useful if you are saving product data locally in your application because you need variant IDs to change a subscriber's plan.
Typically you may query the products list and then use the URLs returned in the data.relationships.variants.links
object to get data for each product's variants. If you do this, you'll end up making multiple API requests:
GET https://api.lemonsqueezy.com/v1/products
GET https://api.lemonsqueezy.com/v1/products/{product_id}/variants
GET https://api.lemonsqueezy.com/v1/products/{product_id}/variants
GET https://api.lemonsqueezy.com/v1/products/{product_id}/variants
- etc
This isn't the ideal way to get the data you need from the API and I'll show you why. Here is an example response from the /products
endpoint. Note the variant relationship URLs for each product, which could be used to query each product's variants.
GET https://api.lemonsqueezy.com/v1/products
{
...
"data": [
{
"type": "products",
"id": "1",
"attributes": {
"store_id": 1,
"name": "Example Product",
"slug": "example-product",
"description": "
Lorem ipsum...
",
"status": "published",
"status_formatted": "Published",
"thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"large_thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"price": 999,
"price_formatted": "$9.99",
"from_price": null,
"to_price": null,
"pay_what_you_want": false,
"buy_now_url": "https://my-store.lemonsqueezy.com/checkout/buy/0a841cf5-4cc2-4bbb-ae5d-9529d97deec6",
"created_at": "2021-05-27T12:54:47.000000Z",
"updated_at": "2021-07-14T11:25:24.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/products/1/store",
"self": "https://api.lemonsqueezy.com/v1/products/1/relationships/store"
}
},
"variants": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/products/1/variants",
"self": "https://api.lemonsqueezy.com/v1/products/1/relationships/variants"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/products/1"
}
},
{...},
{...}
]
...
}
As you can see, this method is cumbersome, needs a lot of API calls and can get out of hand very quickly if you have a handful of products and variants. You also risk hitting rate limits by requesting the API so frequently.
Instead, we should look to load related resources in a single API call. In this case we should be loading related variants into the products request. To do this, we can use the include
query parameter in the request:
GET https://api.lemonsqueezy.com/v1/products?include=variants
Using this one API request, we get all the data we need. It just needs some digesting to ensure all the data is ready to use.
This is an example response:
GET https://api.lemonsqueezy.com/v1/products?include=variants
{
"meta": {
"page": {
"currentPage": 1,
"from": 1,
"lastPage": 1,
"perPage": 10,
"to": 10,
"total": 10
}
},
"jsonapi": {
"version": "1.0"
},
"links": {
"first": "https://api.lemonsqueezy.com/v1/products?page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=name",
"last": "https://api.lemonsqueezy.com/v1/products?page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=name"
},
"data": [
{
"type": "products",
"id": "1",
"attributes": {
"store_id": 1,
"name": "Example Product",
"slug": "example-product",
"description": "
Lorem ipsum...
",
"status": "published",
"status_formatted": "Published",
"thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"large_thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"price": 999,
"price_formatted": "$9.99",
"from_price": null,
"to_price": null,
"pay_what_you_want": false,
"buy_now_url": "https://my-store.lemonsqueezy.com/checkout/buy/0a841cf5-4cc2-4bbb-ae5d-9529d97deec6",
"created_at": "2021-05-27T12:54:47.000000Z",
"updated_at": "2021-07-14T11:25:24.000000Z",
"test_mode": false
},
"relationships": {
...
},
"links": {
...
}
},
{...},
{...}
],
"included": [
{
"type": "variants",
"id": "1",
"attributes": {
"product_id": 1,
"name": "Default",
"slug": "537b22ba-fcc9-452a-9021-c3cabe3985cf",
"description": "
This is the variant description.
",
"price": 999,
"is_subscription": true,
"interval": "month",
"interval_count": 1,
"has_free_trial": false,
"trial_interval": "day",
"trial_interval_count": 30,
"pay_what_you_want": false,
"min_price": 0,
"suggested_price": 0,
"has_license_keys": false,
"license_activation_limit": 5,
"is_license_limit_unlimited": false,
"license_length_value": 1,
"license_length_unit": "years",
"is_license_length_unlimited": false,
"sort": 0,
"status": "pending",
"status_formatted": "Pending",
"created_at": "2021-05-27T12:54:47.000000Z",
"updated_at": "2021-07-14T11:25:24.000000Z",
"test_mode": false
},
"relationships": {
"product": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/variants/1/product",
"self": "https://api.lemonsqueezy.com/v1/variants/1/relationships/product"
}
},
"files": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/variants/1/files",
"self": "https://api.lemonsqueezy.com/v1/variants/1/relationships/files"
}
},
"price-model": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/variants/1/price-model",
"self": "https://api.lemonsqueezy.com/v1/variants/1/relationships/price-model"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/variants/1"
}
},
{...},
{...}
]
}
data
contains a list of products and included
contains the objects requested via the include
query parameter.
If you want, you can even include multiple related resources, like ?include=variants,store
. If you do this, included
would contain a mixed list of Variant and Store objects.
Now you know the basics of how to request related resources, I'm going to show a few other example requests and responses to help you out when building an API integration.
A product and its store
This next example loads store data when querying a single product.
GET https://api.lemonsqueezy.com/v1/products/1?include=store
In this response you'll get a single Product object in the data
key, and a single Store object in included
.
{
"jsonapi": {
"version": "1.0"
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/products/1"
},
"data": {
"type": "products",
"id": "1",
"attributes": {
"store_id": 1,
"name": "Example Product",
"slug": "example-product",
"description": "
Lorem ipsum...
",
"status": "published",
"status_formatted": "Published",
"thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"large_thumb_url": "https://app.lemonsqueezy.com/storage/media/1/1c40f227-aed5-4321-9ffc-62f37a06c9a0.jpg",
"price_formatted": "$9.99",
"price": 999,
"from_price": null,
"to_price": null,
"pay_what_you_want": false,
"buy_now_url": "https://my-store.lemonsqueezy.com/checkout/buy/0a841cf5-4cc2-4bbb-ae5d-9529d97deec6",
"created_at": "2021-05-27T12:54:47.000000Z",
"updated_at": "2021-07-14T11:25:24.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/products/1/store",
"self": "https://api.lemonsqueezy.com/v1/products/1/relationships/store"
},
"data": {
"type": "stores",
"id": "1"
}
},
"variants": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/products/1/variants",
"self": "https://api.lemonsqueezy.com/v1/products/1/relationships/variants"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/products/1"
}
},
"included": [
{
"type": "stores",
"id": "1",
"attributes": {
"name": "Demo App",
"slug": "demo-app-123",
"domain": "demo-app-123.lemonsqueezy.com",
"url": "https://demo-app-123.lemonsqueezy.com",
"avatar_url": "https://lemonsqueezy-staging.imgix.net/avatars/stores/1/8rJPdCMEFSUpklK6F8w4B2yDa9O4nr50CsBa10ZP.png",
"plan": "free",
"country": "FR",
"country_nicename": "France",
"currency": "EUR",
"total_sales": 0,
"total_revenue": 0,
"thirty_day_sales": 0,
"thirty_day_revenue": 0,
"created_at": "2021-05-20T10:47:38.000000Z",
"updated_at": "2021-05-20T10:47:38.000000Z"
},
"relationships": {
"products": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/stores/1/products",
"self": "https://api.lemonsqueezy.com/v1/stores/1/relationships/products"
}
},
"orders": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/stores/1/orders",
"self": "https://api.lemonsqueezy.com/v1/stores/1/relationships/orders"
}
},
"subscriptions": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/stores/1/subscriptions",
"self": "https://api.lemonsqueezy.com/v1/stores/1/relationships/subscriptions"
}
},
"discounts": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/stores/1/discounts",
"self": "https://api.lemonsqueezy.com/v1/stores/1/relationships/discounts"
}
},
"license-keys": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/stores/1/license-keys",
"self": "https://api.lemonsqueezy.com/v1/stores/1/relationships/license-keys"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/stores/1"
}
}
]
}
Subscriptions and customers
This next example loads customer data when querying subscriptions.
GET https://api.lemonsqueezy.com/v1/subscriptions?include=customer
In this response you'll get a list of Subscription objects in the data
key, and a list of Customer objects in included
.
{
"meta": {
"page": {
"currentPage": 1,
"from": 1,
"lastPage": 1,
"perPage": 10,
"to": 9,
"total": 9
}
},
"jsonapi": {
"version": "1.0"
},
"links": {
"first": "https://api.lemonsqueezy.com/v1/subscriptions?include=customer&page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=-createdAt",
"last": "https://api.lemonsqueezy.com/v1/subscriptions?include=customer&page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=-createdAt"
},
"data": [
{
"type": "subscriptions",
"id": "1",
"attributes": {
"store_id": 1,
"customer_id": 1,
"order_id": 1,
"order_item_id": 1,
"product_id": 1,
"variant_id": 1,
"product_name": "Example Product",
"variant_name": "Example Variant",
"user_name": "Darlene Daugherty",
"user_email": "
[email protected]",
"status": "active",
"status_formatted": "Active",
"card_brand": "visa",
"card_last_four": "42424",
"pause": null,
"cancelled": false,
"trial_ends_at": null,
"billing_anchor": 12,
"first_subscription_item": {
"id": 1,
"subscription_id": 1,
"price_id": 1,
"quantity": 5,
"created_at": "2021-08-11T13:47:28.000000Z",
"updated_at": "2021-08-11T13:47:28.000000Z"
},
"urls": {
"update_payment_method": "https://my-store.lemonsqueezy.com/subscription/1/payment-details?expires=1666869343&signature=9985e3bf9007840aeb3951412be475abc17439c449c1af3e56e08e45e1345413",
"customer_portal": "https://my-store.lemonsqueezy.com/billing?expires=1666869343&signature=82ae290ceac8edd4190c82825dd73a8743346d894a8ddbc4898b97eb96d105a5"
},
"renews_at": "2022-11-12T00:00:00.000000Z",
"ends_at": null,
"created_at": "2021-08-11T13:47:27.000000Z",
"updated_at": "2021-08-11T13:54:19.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/store",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/store"
}
},
"customer": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/customer",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/customer"
},
"data": {
"type": "customers",
"id": "1"
}
},
"order": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/order",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/order"
}
},
"order-item": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/order-item",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/order-item"
}
},
"product": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/product",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/product"
}
},
"variant": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/variant",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/variant"
}
},
"subscription-items": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/subscription-items",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/subscription-items"
}
},
"subscription-invoices": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/subscription-invoices",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/subscription-invoices"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1"
}
},
{...},
{...}
],
"included": [
{
"type": "customers",
"id": "1",
"attributes": {
"store_id": 1,
"name": "Luke Skywalker",
"email": "
[email protected]",
"status": "subscribed",
"city": null,
"region": null,
"country": "US",
"total_revenue_currency": 84332,
"mrr": 1999,
"status_formatted": "Subscribed",
"country_formatted": "United States",
"total_revenue_currency_formatted": "$843.32",
"mrr_formatted": "$19.99",
"urls": {
"customer_portal": "https://my-store.lemonsqueezy.com/billing?expires=1666869343&signature=82ae290ceac8edd4190c82825dd73a8743346d894a8ddbc4898b97eb96d105a5"
},
"created_at": "2022-12-01T13:01:07.000000Z",
"updated_at": "2022-12-09T09:05:21.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/customers/1/store",
"self": "https://api.lemonsqueezy.com/v1/customers/1/relationships/store"
}
},
"orders": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/customers/1/orders",
"self": "https://api.lemonsqueezy.com/v1/customers/1/relationships/orders"
}
},
"subscriptions": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/customers/1/subscriptions",
"self": "https://api.lemonsqueezy.com/v1/customers/1/relationships/subscriptions"
}
},
"license-keys": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/customers/1/license-keys",
"self": "https://api.lemonsqueezy.com/v1/customers/1/relationships/license-keys"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/customers/1"
}
},
{...},
{...}
]
}
A subscription and subscription invoices
This last example loads invoice data when querying a subscription.
GET https://api.lemonsqueezy.com/v1/subscription/1?include=subscription-invoices
In this response you'll get a single Subscription object in the data
key, and a list of Subscription invoice objects in included
.
{
"meta": {
"page": {
"currentPage": 1,
"from": 1,
"lastPage": 1,
"perPage": 10,
"to": 9,
"total": 9
}
},
"jsonapi": {
"version": "1.0"
},
"links": {
"first": "https://api.lemonsqueezy.com/v1/subscriptions?include=subscription-invoices&page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=-createdAt",
"last": "https://api.lemonsqueezy.com/v1/subscriptions?include=subscription-invoices&page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=-createdAt"
},
"data": {
"type": "subscriptions",
"id": "1",
"attributes": {
"store_id": 1,
"customer_id": 1,
"order_id": 1,
"order_item_id": 1,
"product_id": 1,
"variant_id": 1,
"product_name": "Example Product",
"variant_name": "Example Variant",
"user_name": "Darlene Daugherty",
"user_email": "
[email protected]",
"status": "active",
"status_formatted": "Active",
"card_brand": "visa",
"card_last_four": "42424",
"pause": null,
"cancelled": false,
"trial_ends_at": null,
"billing_anchor": 12,
"first_subscription_item": {
"id": 1,
"subscription_id": 1,
"price_id": 1,
"quantity": 5,
"created_at": "2021-08-11T13:47:28.000000Z",
"updated_at": "2021-08-11T13:47:28.000000Z"
},
"urls": {
"update_payment_method": "https://my-store.lemonsqueezy.com/subscription/1/payment-details?expires=1666869343&signature=9985e3bf9007840aeb3951412be475abc17439c449c1af3e56e08e45e1345413",
"customer_portal": "https://my-store.lemonsqueezy.com/billing?expires=1666869343&signature=82ae290ceac8edd4190c82825dd73a8743346d894a8ddbc4898b97eb96d105a5"
},
"renews_at": "2022-11-12T00:00:00.000000Z",
"ends_at": null,
"created_at": "2021-08-11T13:47:27.000000Z",
"updated_at": "2021-08-11T13:54:19.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/store",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/store"
}
},
"customer": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/customer",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/customer"
}
},
"order": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/order",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/order"
}
},
"order-item": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/order-item",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/order-item"
}
},
"product": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/product",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/product"
}
},
"variant": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/variant",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/variant"
}
},
"subscription-items": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/subscription-items",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/subscription-items"
}
},
"subscription-invoices": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscriptions/1/subscription-invoices",
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1/relationships/subscription-invoices"
},
"data": [
{
"type": "subscription-invoices",
"id": "1"
},
{...},
{...}
]
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/subscriptions/1"
}
},
"included": [
{
"type": "subscription-invoices",
"id": "1",
"attributes": {
"store_id": 1,
"subscription_id": 1,
"customer_id": 1,
"user_name": "Darlene Daugherty",
"user_email": "
[email protected]",
"billing_reason": "initial",
"card_brand": "visa",
"card_last_four": "4242",
"currency": "USD",
"currency_rate": "1.00000000",
"status": "paid",
"status_formatted": "Paid",
"refunded": false,
"refunded_at": null,
"subtotal": 999,
"discount_total": 0,
"tax": 0,
"total": 999,
"subtotal_usd": 999,
"discount_total_usd": 0,
"tax_usd": 0,
"total_usd": 999,
"subtotal_formatted": "$9.99",
"discount_total_formatted": "$0.00",
"tax_formatted": "$0.00",
"total_formatted": "$9.99",
"urls": {
"invoice_url": "https://app.lemonsqueezy.com/my-orders/.../subscription-invoice/..."
},
"created_at": "2023-01-18T12:16:24.000000Z",
"updated_at": "2023-01-18T12:16:24.000000Z",
"test_mode": false
},
"relationships": {
"store": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/store",
"self": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/relationships/store"
}
},
"subscription": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/subscription",
"self": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/relationships/subscription"
}
},
"customer": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/customer",
"self": "https://api.lemonsqueezy.com/v1/subscription-invoices/1/relationships/customer"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/subscription-invoices/1"
}
},
{...},
{...}
]
}