Become a Paddle partner
Join the Paddle partner program to read this content. You'll also get access to our partner API and agent tooling. Let us know a few details about your business to get started. Already a partner? Log in to view this page.
Products are the items that sellers offer to customers, including subscription plans, recurring addons, and one-time charges.
A seller needs one product with one related price before they can start billing.
When you create or update products and prices, you should create or update them in both sandbox and live. In your platform, we recommend maintaining a catalog and presenting one set of products, prices, and discounts to sellers. This means they don't need to think about data in Paddle.
We recommend creating products and prices using your platform agent. Your agent should ask a user for details about their product and how they want to bill for it, like monthly or annually. You can use an elicitation workflow to help your agent ask the right questions.
Before you begin
You should use the seller's API key to create products, prices, and discounts. Don't use your partner API key. Make sure to include your Paddle-PartnerID since this gives you write access to the import_meta object, which is read-only to non-partners.
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 image.
- At least one related price entity that describes how much and how often a product is billed.
You can create as many prices for a product as you want to describe all the ways it's billed.
For a full overview, see How Paddle works: a primer for partners
Overview
Create a product catalog in three steps:
- Create a product
Define the item that the seller offers to customers. - Create a price
Define how much and how often the product is billed. - Create discounts Optional
Define discounts that can be applied to the product.
Create a product
- Layer
- Your agent
- Authentication
- Seller API key
- Environment
- Sandbox, Live
Products describe the items that sellers offer to customers. For example, "Starter plan," "Pro plan," and "Enterprise plan" are products.
As well as a name, you must include a tax_category so Paddle can calculate sales tax correctly.
Since you need to create products in both sandbox and live accounts in Paddle, you need a way to match the Paddle entities to records on your side. Attach your own identifier using the import_meta.external_id field. You should use the same ID in sandbox and live.
Build a payload with the information about a product that you want to create, then send a POST request to the /products endpoint to create it. Make this request to both the sandbox and live endpoints.
If successful, Paddle returns a 201 with the created product entity. Extract the product ID for both sandbox and live, then store against the catalog record in your database. You'll need the product IDs in the next step to create a related price.
{ "name": "AeroEdit Pro", "tax_category": "standard", "description": "Designed for professional pilots, including all features in Basic plus compliance monitoring, route optimization, and third-party integrations.", "image_url": "https://paddle.s3.amazonaws.com/user/165042/bT1XUOJAQhOUxGs83cbk_pro.png", "import_meta": { "imported_from": "acme-platform", "external_id": "7e52d1b6-4876-4f93-a0ac-5054319c224f" }}{ "data": { "id": "pro_01gsz4t5hdjse780zja8vvr7jg", "name": "AeroEdit Pro", "tax_category": "standard", "type": "standard", "description": "Designed for professional pilots, including all features in Basic plus compliance monitoring, route optimization, and third-party integrations.", "image_url": "https://paddle.s3.amazonaws.com/user/165042/bT1XUOJAQhOUxGs83cbk_pro.png", "custom_data": null, "status": "active", "import_meta": { "imported_from": "acme-platform", "external_id": "7e52d1b6-4876-4f93-a0ac-5054319c224f" }, "created_at": "2026-02-23T12:43:46.605Z", "updated_at": "2026-04-05T15:53:44.687Z" }, "meta": { "request_id": "ccb21d76-1e13-4a5e-afb8-0f4c9f20ac07" }}Make sure to include your Paddle-PartnerID header so you can write to the import_meta field.
You can create one product at a time. Repeat the process for each product across both environments.
For more examples of the product configurations you can create, see Create products and prices
Create a price
- Layer
- Your agent
- Authentication
- Seller API key
- Environment
- Sandbox, Live
Prices are related to products and describe how much and how often a product is billed. For example, "Monthly" and "Annual" are prices for a product called "Pro plan."
Against prices, you can set:
- Name (public) and description (private)
- Unit price and currency
- Its billing cycle
- Country-specific price overrides
- Details about a trial period, including whether it's card-required or cardless, free or paid, and how long the trial should last
Description and unit price are required. You can come back to the other fields later.
Since you need to create prices in both sandbox and live accounts in Paddle, you need a way to match the Paddle entities to records on your side. Attach your own identifier using the import_meta.external_id field. You should use the same ID in sandbox and live.
Build a payload with the information about a price that you want to create, then send a POST request to the /prices endpoint to create it. Make this request to both the sandbox and live endpoints.
If successful, Paddle returns a 201 with the created price entity. Extract the price ID for both sandbox and live, then store against the catalog record in your database.
{ "description": "Monthly (per seat)", "name": "Monthly (per seat)", "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg", "unit_price": { "amount": "500", "currency_code": "USD" }, "billing_cycle": { "interval": "month", "frequency": 1 }, "import_meta": { "imported_from": "acme-platform", "external_id": "5f47ac42-df98-4f52-b4b0-ffdd27f3dcb1" }}{ "data": { "id": "pri_01hv0vax6rv18t4tamj848ne4d", "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg", "type": "standard", "description": "Monthly (per seat)", "name": "Monthly (per seat)", "billing_cycle": { "interval": "month", "frequency": 1 }, "trial_period": null, "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": { "imported_from": "acme-platform", "external_id": "5f47ac42-df98-4f52-b4b0-ffdd27f3dcb1" }, "created_at": "2026-04-09T07:14:38.424504286Z", "updated_at": "2026-04-09T07:14:38.424504359Z" }, "meta": { "request_id": "9e7f51e8-838b-4b2c-b0fa-d52d0593354c" }}You can create one price at a time. Repeat the process for each price across both environments.
For full examples of the price configurations you can create, see Create products and prices
Create discounts Optional
- Layer
- Your agent
- Authentication
- Seller API key
- Environment
- Sandbox, Live
Discounts let you reduce the amount that a customer has to pay. They can be percentage based, a flat amount, or an amount per unit.
You don't need to create a discount to start billing with Paddle, but sellers often create them while thinking about their products and prices. For example, they might want to offer a 50% discount on the first billing period to make their pricing more attractive.
When creating a discount, you can set:
- An internal description
- Type of the discount:
percentage,flat, orflat_per_seat. - Details of the amount, like the percentage or unit amount to deduct
- A code that customers can use to apply at checkout
- An expiry date
- A usage limit
It's most common for sellers to create percentage-based discounts with no expiry date and no usage limit.
Since you need to create discounts in both sandbox and live accounts in Paddle, you need a way to match the Paddle entities to records on your side. Attach your own identifier using the import_meta.external_id field. You should use the same ID in sandbox and live.
Build a payload with the information about a discount that you want to create, then send a POST request to the /discounts endpoint to create it. Make this request to both the sandbox and live endpoints.
If successful, Paddle returns a 201 with the created discount entity. Extract the discount ID for both sandbox and live, then store against the catalog record in your database.
{ "description": "20% welcome discount", "type": "percentage", "amount": "20", "enabled_for_checkout": true, "code": "WELCOME20", "recur": false, "import_meta": { "imported_from": "acme-platform", "external_id": "welcome-20" }}{ "data": { "id": "dsc_01hv0w9yq8m2k4n6p8r0s2t4v6", "status": "active", "description": "20% welcome discount", "enabled_for_checkout": true, "code": "WELCOME20", "type": "percentage", "amount": "20", "currency_code": null, "recur": false, "maximum_recurring_intervals": null, "usage_limit": null, "restrict_to": null, "expires_at": null, "times_used": 0, "custom_data": null, "import_meta": { "imported_from": "acme-platform", "external_id": "welcome-20" }, "created_at": "2026-04-09T07:14:38.424504286Z", "updated_at": "2026-04-09T07:14:38.424504359Z" }, "meta": { "request_id": "c1132253-4657-48f9-94fb-356273849bf0" }}You can create one discount at a time. Repeat the process for each discount across both environments.
For full examples of the discount configurations you can create, see Create and manage discounts