Skip to content

Public API v2: Volume Pricing

Quantity breaks and value breaks: the more a customer buys, the lower the price.

Scopes volume-pricing:read, volume-pricing:write
Plan Plans with Volume Pricing; otherwise 403
Takes effect Saved in the app; reaches the storefront at the next upload.

Every response has the same envelope (success, status, data, meta; see Responses). Returns below describes data. The examples are real calls; the rules were created disabled.

  • A table has 1–50 rows in ascending order. Ranges include both ends and must not overlap — [1–10] then [10–20] overlap; use [1–9], [10–20]. Only the last row may leave its upper bound null.
  • product_condition_type = by_variants goes with rule_type order or variant only.

What every read returns. Lists come back as [] when empty, never null.

idstringread-only

Rule id.

namestring

Rule name.

priorityinteger

Lower number wins; see Rules.

statusenum

disabled rules are kept but not applied. One of disabled, enabled.

CustomersCommon object

Who gets the rule.

Show fields

apply_toenum

all everyone, logged in or not · logged_in any logged-in customer · non_logged_in visitors who are not logged in · customer_ids the listed customers · customer_tags customers with any of the tags · company_location the listed B2B company locations. Accepted here: all, logged_in, non_logged_in, customer_ids, customer_tags, company_location.

customer_ids[string]

Used when apply_to is customer_ids; required and not empty then.

customer_tags[string]

Used when apply_to is customer_tags; required and not empty then.

company_location_ids[string]

Used when apply_to is company_location; required and not empty then.

exclude_fromenum

none (default) · customer_tags · customer_ids · company_location. Excluded customers stay out even when apply_to includes them. Accepted here: none, customer_tags, customer_ids, company_location.

exc_customer_tags[string]

Used when exclude_from is customer_tags.

exc_customers[string]

Used when exclude_from is customer_ids.

exc_company_location_ids[string]

Used when exclude_from is company_location.

ProductsCommon object

Which products the rule covers.

Show fields

product_condition_typeenum

all every product · by_ids · by_collections · by_tags · by_variants. Accepted here: all, by_ids, by_collections, by_tags, by_variants.

product_ids[string]

Used when the type is by_ids; required and not empty then.

product_collections[string]

Used when the type is by_collections; required and not empty then.

product_tags[string]

Used when the type is by_tags; required and not empty then.

variant_ids[string]

Used when the type is by_variants; required and not empty then.

exc_product_typeenum

none (default) or one of the types above: these products are left out. Accepted here: none, by_ids, by_collections, by_tags, by_variants.

exc_specific_products[string]

Used when exc_product_type is by_ids.

exc_product_collections[string]

Used when exc_product_type is by_collections.

exc_product_tags[string]

Used when exc_product_type is by_tags.

exc_product_variants[string]

Used when exc_product_type is by_variants.

MarketsCommon object

Which markets the rule covers.

Show fields

market_condition_typeenum

all (default) every market · by_ids the listed markets. Accepted here: all, by_ids.

market_ids[string]

Shopify market ids.

rule_typeenum

One of product, order, variant, collection.

rule_settingenum

One of quantity, value.

table_typeenum

One of full_range_discounts, from_discounts_with_prices_1, full_range_prices, from_prices_1, from_prices_2, from_discounts, from_discounts_with_prices_2, legacy_1, legacy_2, from_prices_and_total.

qty_table[object]

[] unless rule_setting is quantity.

Show fields

qty_frominteger

qty_tointeger or null

discount_typeenum

One of apply_fixed, decrease_fixed, decrease_percentage.

discount_valuestring

amount_table[object]

[] unless rule_setting is value.

Show fields

amount_fromstring

amount_tostring or null

discount_typeenum

One of apply_fixed, decrease_fixed, decrease_percentage.

discount_valuestring

ScheduleCommon object

When the rule applies.

Show fields

start_atstring

UTC date and time ending in Z; null or left out: starts at once.

end_atstring

After start_at; null or left out: never ends.

