E-commerce Products API
Sync products from your shop into MailerLite so they can be added to campaigns and product blocks.
Get products
If you want to get products for the given shop, send this GET request
GET https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/productsRequest parameters
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| shop_id | integer | yes | Must provide valid shop id |
| limit | integer | no | Defaults to 100 |
| page | integer | no | Defaults to 1 |
| type | string | no | MailerLite shop only. One of one-time, subscription, booking |
Response
{
"data": [
{
"id": "31986843543567834",
"name": "Product name",
"price": 123.4,
"url": "https://shop-url.com/product-name",
"image": "https://shop-url.com/product-image.jpg",
"exclude_from_automations": false,
"short_description": "Product's short description.",
"description": "Product's longer description.",
"categories": [
{
"id": "1234566457534276",
"name": "Category 1",
"exclude_from_automations": false,
"created_at": "2021-09-01 14:03:50",
"updated_at": "2021-09-01 14:03:50"
},
{
"id": "1234566457534278",
"name": "Category 2",
"exclude_from_automations": false,
"created_at": "2021-09-01 14:03:50",
"updated_at": "2021-09-01 14:03:50"
}
],
"variants": []
}
],
"links": {
"first": "https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products?page=1",
"last": "https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"path": "https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products",
"per_page": 100,
"to": 1,
"total": 1
}
}Create/update product
You can create or update a product for the given shop.
To create a product for the given shop, send this POST request
POST https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/productsTo update a product for the given shop, send this PUT request
PUT https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products/:product_idRequest body
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| name | string | yes | The product's name |
| price | float | no | The product's price in the shop's currency. Defaults to 0. |
| exclude_from_automations | boolean | no | If true this product will not trigger any automations. Defaults to false |
| url | string | no | The products url. |
| image | string | no | The products main image url. |
| short_description | string | no | The product's short description. Max 255 characters. HTML tags are automatically removed |
| description | string | no | The product's description. HTML tags are automatically removed. |
{
"name": "Product name",
"price": 123.40,
"url": "https://shop-url.com/product-name",
"image": "https://shop-url.com/product-image.jpg",
"exclude_from_automations": false,
"short_description": "Product's short description.",
"description": "Product's longer description."
}Response
If the product was created:
Response Code: 201 Created{
"data": {
"id": "31986843543567834",
"name": "Product name",
"price": 123.4,
"url": "https://shop-url.com/product-name",
"image": "https://shop-url.com/product-image.jpg",
"exclude_from_automations": false,
"short_description": "Product's short description.",
"description": "Product's longer description.",
"categories": [],
"variants": []
}
}Error
Response Code: 422 Unprocessable EntityThe error response will contain information about the invalid data.
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name must be provided."]
}
}Fetch a product
If you want to fetch a product for the given shop, send this GET request
GET https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products/:product_idRequest parameters
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| product_id | integer | yes | Must provide valid product id |
| shop_id | integer | yes | Must provide valid shop id |
GET https://connect.mailerlite.com/api/ecommerce/shops/31986843064993537/products/319868430643456756Response
If the shop and the product exist:
Response Code: 200 OK{
"data": {
"id": "31986843543567834",
"name": "Product name",
"price": 123.4,
"url": "https://shop-url.com/product-name",
"image": "https://shop-url.com/product-image.jpg",
"exclude_from_automations": false,
"short_description": "Product's short description.",
"description": "Product's longer description.",
"categories": [
{
"id": "1234566457534276",
"name": "Category 1",
"exclude_from_automations": false,
"created_at": "2021-09-01 14:03:50",
"updated_at": "2021-09-01 14:03:50"
},
{
"id": "1234566457534278",
"name": "Category 2",
"exclude_from_automations": false,
"created_at": "2021-09-01 14:03:50",
"updated_at": "2021-09-01 14:03:50"
}
],
"variants": []
}
}Error
If the product or shop cannot be found:
Response Code: 404 Not FoundFetch total products count
If you want to fetch the total products count for the given shop, send this GET request
GET https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products?limit=0Request parameters
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| shop_id | integer | yes | Must provide valid shop id |
| limit | integer | yes | Value must be 0 |
Response
Response Code: 200 OK{
"total": 123
}Delete a product
If you want to delete a product for the given shop, send this DELETE request
DELETE https://connect.mailerlite.com/api/ecommerce/shops/:shop_id/products/:product_idRequest parameters
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| product_id | integer | yes | Must provide valid product id |
| shop_id | integer | yes | Must provide valid shop id |
Response
Response code: 200 OK{
"data": {
"id": "31986843543567834",
"name": "Product name",
"price": 123.4,
"url": "https://shop-url.com/product-name",
"image": "https://shop-url.com/product-image.jpg",
"exclude_from_automations": false,
"short_description": "Product's short description.",
"description": "Product's longer description.",
"categories": [],
"variants": []
}
}Error
Response code: 404 Not FoundMailerLite shop products
Products of the MailerLite shop are sold through MailerLite checkout. They use the same endpoints as other products, with extra fields.
Additional response fields
| Field | Type | Description |
|---|---|---|
| type | string | one-time, subscription or booking |
| currency | string | ISO 4217 currency code of the product |
| currency_symbol | string | Symbol of currency |
| enabled | boolean | Whether the product can be bought |
| discounts | array | Discounts on the product |
| assets | array | Files and links delivered after purchase |
| settings | object | Post-purchase action and booking settings |
| stripe_minimum | boolean | true if the price is below Stripe's minimum charge for the currency |
| has_checkout | boolean | Whether the product has a checkout page |
| checkout_url | string | Checkout page URL. Only returned when has_checkout is true |
| order_stats | object | Orders count and total amount. Only returned when listing products |
| created_at | string | Creation date |
{
"data": {
"id": "31986843543567834",
"name": "Product name",
"price": 20,
"type": "one-time",
"currency": "USD",
"currency_symbol": "$",
"enabled": true,
"discounts": [
{
"id": "31986843543567900",
"name": "Launch discount",
"value": "10",
"is_percentage": true,
"enabled": true,
"start_date": "2026-10-01 00:00:00",
"end_date": "2026-10-31 23:59:59",
"created_at": "2026-10-01 10:00:00",
"updated_at": "2026-10-01 10:00:00",
"price_after_discount": 18
}
],
"assets": [],
"settings": {
"action": "move_to_group",
"group_id": "1234567890"
},
"stripe_minimum": false,
"has_checkout": true,
"checkout_url": "https://...",
"created_at": "2026-10-01 10:00:00"
}
}Create/update request body
On the MailerLite shop, name, price, currency and settings are required on both POST and PUT.
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| price | float | yes | Must meet Stripe's minimum charge for currency, unless settings.free is true |
| currency | string | yes | ISO 4217 currency code |
| type | string | no | one-time, subscription or booking |
| enabled | boolean | no | Whether the product can be bought |
| settings | object | yes | See settings below |
| discounts | array | no | See discounts below |
Discounts
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| discounts.*.name | string | no | Discount name |
| discounts.*.value | float | no | Amount or percentage. The discounted price must meet Stripe's minimum or be 0 |
| discounts.*.is_percentage | boolean | no | If true, value is a percentage |
| discounts.*.enabled | boolean | no | Whether the discount is active |
| discounts.*.start_date | string | no | Y-m-d H:i:s |
| discounts.*.end_date | string | no | Y-m-d H:i:s, after start_date |
On PUT, sending discounts replaces all existing discounts and [] removes them. Omit discounts to keep them.
Settings
settings is merged into the product's existing settings on PUT, but action must still be sent.
| Parameter | Type | Required | Limitations |
|---|---|---|---|
| action | string | yes | move_to_group, remove_from_group or update_custom_field |
| group_id | string | if action is move_to_group or remove_from_group | Group id |
| field_id | string | if action is update_custom_field | Field id |
| action_on_field | string | no | set_to_current_date sets the field to the purchase date |
| field_value | string | with field_id, unless set_to_current_date | Value to set |
| free | boolean | no | Product is free |
| booking_type | string | no | one-on-one or group |
| duration | float | no | Between 15 minutes and 24 hours, in 5-minute steps |
| duration_unit | string | with duration | minutes or hours |
| calendar_integration_type | string | no | google, outlook or external. Google and Outlook must be connected |
| external_link | string | if calendar_integration_type is external | URL |
| location | string | no | google-meet, in-person, phone-call, custom-link, teams-meeting |
| location_address | string | if location is in-person | |
| location_link | string | if location is custom-link | URL |
| location_instructions | string | no | |
| timezone_id | integer | no | Timezone id |
| booking_window_days | integer | no | 0 to 100 |
| buffer_between_meetings | integer | no | Minimum 0 |
| buffer_between_meetings_unit | string | no | minutes or hours |
| minimum_notice_period | integer | no | Minimum 0 |
| minimum_notice_period_unit | string | no | minutes, hours or days |
| custom_availability_days | object | no | Keyed by weekday (monday...), each ["H:i", "H:i"] with start before end |
| booking_group_date_time_utc | string | if booking_type is group | Y-m-d H:i in UTC, in the future |
| booking_group_max_participants | integer | no | 1 to 1000 |
| booking_group_display_remaining_slots | boolean | no | Show remaining slots on checkout |
{
"name": "Product name",
"price": 20,
"currency": "USD",
"type": "one-time",
"settings": {
"action": "move_to_group",
"group_id": "1234567890"
},
"discounts": [
{
"name": "Launch discount",
"value": 10,
"is_percentage": true,
"enabled": true,
"start_date": "2026-10-01 00:00:00",
"end_date": "2026-10-31 23:59:59"
}
]
}Errors
If the account's paid product limit would be exceeded:
Response Code: 413 Payload Too Large