Your product catalog holds the products that are being sold to customers, including subscription plans, recurring addons, and one-time charges.
Create products and related prices to start billing.
How it works
A complete product in Paddle is made up of two parts:
- A product entity that describes the item, like its name, description, and an image.
- At least one related price entity that describes how much and how often a product is billed.
Products are the items that customers buy — like subscription plans, recurring addons, or one-time charges. Prices describe how they pay for them.
In this example, Enterprise is a product and $3000/mo is a price for it.
When switching from monthly to yearly:
- Products remain the same — the name and details remain as Enterprise.
- Prices change — your page should fetch prices for products where the billing cycle is yearly rather than monthly.
You can create as many prices for a product as you want to describe all the ways it's billed. However, prices may only relate to one product.
Billing cycle
The billing cycle against a price determines how often Paddle bills for it. You can set an interval and a frequency. This is typically things like every month, every three months, or every year, but you can be as flexible as you like.
Paddle supports multi-product subscriptions, letting you add recurring addons alongside subscription plans. When building multi-product subscriptions, all items on a subscription must have the same billing period. This means that if a customer subscribes to your "Pro plan" with a yearly price, you must also create yearly price for any recurring addons. You can't add a monthly addon to a subscription for a yearly plan.
One-time charges
Prices don't have to have a billing cycle. These are called "one-time charges."
One-time charges can be billed to subscriptions. They're typically used for things like setup or onboarding fees at the start of a subscription, or data auditing or support incident fees during a subscription.
You might also use them to offer ebooks, access to webinars, or other learning resources to customers.
Create a product
Create products to describe items being sold. You can add prices to products afterward.
We recommend creating products using the Paddle dashboard.
- Go to Paddle > Catalog > Products.
- Click New product
- Enter details for your new product.
- Click Save when you're done.
Send a POST request to the /products endpoint to create a product.
In your request, include the product name and tax_category.
Optionally include description, image_url (HTTPS, square images recommended), and custom_data.
For tax_category, standard or saas are available by on all Paddle accounts by default. You can request other tax categories for your account in the Paddle dashboard.
This example creates a new product for a subscription plan called "AeroEdit Student." It includes an object of custom data.
If successful, Paddle responds with a copy of the new product entity. Paddle creates an id starting with pro_ — keep this for the next step to associate a price.
{ "name": "AeroEdit Student", "tax_category": "standard", "description": "Essential tools for student pilots to manage flight logs, analyze performance, and plan routes, and ensure compliance. Valid student pilot certificate from the FAA required.", "image_url": "https://paddle.s3.amazonaws.com/user/165798/bT1XUOJAQhOUxGs83cbk_pro.png", "custom_data": { "features": { "aircraft_performance": true, "compliance_monitoring": false, "flight_log_management": true, "payment_by_invoice": false, "route_planning": true, "sso": false }, "suggested_addons": [ "pro_01h1vjes1y163xfj1rh1tkfb65", "pro_01gsz97mq9pa4fkyy0wqenepkz" ], "upgrade_description": null }}{ "data": { "id": "pro_01htz88xpr0mm7b3ta2pjkr7w2", "name": "AeroEdit Student", "tax_category": "standard", "type": "standard", "description": "Essential tools for student pilots to manage flight logs, analyze performance, and plan routes, and ensure compliance. Valid student pilot certificate from the FAA required.", "image_url": "https://paddle.s3.amazonaws.com/user/165798/bT1XUOJAQhOUxGs83cbk_pro.png", "custom_data": { "features": { "aircraft_performance": true, "compliance_monitoring": false, "flight_log_management": true, "payment_by_invoice": false, "route_planning": true, "sso": false }, "suggested_addons": [ "pro_01h1vjes1y163xfj1rh1tkfb65", "pro_01gsz97mq9pa4fkyy0wqenepkz" ], "upgrade_description": null }, "status": "active", "import_meta": null, "created_at": "2024-04-08T16:22:16.024Z", "updated_at": "2024-04-08T16:22:16.024Z" }, "meta": { "request_id": "cf40234b-e140-44d1-a83f-7bbdedd88589" }}This example creates a product for a recurring addon called "Voice rooms addon."
If successful, Paddle responds with a copy of the new product entity. Paddle creates an id starting with pro_ — keep this for the next step to associate a price.
{ "name": "Voice rooms addon", "tax_category": "standard", "description": "Create voice rooms in your chats to work in real time alongside your colleagues. Includes unlimited voice rooms and recording backup for compliance.", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/GcZzBjXRfiraensppgtQ_icon2.png"}{ "data": { "id": "pro_01h1vjes1y163xfj1rh1tkfb65", "name": "Voice rooms addon", "tax_category": "standard", "description": "Create voice rooms in your chats to work in real time alongside your colleagues. Includes unlimited voice rooms and recording backup for compliance.", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/GcZzBjXRfiraensppgtQ_icon2.png", "custom_data": null, "status": "active", "created_at": "2023-06-01T13:30:50.302Z" }, "meta": { "request_id": "4fd71021-1ba6-4401-97bc-355806af83c3" }}This example creates a new product for a one-time charge called "Custom domains setup."
If successful, Paddle responds with a copy of the new product entity. Paddle creates an id starting with pro_ — keep this for the next step to associate a price.
{ "name": "Custom domains setup", "tax_category": "standard", "description": "Make ChatApp truly your own with custom domains! Custom domains reinforce your brand identity and make it easy for your team to access ChatApp.", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/SW3OevDQ92dUHSkN5a2x_icon3.png"}{ "data": { "id": "pro_01gsz97mq9pa4fkyy0wqenepkz", "name": "Custom domains", "tax_category": "standard", "description": "Make ChatApp truly your own with custom domains! Custom domains reinforce your brand identity and make it easy for your team to access ChatApp.", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/SW3OevDQ92dUHSkN5a2x_icon3.png", "custom_data": null, "status": "active", "created_at": "2023-02-23T14:01:02.441Z" }, "meta": { "request_id": "7b476cdd-c8eb-4f47-90c3-bf24ad5187db" }}Create a related price
Once you've created products, create related prices that describe how you bill for them. You can't offer a product for sale without creating a price.
Add price overrides to a price to set country specific prices. Price overrides let you override the base price with a custom price and currency for any country. See: Localize prices
- Go to Paddle > Catalog > Products, then click the product you want to add a price to in the list.
- Under the Prices section, click New price
- Enter details for your new price.
- Click Save when you're done.
Send a POST request to the /prices endpoint to create a price.
In you request, include product_id (Paddle ID of the product), unit_price (base price), and a description.
To make a price recurring, include billing_cycle with interval and frequency.
Optionally include trial_period (requires billing_cycle), name (shown at checkout and on invoices), unit_price_overrides for localized pricing, tax_mode, quantity limits (defaults to 1-100), and custom_data.
This example creates a monthly price for a subscription plan with a trial period. It's related to the subscription plan product using the product_id field.
If successful, Paddle responds with a copy of the new price entity.
{ "description": "Monthly (per seat) with 14 day trial", "name": "Monthly (per seat)", "product_id": "pro_01htz88xpr0mm7b3ta2pjkr7w2", "unit_price": { "amount": "500", "currency_code": "USD" }, "billing_cycle": { "interval": "month", "frequency": 1 }, "trial_period": { "interval": "day", "frequency": 14 }, "tax_mode": "account_setting"}{ "data": { "id": "pri_01hv0vax6rv18t4tamj848ne4d", "product_id": "pro_01htz88xpr0mm7b3ta2pjkr7w2", "type": "standard", "description": "Monthly (per seat) with 14 day trial", "name": "Monthly (per seat)", "billing_cycle": { "interval": "month", "frequency": 1 }, "trial_period": { "interval": "day", "frequency": 14, "requires_payment_method": false }, "tax_mode": "account_setting", "unit_price": { "amount": "500", "currency_code": "USD" }, "unit_price_overrides": [], "custom_data": null, "status": "active", "quantity": { "minimum": 1, "maximum": 100 }, "import_meta": null, "created_at": "2024-04-09T07:14:38.424504286Z", "updated_at": "2024-04-09T07:14:38.424504359Z" }, "meta": { "request_id": "9e7f51e8-838b-4b2c-b0fa-d52d0593354c" }}This example creates a monthly price for a recurring addon. It's related to the recurring addon product using the product_id field.
If successful, Paddle responds with a copy of the new price entity.
{ "product_id": "pro_01h1vjes1y163xfj1rh1tkfb65", "description": "Monthly (recurring addon)", "name": "Monthly (recurring addon)", "billing_cycle": { "interval": "month", "frequency": 1 }, "unit_price": { "amount": "10000", "currency_code": "USD" }}{ "data": { "id": "pri_01h1vjfevh5etwq3rb416a23h2", "product_id": "pro_01h1vjes1y163xfj1rh1tkfb65", "name": "Monthly (recurring addon)", "description": "Monthly (recurring addon)", "billing_cycle": { "interval": "month", "frequency": 1 }, "trial_period": null, "tax_mode": "account_setting", "unit_price": { "amount": "10000", "currency_code": "USD" }, "unit_price_overrides": [], "custom_data": null, "status": "active", "quantity": { "minimum": 1, "maximum": 100 } }, "meta": { "request_id": "4e373a48-9dfb-4d97-a914-e7e45ca3a61d" }}This example creates a monthly price for a one-time charge. It's related to the one-time charge product using the product_id field. Only one charge may be applied at once, so it includes the quantity object with minimum and maximum values of 1.
If successful, Paddle responds with a copy of the new price entity.
{ "product_id": "pro_01gsz97mq9pa4fkyy0wqenepkz", "description": "One-time charge", "billing_cycle": null, "unit_price": { "amount": "19900", "currency_code": "USD" }, "quantity": { "minimum": 1, "maximum": 1 }}{ "data": { "id": "pri_01gsz98e27ak2tyhexptwc58yk", "product_id": "pro_01gsz97mq9pa4fkyy0wqenepkz", "name": null, "description": "One-time charge", "billing_cycle": null, "trial_period": null, "tax_mode": "account_setting", "unit_price": { "amount": "19900", "currency_code": "USD" }, "unit_price_overrides": [], "custom_data": null, "status": "active", "quantity": { "minimum": 1, "maximum": 1 } }, "meta": { "request_id": "94f4aa43-45b3-4f01-90ee-4a593eb1b656" }}Review prices and products
Once you've created products and related prices, you can use the include query parameter in the Paddle API to review them. You can:
- Get a product and include its related prices
- Get a price and include its related product
- List prices for a product
Get a product and all prices
Use the include query parameter with the value prices to include related prices in the response.
Return entities related to the specified product. Use a comma-separated list to specify multiple product IDs.
Include related entities in the response. Use a comma-separated list to specify multiple entities.
Get a price and related product
Use the include query parameter with the value product to include the related product in the response.
Return entities related to the specified price. Use a comma-separated list to specify multiple price IDs.
Include related entities in the response. Use a comma-separated list to specify multiple entities.
List prices for a product
Use the product_id query parameter to filter prices by product. Pass a comma-separated list to list prices for more than one product.
Events
product.created | Occurs when a product is created. |
price.created | Occurs when a price is created. |
product.updated | Occurs when a price is created and associated with a product. |