Some features are available through the Admin API and Store API but not on the standard Admin form. This chapter covers customer groups, regions, bulk operations, and developer exports.
Authentication:
- Admin API – Admin session cookie or bearer token
- Store API – Publishable API key header (
x-publishable-api-key)
Customer groups (B2B)
Scope rules to a Medusa customer group so VIP or wholesale buyers see different tiers.
Create a group-specific rule
Request:
POST /admin/quantity-pricing
Content-Type: application/jsonBody:
{
"product_id": "prod_01XXXXXXXX",
"min_qty": 10,
"max_qty": null,
"pricing_type": "fixed",
"price": 75,
"currency_code": "usd",
"customer_group_id": "cusgroup_01XXXXXXXX"
}cURL example:
curl -X POST "https://your-medusa-backend.com/admin/quantity-pricing" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"product_id": "prod_01XXXXXXXX",
"min_qty": 10,
"max_qty": null,
"pricing_type": "fixed",
"price": 75,
"currency_code": "usd",
"customer_group_id": "cusgroup_01XXXXXXXX"
}'Storefront – fetch tiers for logged-in B2B customer
Pass the customer’s customer_group_id from their profile:
GET /store/quantity-pricing?product_id=prod_01XXX&customer_group_id=cusgroup_01XXX&quantity=20¤cy_code=usdHeaders:
x-publishable-api-key: pk_your_publishable_keyGroup-specific rules score higher than generic rules when the group matches.
Regional overrides
Add region_id when creating or updating a rule for regional pricing.
Request:
POST /admin/quantity-pricing
Content-Type: application/jsonBody:
{
"product_id": "prod_01XXXXXXXX",
"min_qty": 5,
"max_qty": null,
"pricing_type": "percentage",
"price": 12,
"currency_code": "eur",
"region_id": "reg_01XXXXXXXX"
}Storefront:
GET /store/quantity-pricing?product_id=prod_01XXX®ion_id=reg_01XXX&quantity=10¤cy_code=eurBulk creation
For large catalogs, create rules with a script:
GET /admin/quantity-pricing?limit=100&offset=0POST /admin/quantity-pricingWorkflow:
- Export product IDs from your catalog
- Loop products and
POSTthe same tier template per product - Paginate with
offsetto audit all rules
Note Rules are per product, not per collection. Loop all products in a collection and apply the same template to each.
Admin API reference
| Method | Path | Description |
|---|---|---|
GET |
|
List rules (filters + pagination) |
POST |
|
Create rule |
GET |
|
Get one rule |
PUT |
|
Update rule |
DELETE |
|
Delete rule |
GET |
|
Variant catalog prices |
List filters (GET)
| Parameter | Description |
|---|---|
|
Filter by product |
|
Filter by variant |
|
Filter by currency |
|
Filter by group |
|
Filter by region |
|
Page size (1-100, default 50) |
|
Pagination offset |
Create rule – full body reference
| Field | Required | Type | Description |
|---|---|---|---|
|
Yes |
string |
Medusa product ID |
|
No |
string \ |
null Null = all variants |
|
Yes |
number |
Minimum quantity (≥ 1) |
|
No |
number \ |
null Null = open-ended (51+) |
|
No |
string |
|
|
Yes |
number |
Tier value (positive) |
|
Yes |
string |
ISO 4217, e.g. |
|
No |
string \ |
null, B2B segment |
|
No |
string \ |
null, Regional override |
|
No |
number \ |
null, List price fallback for discount tiers |
Create example – bounded tier
POST /admin/quantity-pricing{
"product_id": "prod_01XXXXXXXX",
"min_qty": 1,
"max_qty": 10,
"pricing_type": "fixed",
"price": 100,
"currency_code": "inr"
}Create example – open-ended tier (51+)
Set "max_qty": null:
{
"product_id": "prod_01XXXXXXXX",
"min_qty": 51,
"max_qty": null,
"pricing_type": "fixed",
"price": 80,
"currency_code": "usd"
}Update rule
PUT /admin/quantity-pricing/qprice_01XXXXXXXX{
"price": 85,
"min_qty": 51
}Delete rule
DELETE /admin/quantity-pricing/qprice_01XXXXXXXXStore API reference
GET /store/quantity-pricing| Parameter | Required | Description |
|---|---|---|
|
Yes |
Product to query |
|
No |
Variant filter |
|
No |
Filter / calculation currency |
|
No |
Returns |
|
No |
Override catalog for discount tiers |
|
No |
B2B segment |
|
No |
Regional context |
Example with calculated price:
GET /store/quantity-pricing?product_id=prod_01XXX¤cy_code=usd&quantity=25Response snippet:
{
"quantity_prices": [],
"calculated_price": {
"unit_price": 90,
"quantity": 25,
"currency_code": "usd",
"rule_id": "qprice_02...",
"pricing_type": "fixed",
"line_total": 2250
}
}Workflows (developer)
Safe create/update/delete with rollback compensation:
import {
createQuantityPricingRuleWorkflow,
updateQuantityPricingRuleWorkflow,
deleteQuantityPricingRuleWorkflow,
} from "@webbycrown/medusa-quantity-pricing-rules/workflows"Cart / checkout helper
import {
resolveQuantityUnitPrice,
PRICING_ENGINE_MODULE,
} from "@webbycrown/medusa-quantity-pricing-rules"
const unitPrice = await resolveQuantityUnitPrice(container, {
product_id: "prod_01...",
variant_id: "variant_01...",
quantity: 25,
currency_code: "inr",
})Use in custom add-to-cart or checkout flows when a tier applies.
Package exports
| Export | Purpose |
|---|---|
|
Container key ( |
|
Resolve tier unit price |
|
Batch catalog prices |
|
Create / update / delete workflows |