created_atstring or nullread-only

UTC, ending in Z.

updated_atstring or nullread-only

UTC, ending in Z.

The rule object
{
"id": "27213",
"name": "Buy more, save more",
"priority": 1,
"status": "disabled",
"apply_to": "customer_tags",
"customer_ids": [],
"customer_tags": [
"vip"
],
"company_location_ids": [],
"exclude_from": "none",
"exc_customer_tags": [],
"exc_customers": [],
"exc_company_location_ids": [],
"product_condition_type": "by_collections",
"product_ids": [],
"product_collections": [
"482901234567"
],
"product_tags": [],
"variant_ids": [],
"exc_product_type": "none",
"exc_specific_products": [],
"exc_product_collections": [],
"exc_product_tags": [],
"exc_product_variants": [],
"market_condition_type": "all",
"market_ids": [],
"rule_type": "product",
"rule_setting": "quantity",
"table_type": "from_prices_1",
"qty_table": [
{
"qty_from": 1,
"qty_to": 9,
"discount_type": "decrease_percentage",
"discount_value": "5.00"
},
{
"qty_from": 10,
"qty_to": null,
"discount_type": "decrease_percentage",
"discount_value": "10.00"
}
],
"amount_table": [],
"start_at": "2026-10-31T17:00:00.000Z",
"end_at": null,
"created_at": "2026-10-21T09:33:13.000Z",
"updated_at": "2026-10-21T09:33:13.000Z"
}

List rules

GET/api/v2/volume-pricing/rules

Scope volume-pricing:readCost 10

List rules, newest first, with their tables.

limitinteger

1–250, default 50. See Paging.

cursorstring

next_cursor or prev_cursor of the last page; leave out for the first page. Keep the same filters on every page.

filter_statusenum

One of disabled, enabled.

filter_namestring

Part of the name, any case. 1–200 characters.

filter_rule_settingenum

One of quantity, value.

filter_rule_typeenum

One of product, order, variant, collection.

data[Rule]

The rules of this page; [] when there are none.

meta.paginationobject

limit, next_cursor, prev_cursor and links to the next and previous pages.

cURL
curl -X GET "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules?limit=2&filter_name=Buy" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Create a rule

POST/api/v2/volume-pricing/rules

Scope volume-pricing:writeCost 11

Create a rule.

The body of POST /rules, PUT /rules/{id} and each element of bulk-upsert (add id to replace a rule). PUT replaces the whole rule: optional fields left out go back to their defaults. Fields not listed here are refused with 422.

namestringrequired

Rule name. 1–200 characters.

priorityintegerrequired

Lower number wins; see Rules. 0–99.

statusenumrequired

disabled rules are kept but not applied. One of disabled, enabled.

CustomersCommon objectrequired

Who gets the rule.

Show fields

apply_toenum

all everyone, logged in or not · logged_in any logged-in customer · non_logged_in visitors who are not logged in · customer_ids the listed customers · customer_tags customers with any of the tags · company_location the listed B2B company locations. Accepted here: all, logged_in, non_logged_in, customer_ids, customer_tags, company_location.

customer_ids[string]

Used when apply_to is customer_ids; required and not empty then.

customer_tags[string]

Used when apply_to is customer_tags; required and not empty then.

company_location_ids[string]

Used when apply_to is company_location; required and not empty then.

exclude_fromenum

none (default) · customer_tags · customer_ids · company_location. Excluded customers stay out even when apply_to includes them. Accepted here: none, customer_tags, customer_ids, company_location.

exc_customer_tags[string]

Used when exclude_from is customer_tags.

exc_customers[string]

Used when exclude_from is customer_ids.

exc_company_location_ids[string]

Used when exclude_from is company_location.

ProductsCommon objectrequired

Which products the rule covers.

Show fields

product_condition_typeenum

all every product · by_ids · by_collections · by_tags · by_variants. Accepted here: all, by_ids, by_collections, by_tags, by_variants.

product_ids[string]

Used when the type is by_ids; required and not empty then.

