Product Price Tables
A Product Price Table list allows owners/merchants to set custom prices for products through discounts applied at different levels: storewide, specific categories, or individual products. Additionally, it's possible to define business rules such as minimum cart value and minimum product quantity for authenticated customers associated with the price list.
This resource is available in the unstable, v1, and 2025-03 API versions. Unless an endpoint is explicitly marked otherwise, the request and response contract is the same in all three versions.
Price calculation follows the most specific configured rule: a product variant exception takes precedence over a category exception, and a category exception takes precedence over default_discount. A fixed variant price, when provided, is used instead of its percentage discount.
All path parameters are required. id identifies the price table except when it appears after /categories/, /product-variants/, or /customers/, where it identifies the category, product variant, or customer respectively. IDs are represented as strings in request and response bodies, even when they contain only digits.
Properties
| Property | Explanation | Type | Required in POST |
|---|---|---|---|
| id | The unique identifier for the price table | String | false |
| verification_code | Unique Code that identifies a price table in the client self-registration link | UUID | false |
| store_id | The unique identifier of the store that owns this price table | String | false |
| name | Name of the price table | String | true |
| default_discount | Discount percentage applied to all existing products in the store | String | true |
| cart_minimum_price | Minimum cart value required to apply this price table | String | false |
| cart_minimum_quantity | Minimum quantity of products required in cart to apply this price table | Integer | false |
| categories | Category-specific discount exceptions. See Category exceptions. | Array | false |
| product_variants | Product-variant discount or fixed-price exceptions. See Product variant exceptions. | Array | false |
| auto_approve_customers | Flag to indicate automatic customer association approval (default true in creation) | Boolean | false |
| active | Whether the price table is currently active and can be applied | Boolean | false |
| created_at | Timestamp when the price table was created in ISO 8601 format | Timestamp | false |
| updated_at | Timestamp when the price table was last updated in ISO 8601 format | Timestamp | false |
| has_categories | Indicates if this price table has specific category configurations | Boolean | false |
| has_products_variants | Indicates if this price table has specific product/variant configurations | Boolean | false |
| has_customers | Indicates if this price table has specific customer associations | Boolean | false |
Endpoints
POST /products/price-tables
Create a specific product price table
POST /products/price-tables
{
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"categories": [
{
"id": "135796548",
"discount": "15.00"
},
{
"id": "542635852",
"discount": "30.00"
}
],
"product_variants": [
{
"product_id": "84682548",
"product_variant_id": "234098766",
"discount": "10.00",
"price": null
},
{
"product_id": "34567892",
"product_variant_id": "38946272",
"discount": "7.00",
"price": null
}
]
}
HTTP/1.1 201 OK
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-17T15:12:39.396Z",
"has_categories": true,
"has_products_variants": true,
"has_customers": false
}
HTTP/1.1 400 Bad Request
{
"code": 400,
"message": "Bad Request",
"description": "Invalid input parameters",
"errors": {
"name": ["The name field is required."],
"default_discount": ["The default_discount field is required"]
}
}
GET /products/price-tables/{id}
Return a specific product price table
GET /products/price-tables/1
HTTP/1.1 200 OK
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-17T15:12:39.396Z",
"has_categories": true,
"has_products_variants": true,
"has_customers": true
}
GET /products/price-tables
Return a paginated list of product price tables
| Parameter | Explanation |
|---|---|
| page | Page number. Optional; defaults to 1; minimum 1. |
| per_page | Results per page. Optional; defaults to 10; minimum 1; maximum 10. |
GET /products/price-tables?page=1&per_page=10
HTTP/1.1 200 OK
{
"total": 2,
"page": 1,
"price_tables": [
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-17T15:12:39.396Z",
"has_categories": true,
"has_products_variants": true,
"has_customers": true
},
{
"id": "2",
"verification_code": "4f3ba8f8-5698-47d8-9117-547165c42041",
"store_id": "3776871",
"name": "Special Price Table",
"default_discount": "15.00",
"cart_minimum_price": "399.00",
"cart_minimum_quantity": 15,
"auto_approve_customers": false,
"active": true,
"created_at": "2025-11-20T12:47:13.786Z",
"updated_at": "2025-11-20T12:47:13.786Z",
"has_categories": false,
"has_products_variants": true,
"has_customers": true
}
]
}
PUT /products/price-tables/{id}
Update a specific product price table
PUT /products/price-tables/1
{
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"categories": [
{
"id": "135796548",
"discount": "50.00"
}
],
"product_variants": [
{
"product_id": "84682548",
"product_variant_id": "234098766",
"discount": "15.00",
"price": "487.50"
},
{
"product_id": "34567892",
"product_variant_id": "38946272",
"discount": "20.00",
"price": "699.90"
}
]
}
HTTP/1.1 200 OK
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-27T12:15:48.654Z",
"has_categories": true,
"has_products_variants": true,
"has_customers": false
}
HTTP/1.1 400 Bad Request
{
"code": 400,
"message": "Bad Request",
"description": "Invalid input parameters",
"errors": {
"name": ["The name field is required."],
"default_discount": ["The default_discount field is required"]
}
}
FAQ
How to clear all category exceptions of a Product Price Table
If you would like to update to clear all categories in a Product Price table, the following body should be sent:
{
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"categories": [],
"product_variants": [
{
"product_id": "84682548",
"product_variant_id": "234098766",
"discount": "15.00",
"price": "487.50"
},
{
"product_id": "34567892",
"product_variant_id": "38946272",
"discount": "20.00",
"price": "699.90"
}
]
}
HTTP/1.1 200 OK
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-27T12:15:48.654Z",
"has_categories": false,
"has_products_variants": true,
"has_customers": false
}
How to clear all product variant exceptions of a Product Price Table
If you would like to update to clear all product variants in a Product Price table, the following body should be sent:
{
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"categories": [
{
"id": "135796548",
"discount": "50.00"
}
],
"product_variants": []
}
HTTP/1.1 200 OK
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "10.00",
"cart_minimum_price": "350.00",
"cart_minimum_quantity": 20,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-27T12:15:48.654Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": false
}
How to set up discounts for specific categories
See Category exceptions.
How to set up discounts for specific products and variants
How to associate or disassociate a client in a specific price table?
Product Price Table Categories
This documentation explains how to configure specific discounts for a category within a price table, allowing merchants to set custom pricing rules that apply to all products within selected categories.
Properties
| Property | Explanation | Type | Required |
|---|---|---|---|
| id | The unique identifier for the category | String | true |
| discount | Discount that will be applied to products that have the related category | String | true |
Endpoints
PUT /products/price-tables/{id}/categories
Updates one or more category exceptions in a product price table list.
PUT /products/price-tables/1/categories
[
{
"id": "1238746858",
"discount": "20.00"
},
{
"id": "3896583258",
"discount": "0.00"
}
]
HTTP/1.1 204 No Content
{}
GET /products/price-tables/{id}/categories/{id}
Gets a specific category exception from a product price table.
GET /products/price-tables/1/categories/1238746858
HTTP/1.1 200 Ok
{
"price_table": {
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true,
"categories": [
{
"id": "1238746858",
"discount": "20.00"
}
]
}
}
GET /products/price-tables/{id}/categories
Returns a paginated list of categories from the product price table.
| Parameter | Explanation |
|---|---|
| page | Page number. Optional; defaults to 1; minimum 1. |
| per_page | Results per page. Optional; defaults to 50; minimum 1; maximum 50. |
GET /products/price-tables/1/categories?page=1&per_page=50
HTTP/1.1 200 Ok
{
"total": 2,
"page": 1,
"price_table": {
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true,
"categories": [
{
"id": "1238746858",
"discount": "20.00"
},
{
"id": "3896583258",
"discount": "0.00"
}
]
}
}
DELETE /products/price-tables/{id}/categories/{id}
Delete a specific category exception from a product price table.
DELETE /products/price-tables/1/categories/1238746858
HTTP/1.1 204 No Content
{}
FAQ
How to clear all category exceptions of a Product Price Table
If you would like to update to clear all categories in a Product Price table, the following body should be sent:
[]
HTTP/1.1 204 No Content
{}
Product Price Table Products Variants
This documentation explains how to configure specific discounts for individual products and their variants within a product price table, allowing merchants to set custom pricing rules at the product and variant level.
Properties
| Property | Explanation | Type | Required |
|---|---|---|---|
| product_id | The unique identifier for the product | String | true |
| product_variant_id | The unique identifier for the product variant | String | true |
| discount | Discount that will be applied to product variant | String | true |
| price | Fixed price that will be applied to product variant | String | false |
Endpoints
PUT /products/price-tables/{id}/product-variants
Updates one or more products variants exceptions in a product price table.
PUT /products/price-tables/1/product-variants
[
{
"product_id": "136548284",
"product_variant_id": "136548285",
"discount": "20.00",
"price": "150.00"
},
{
"product_id": "246818282",
"product_variant_id": "246818285",
"discount": "10.00",
"price": "250.00"
},
{
"product_id": "358965478",
"product_variant_id": "358965484",
"discount": "0.00",
"price": "350.00"
}
]
HTTP/1.1 204 No Content
{}
GET /products/price-tables/{id}/product-variants/{id}
Gets a specific product variant exception from a product price table.
GET /products/price-tables/1/product-variants/136548285
HTTP/1.1 200 Ok
{
"price_table": {
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true,
"product_variants": [
{
"product_id": "136548284",
"product_variant_id": "136548285",
"discount": "20.00",
"price": "150.00"
}
]
}
}
GET /products/price-tables/{id}/product-variants
Returns a paginated list of products variants from the product price table.
| Parameter | Explanation |
|---|---|
| page | Page number. Optional; defaults to 1; minimum 1. |
| per_page | Results per page. Optional; defaults to 50; minimum 1; maximum 50. |
GET /products/price-tables/1/product-variants?page=1&per_page=50
HTTP/1.1 200 Ok
{
"total": 3,
"page": 1,
"price_table": {
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true,
"product_variants": [
{
"product_id": "136548284",
"product_variant_id": "136548285",
"discount": "20.00",
"price": "150.00"
},
{
"product_id": "246818282",
"product_variant_id": "246818285",
"discount": "10.00",
"price": "250.00"
},
{
"product_id": "358965478",
"product_variant_id": "358965484",
"discount": "0.00",
"price": "350.00"
}
]
}
}
DELETE /products/price-tables/{id}/product-variants/{id}
Delete a specific product variant exception from a product price table.
DELETE /products/price-tables/1/product-variants/136548285
HTTP/1.1 204 No Content
{}
FAQ
How to use only the percentage discount
If you would like to use only percentage discount for product variant in a Product Price table, the following body should be sent:
[
{
"product_id": "136548284",
"product_variant_id": "136548285",
"discount": "20.00",
"price": null
}
]
HTTP/1.1 204 No Content
{}
How to clear all products variants exceptions of a Product Price Table
If you would like to update to clear all products variants in a product price table, the following body should be sent:
[]
HTTP/1.1 204 No Content
{}
Product Price Table Customers
This documentation explains how to associate and disassociate customers with a product price table, allowing merchants to control which customers have access to specific pricing rules and discounts.
Customer Properties
| Property | Explanation | Type | Required |
|---|---|---|---|
| id | The unique identifier for the customer. Required in customer ID request arrays. | String | true |
| created_at | Timestamp when the customer was associated to the price table in ISO 8601 format. | Timestamp | false |
| approved_at | Timestamp when the association was approved, or null while approval is pending. | Timestamp | false |
Endpoints
PUT /products/price-tables/{id}/customers
Adds one or more customers to a product price table. This operation is incremental (append) — customers sent in each request are added to the existing associations without removing previously linked customers.
Limits and constraints:
- Maximum of 10,000 customers per request.
- A customer can only be associated with one price table at a time. If any customer in the payload is already associated with a price table, the entire batch fails with a
409 Conflicterror. Remove the conflicting customers from the payload or disassociate them from their current price table before retrying.
PUT /products/price-tables/1/customers
["123456789", "654987321", "456897321"]
HTTP/1.1 204 No Content
{}
Error responses
HTTP/1.1 409 Conflict — One or more customers are already associated with a price table. The errors field lists the conflicting customer IDs.
{
"code": 409,
"message": "Conflict",
"description": "Customers are associated with a product price table.",
"errors": [
{
"customers": ["123456789"]
}
]
}
POST /products/price-tables/{id}/approve-customers
Approve one or more customers in a product price table.
POST /products/price-tables/1/approve-customers
["123456789", "654987321", "456897321"]
HTTP/1.1 204 No Content
{}
GET /products/price-tables/customers/{id}
Returns a paginated list of product price tables associated with a customer.
| Parameter | Explanation |
|---|---|
| page | Page number. Optional; defaults to 1; minimum 1. |
| per_page | Results per page. Optional; defaults to 10; minimum 1; maximum 10. |
GET /products/price-tables/customers/123456789?page=1&per_page=10
HTTP/1.1 200 Ok
{
"total": 1,
"page": 1,
"price_tables": [
{
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true
}
]
}
GET /products/price-tables/{id}/customers
Returns a paginated list of customers from the product price table.
| Parameter | Explanation |
|---|---|
| page | Page number. Optional; defaults to 1; minimum 1. |
| per_page | Results per page. Optional; defaults to 50; minimum 1; maximum 50. |
GET /products/price-tables/1/customers?page=1&per_page=50
HTTP/1.1 200 Ok
{
"total": 4,
"page": 1,
"price_table": {
"id": "1",
"verification_code": "5a23d45e-52b4-470f-8cf8-ff959b9ef0fa",
"store_id": "3776871",
"name": "Price Table",
"default_discount": "7.00",
"cart_minimum_price": "250.00",
"cart_minimum_quantity": 30,
"auto_approve_customers": true,
"active": true,
"created_at": "2025-11-17T15:12:39.396Z",
"updated_at": "2025-11-23T12:48:52.132Z",
"has_categories": true,
"has_products_variants": false,
"has_customers": true,
"customers": [
{
"id": "123456789",
"created_at": "2026-04-10T19:10:18.795Z",
"approved_at": "2026-04-22T17:56:42.924Z"
},
{
"id": "987654321",
"created_at": "2026-04-11T19:10:18.795Z",
"approved_at": "2026-04-22T17:56:42.924Z"
},
{
"id": "789456321",
"created_at": "2026-04-12T19:10:18.795Z",
"approved_at": "2026-04-22T17:56:42.924Z"
},
{
"id": "654987321",
"created_at": "2026-04-13T19:10:18.795Z",
"approved_at": "2026-04-22T17:56:42.924Z"
}
]
}
}
DELETE /products/price-tables/{id}/customers/{id}
Delete a specific customer from a product price table.
DELETE /products/price-tables/1/customers/987654321
HTTP/1.1 204 No Content
{}
FAQ
How do I bulk-associate customers with a price table?
Use PUT /products/price-tables/{id}/customers with batches of up to 10,000 customer IDs per request. Each request appends the provided customers to the price table — existing associations are preserved.
Before sending a batch, make sure none of the customers are already associated with a price table (including the target one). If any customer in the payload has an existing association, the entire batch is rejected with a 409 Conflict error listing the conflicting IDs. You must remove those customers from the payload or disassociate them first using DELETE /products/price-tables/{id}/customers/{customerId}, then retry.
What happens if I send the same customer in multiple requests?
A customer can only be associated with one price table at a time. If a customer is already linked to any price table and you include them in a new request, the entire batch fails with a 409 Conflict response. To move a customer to a different price table, first delete their association using DELETE /products/price-tables/{id}/customers/{customerId}, then add them to the new table.
Product visibility by Price Table (unstable only)
These endpoints control who can discover and access a product according to the customer's Price Table. They are available only in the unstable API version and require the store to have Product Visibility enabled.
The visibility configuration has three scopes:
| Scope | Behavior |
|---|---|
hidden | Hides the product from every audience. price_table_ids should be empty. |
all | Makes the product available to customers associated with any Price Table. price_table_ids should be empty. |
selected | Makes the product available only to customers associated with the Price Tables in price_table_ids. |
exclusive controls access for customers without a Price Table. When false, they can also access the product; when true, access is exclusive to the audience selected by scope. The default product behavior is equivalent to scope: "all", exclusive: false, and an empty price_table_ids array.
Visibility properties
| Property | Explanation | Type | Required in PUT |
|---|---|---|---|
| product_id | Product whose visibility is configured. Returned by the API; provided as the required path parameter. | Integer | false |
| scope | Visibility audience to configure. Accepted values: hidden, all, or selected. The response calls this property mode. | String | true |
| mode | Current visibility scope. Returned by GET and PUT; not accepted in the request body. | String | false |
| exclusive | Whether the product must be hidden from customers without a Price Table. | Boolean | true |
| price_table_ids | Price Tables that can access the product when scope is selected. Each ID must contain digits only and must be serialized as a string, for example "123"; JSON numbers such as 123 are not accepted. The response also returns every ID as a string. Send an empty array for hidden or all. | Array of numeric strings | false |
Both requests and responses use strings for price_table_ids. For example, use ["1", "2"], never [1, 2].
GET /products/{product_id}/price-tables/visibility
Returns the product's explicit Price Table visibility configuration. Requires the read_products permission.
GET /products/42/price-tables/visibility
HTTP/1.1 200 OK
{
"product_id": 42,
"mode": "selected",
"exclusive": true,
"price_table_ids": ["1", "2"]
}
Returns 404 Not Found when the product has no explicit visibility configuration and 405 Method Not Allowed when Product Visibility is not enabled for the store.
PUT /products/{product_id}/price-tables/visibility
Creates or replaces the product's Price Table visibility configuration. Requires the write_products permission. Sending the default configuration (all, exclusive: false) removes any stored override and restores the default product behavior.
PUT /products/42/price-tables/visibility
{
"scope": "selected",
"exclusive": true,
"price_table_ids": ["1", "2"]
}
HTTP/1.1 200 OK
{
"product_id": 42,
"mode": "selected",
"exclusive": true,
"price_table_ids": ["1", "2"]
}
Returns 400 Bad Request for a missing or invalid scope or exclusive, or when price_table_ids contains values other than numeric strings. Returns 422 Unprocessable Entity when any supplied Price Table ID does not belong to the store, and 405 Method Not Allowed when Product Visibility is not enabled.
DELETE /products/{product_id}/price-tables/visibility
Deletes the explicit visibility configuration and restores the product's default visibility (all, non-exclusive). Requires the write_products permission.
DELETE /products/42/price-tables/visibility
HTTP/1.1 204 No Content
Returns 404 Not Found when no explicit configuration exists and 405 Method Not Allowed when Product Visibility is not enabled for the store.