product_collections[string]

Used when the type is by_collections; required and not empty then.

product_tags[string]

Used when the type is by_tags; required and not empty then.

variant_ids[string]

Used when the type is by_variants; required and not empty then.

exc_product_typeenum

none (default) or one of the types above: these products are left out. Accepted here: none, by_ids, by_collections, by_tags, by_variants.

exc_specific_products[string]

Used when exc_product_type is by_ids.

exc_product_collections[string]

Used when exc_product_type is by_collections.

exc_product_tags[string]

Used when exc_product_type is by_tags.

exc_product_variants[string]

Used when exc_product_type is by_variants.

MarketsCommon object

Which markets the rule covers.

Show fields

market_condition_typeenum

all (default) every market · by_ids the listed markets. Accepted here: all, by_ids.

market_ids[string]

Shopify market ids.

rule_typeenumrequired

  • product: Count the quantity or value of all matching products in the cart together.
  • order: Count the whole cart.
  • variant: Count each variant on its own.

rule_settingenumrequired

  • quantity: Breaks by quantity; send qty_table.
  • value: Breaks by amount; send amount_table.

table_typeenumrequired

  • full_range_discounts: Table “Full range & discounts”.
  • from_discounts_with_prices_1: Table “From & discounts with discounted prices 1”.
  • full_range_prices: Table “Full range & discounted prices”.
  • from_prices_1: Table “From & discounted prices 1”.
  • from_prices_2: Table “From & discounted prices 2”.
  • from_discounts: Table “From & discounts”.
  • from_discounts_with_prices_2: Table “From & discounts with discounted prices 2”.
  • legacy_1, legacy_2: Tables “Legacy 1” and “Legacy 2”.

qty_table[object]

Required when rule_setting is quantity; rows ascend and do not overlap. 1–50 items.

Show fields

qty_fromintegerrequired

1–2,147,483,647.

qty_tointeger

null or left out: no upper bound, last row only. 1–2,147,483,647.

discount_typeenumrequired

  • apply_fixed: Fixed price: the price per item becomes the value.
  • decrease_fixed: Fixed-amount decrease.
  • decrease_percentage: Percentage decrease (at most 100).

discount_valuestringrequired

Decimal string, up to 2 decimals.

amount_table[object]

Required when rule_setting is value; rows ascend and do not overlap. 1–50 items.

Show fields

amount_fromstringrequired

amount_tostring

null or left out: no upper bound, last row only.

discount_typeenumrequired

  • apply_fixed: Fixed price: the price per item becomes the value.
  • decrease_fixed: Fixed-amount decrease.
  • decrease_percentage: Percentage decrease (at most 100).

discount_valuestringrequired

Decimal string, up to 2 decimals.

ScheduleCommon object

When the rule applies.

Show fields

start_atstring

UTC date and time ending in Z; null or left out: starts at once.

end_atstring

After start_at; null or left out: never ends.

dataRule

The new rule.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"name": "Buy more, save more",
"priority": 1,
"status": "disabled",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"product_condition_type": "by_collections",
"product_collections": [
"482901234567"
],
"rule_type": "product",
"rule_setting": "quantity",
"table_type": "from_prices_1",
"qty_table": [
{
"qty_from": 1,
"qty_to": 9,
"discount_type": "decrease_percentage",
"discount_value": "5"
},
{
"qty_from": 10,
"qty_to": null,
"discount_type": "decrease_percentage",
"discount_value": "10"
}
],
"start_at": "2026-10-31T17:00:00Z",
"end_at": null
}'

Get a rule

GET/api/v2/volume-pricing/rules/{id}

Scope volume-pricing:readCost 10

Get a rule.

idstringrequired

Rule id.

dataRule

The rule. An id that does not exist answers 404 RESOURCE_NOT_FOUND.

cURL
curl -X GET "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/27213" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Replace a rule

PUT/api/v2/volume-pricing/rules/{id}

Scope volume-pricing:writeCost 11

Replace a rule and its table; optional fields left out go back to their defaults.

idstringrequired

Rule id.

The same fields as Create a rule.

dataRule

The rule after the change.

cURL
curl -X PUT "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/27213" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"name": "Buy more, save more (updated)",
"priority": 2,
"status": "disabled",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"product_condition_type": "by_collections",
"product_collections": [
"482901234567"
],
"rule_type": "product",
"rule_setting": "quantity",
"table_type": "from_prices_1",
"qty_table": [
{
"qty_from": 1,
"qty_to": 9,
"discount_type": "decrease_percentage",
"discount_value": "5"
},
{
"qty_from": 10,
"qty_to": null,
"discount_type": "decrease_percentage",
"discount_value": "10"
}
],
"start_at": "2026-10-31T17:00:00Z",
"end_at": null
}'

Delete a rule

DEL/api/v2/volume-pricing/rules/{id}

Scope volume-pricing:writeCost 11

Delete a rule.

idstringrequired

Rule id.

data.idstring

Id of the deleted rule.

data.deletedboolean

true.

cURL
curl -X DELETE "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/27213" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Create or replace rules in bulk

POST/api/v2/volume-pricing/rules/bulk-upsert

Scope volume-pricing:writeCost ceil(10 + 0.4 × rules)

Create or replace up to 250 rules; each one succeeds or fails on its own.

See Bulk & idempotency.

rules[object]required

1–250 rules, each with the fields of Create a rule.

Show fields

idstring

Set it to replace that rule, as Replace a rule does; leave it out to create one.

data.results[object]

One entry per rule, in the order sent.

Show fields

indexinteger

Position of the rule in rules.

idstring

Rule id.

resultenum

created, updated or error.

errorobject

code and message, only when result is error.

data.summaryobject

total, succeeded, failed.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/bulk-upsert" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"name": "Buy more, save more B",
"priority": 1,
"status": "disabled",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"product_condition_type": "by_collections",
"product_collections": [
"482901234567"
],
"rule_type": "product",
"rule_setting": "quantity",
"table_type": "from_prices_1",
"qty_table": [
{
"qty_from": 1,
"qty_to": 9,
"discount_type": "decrease_percentage",
"discount_value": "5"
},
{
"qty_from": 10,
"qty_to": null,
"discount_type": "decrease_percentage",
"discount_value": "10"
}
],
"start_at": "2026-10-31T17:00:00Z",
"end_at": null
},
{
"name": "Buy more, save more (bulk)",
"priority": 1,
"status": "disabled",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"product_condition_type": "by_collections",
"product_collections": [
"482901234567"
],
"rule_type": "product",
"rule_setting": "quantity",
"table_type": "from_prices_1",
"qty_table": [
{
"qty_from": 1,
"qty_to": 9,
"discount_type": "decrease_percentage",
"discount_value": "5"
},
{
"qty_from": 10,
"qty_to": null,
"discount_type": "decrease_percentage",
"discount_value": "10"
}
],
"start_at": "2026-10-31T17:00:00Z",
"end_at": null,
"id": "27213"
}
]
}'

Delete rules in bulk

POST/api/v2/volume-pricing/rules/bulk-delete

Scope volume-pricing:writeCost ceil(10 + 0.4 × rules)

Delete up to 250 rules; an unknown id fails on its own.

See Bulk & idempotency.

ids[string]required

1–250 rule ids.

data.results[object]

One entry per id: index, id, result (deleted or error) and error (code, message) when it failed.

data.summaryobject

total, succeeded, failed.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/bulk-delete" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"27214",
"999999999"
]
}'

Upload rules to the storefront

POST/api/v2/volume-pricing/rules/upload

Scope volume-pricing:writeCost 20

Upload the rules to the storefront, as the app does.

The body is empty. See Upload.

data.statusenum

uploaded, or partial_success when some rules did not reach the storefront.

data.skippedobject

capacity_exceeded, write_failed and rule_id_range; see Upload.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/volume-pricing/rules/upload" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"