# 🔗Public APIs for Volume Pricing (VP)

## 🔐 Get Your Access Key

After installing the **BSS B2B Solution** Shopify app:

1. Open the **Public API** page
2. Click **Copy** to copy your **Access Key**

Use this key in request bodies shown below.

***

## 🧱 Rule Model — Fields & Enums

Understand these fields before calling the endpoints:

**priority**\
Determines which rule takes precedence over others.

**status**

```
0: inactive
1: active
```

**apply\_to**

```
0: All customers
1: Logged-in customers
2: Not-logged-in customers
3: Specific customers
4: Customer tags
```

**exclude\_customer**

```
0: None
1: Customer tags
2: Specific customers
```

**product\_condition\_type**

```
0: All products
1: Specific products
2: Product collections
3: Product tags
4: Specific variants
```

**exc\_product\_type**

```
0: None
1: Specific products
2: Product collections
3: Product tags
```

**rule\_setting**

```
0: Quantity break
1: Amount break
```

**qb\_table\_type**

```
0: Full range & Discounts
1: Full range & Discounted prices
2: From & Discounts
3: From & Discounted prices 1
4: From & Discounted prices 2
5: From & Discounts with Discounted prices 1
6: From & Discounts with Discounted prices 2
7: Legacy 1
8: Legacy 2
```

> **Note**
>
> * When you **get rules by domain or ID**, `rule_setting` appears in the response to indicate whether a rule is **Quantity-based** or **Volume-based**.
> * When you **create/update** a rule, `rule_setting` will be **Quantity-based by default** (create/update **Volume-based** is **not** supported as of now).

***

### 📊 `qty_table` — Quantity Settings

**rule\_type**

```
0: Minimum Product Qty
1: Minimum Order Qty
2: Minimum Variant Qty
```

**Behavior explanations (verbatim logic):**

* **Minimum Product Qty**\
  If one order contains the selected products and the number of each product meets the quantity break ranges, the price of the product will be discounted accordingly.\
  **Example:**\
  Products **A** (variants **A1, A2**) and **B** (variants **B1, B2**) are selected.\
  Ranges: 0–5 (−10%), 6–10 (−15%).\
  If a customer buys **3×A1, 6×A2, 4×B1** → Total **A** qty = **9** → **A** gets **−15%**, **B** gets **−10%**.\
  If qty is not within ranges, original prices apply.
* **Minimum Order Qty**\
  If one order contains the selected products and the **total number of those products** meets the ranges, they will be discounted accordingly.\
  **Example:**\
  Products **A, B**; A has **A1, A2**, B has **B1, B2**.\
  Ranges: 0–5 (−10%), 6–10 (−15%), 11–20 (−20%).\
  If customer buys **3×A1, 6×A2, 4×B1** → Total **A+B** qty = **13** → **A & B** get **−20%**.\
  If qty not within ranges, original prices apply.
* **Minimum Variant Qty**\
  If one order contains the selected products and the **number of variants** meets the ranges, those **variants** are discounted accordingly.\
  **Example:**\
  Products **A, B**; variants **A1, A2, B1, B2**.\
  Ranges: 0–5 (−10%), 6–10 (−15%), 11–20 (−20%).\
  If customer buys **3×A1, 6×A2, 4×B1** → **A1 & B1** get **−10%**, **A2** gets **−15%**.\
  If qty not within ranges, original prices apply.

**Range fields**

* `qty_from`: lower bound of a range
* `qty_to`: upper bound of a range

**discount\_type**

```
0: Apply a price to selected products
1: Decrease a fixed amount of the original prices of selected products
2: Decrease the original prices of selected products by a percentage (%)
```

***

## 📥 Rule Endpoints

### Get rules by domain

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/get-by-domain
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{ 
  "domain": "abc.myshopify.com", 
  "accessKey": "xxx" 
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "rules": [
    {
      "id": 9792,
      "shop_id": 9204,
      "name": "sencond1",
      "priority": 0,
      "rule_type": 2,
      "rule_setting": 0,
      "status": 1,
      "apply_to": 0,
      "customer_ids": [],
      "customer_tags": [],
      "product_condition_type": 0,
      "product_ids": [],
      "product_collections": [],
      "product_tags": [],
      "varianst_id": [],
      "exc_product_type": 1,
      "exc_specific_products": [6669588136111, 6669469352111],
      "exc_product_collections": [],
      "exc_product_tags": [],
      "published_at": null,
      "unpublished_at": null,
      "exc_customer_tags": "",
      "exclude_from": 0,
      "exc_customers": "",
      "qb_table_type": 3,
      "createdAt": "2023-03-09T02:27:26.000Z",
      "updatedAt": "2023-05-30T04:29:18.000Z",
      "qbRuleQtyTables": [
        {
          "id": 33022,
          "rule_id": 9792,
          "qty_from": 1,
          "qty_to": 4,
          "discount_type": 0,
          "discount_value": 10,
          "createdAt": "2023-05-26T04:26:21.000Z",
          "updatedAt": "2023-05-26T04:26:21.000Z"
        },
        {
          "id": 33023,
          "rule_id": 9792,
          "qty_from": 6,
          "qty_to": 8,
          "discount_type": 1,
          "discount_value": 10,
          "createdAt": "2023-05-26T04:26:21.000Z",
          "updatedAt": "2023-05-26T04:26:21.000Z"
        }
      ],
      "abRuleQtyTables": []
    },
    {
      "id": 9909,
      "shop_id": 9204,
      "name": "sencond2",
      "priority": 0,
      "rule_type": 2,
      "rule_setting": 0,
      "status": 1,
      "apply_to": 0,
      "customer_ids": [],
      "customer_tags": [],
      "product_condition_type": 4,
      "product_ids": [],
      "product_collections": [],
      "product_tags": [],
      "variants_ids": [4908909872990, 8799990863829],
      "exc_product_type": 0,
      "exc_specific_products": [],
      "exc_product_collections": [],
      "exc_product_tags": [],
      "published_at": null,
      "unpublished_at": null,
      "exc_customer_tags": null,
      "exclude_from": 0,
      "exc_customers": null,
      "qb_table_type": 0,
      "createdAt": "2023-03-13T09:39:48.000Z",
      "updatedAt": "2023-05-26T04:26:21.000Z",
      "qbRuleQtyTables": [
        {
          "id": 33024,
          "rule_id": 9909,
          "qty_from": 1,
          "qty_to": 4,
          "discount_type": 0,
          "discount_value": 10,
          "createdAt": "2023-05-26T04:26:21.000Z",
          "updatedAt": "2023-05-26T04:26:21.000Z"
        },
        {
          "id": 33025,
          "rule_id": 9909,
          "qty_from": 6,
          "qty_to": 8,
          "discount_type": 1,
          "discount_value": 11,
          "createdAt": "2023-05-26T04:26:21.000Z",
          "updatedAt": "2023-05-26T04:26:21.000Z"
        }
      ],
      "abRuleQtyTables": []
    }
  ]
}
```

{% endcode %}

***

### Get rules by ID

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/get-by-id
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "id": 46
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "rule": {
    "id": 46,
    "name": "sencond1",
    "priority": 0,
    "status": 1,
    "apply_to": 0,
    "customer_ids": [],
    "customer_tags": [],
    "exclude_from": 0,
    "exc_customers": [],
    "exc_customer_tags": [],
    "product_condition_type": 0,
    "product_ids": [],
    "product_collections": [],
    "product_tags": [],
    "variant_ids": [],
    "exc_product_type": 3,
    "exc_specific_products": [],
    "exc_product_tags": ["babytshirt", "gaminggear"],
    "exc_product_collections": [],
    "rule_setting": 0,
    "rule_type": 2,
    "qty_table": [
      {
        "id": 33022,
        "rule_id": 9792,
        "qty_from": 1,
        "qty_to": 4,
        "discount_type": 0,
        "discount_value": 10,
        "createdAt": "2023-05-26T04:26:21.000Z",
        "updatedAt": "2023-05-26T04:26:21.000Z"
      },
      {
        "id": 33023,
        "rule_id": 9792,
        "qty_from": 6,
        "qty_to": 8,
        "discount_type": 1,
        "discount_value": 10,
        "createdAt": "2023-05-26T04:26:21.000Z",
        "updatedAt": "2023-05-26T04:26:21.000Z"
      }
    ],
    "amount_table": [],
    "qb_table_type": 3,
    "createdAt": "2023-03-09T02:27:26.000Z",
    "updatedAt": "2023-05-30T04:29:18.000Z"
  }
}
```

{% endcode %}

***

### Create or Update a single rule

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/save
```

**Headers**

```
Content-Type: application/json
```

**Rules**

* If there’s **no `id`**, a **new rule** is created.
* If `id` is present, that rule is **updated**.
* If `"product_condition_type" = 4` (**specific variants**), then **`rule_type` must not be `0`** (minimum product qty).

**Body**

{% code expandable="true" %}

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "rule": {
    "id": 11,
    "name": "sencond1",
    "priority": 0,
    "status": 1,
    "apply_to": 0,
    "customer_ids": [],
    "customer_tags": [],
    "exclude_from": 0,
    "exc_customers": [],
    "exc_customer_tags": [],
    "product_condition_type": 0,
    "product_ids": [],
    "product_collections": [],
    "product_tags": [],
    "variant_ids": [],
    "exc_product_type": 1,
    "exc_specific_products": [4766764787771, 4766764787752],
    "exc_product_tags": [],
    "exc_product_collections": [],
    "rule_setting": 0,
    "rule_type": 2,
    "qty_table": [
      { "qty_from": 1, "qty_to": 4, "discount_type": 0, "discount_value": 10 },
      { "qty_from": 6, "qty_to": 8, "discount_type": 1, "discount_value": 10 }
    ],
    "amount_table": [],
    "qb_table_type": 1
  }
}
```

{% endcode %}

**Response 200**

```json
{
  "success": true,
  "ruleId": 11,
  "message": "Updated the rule successfully"
}
```

***

### Create or Update multiple rules

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/bulk-save
```

**Headers**

```
Content-Type: application/json
```

**Rules**

* If a rule **has no `id`**, it will be **created**.
* If a rule **has an `id`**, it will be **updated**.
* If an `id` is **incorrect/not found** inside the batch, those rules will **not** be created/updated.

**Body (excerpt)**

{% code expandable="true" %}

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "rules": [
    {
      "name": "sencond1",
      "priority": 0,
      "status": 1,
      "apply_to": 0,
      "product_condition_type": 0,
      "customer_ids": [],
      "customer_tags": [],
      "product_ids": [],
      "product_collections": [],
      "product_tags": [],
      "variant_ids": [],
      "exc_customer_tags": "",
      "exclude_from": 0,
      "exc_customers": "",
      "exc_product_type": 0,
      "exc_specific_products": [],
      "exc_product_tags": [],
      "exc_product_collections": [],
      "rule_type": 2,
      "rule_setting": 0,
      "qty_table": [
        { "qty_from": 1, "qty_to": 4, "discount_type": 0, "discount_value": 10 },
        { "qty_from": 6, "qty_to": 8, "discount_type": 1, "discount_value": 10 }
      ],
      "amount_table": [],
      "qb_table_type": 4
    },
    {
      "id": 9909,
      "name": "sencond2",
      "priority": 0,
      "status": 1,
      "apply_to": 0,
      "product_condition_type": 0,
      "customer_ids": [],
      "customer_tags": [],
      "product_ids": [],
      "product_collections": [],
      "product_tags": [],
      "variant_ids": [],
      "exc_customer_tags": "",
      "exclude_from": 0,
      "exc_customers": "",
      "exc_product_type": 2,
      "exc_specific_products": [],
      "exc_product_collections": [265680552111, 318279188655, 318279254191, 318279221423, 265681010863],
      "exc_product_tags": [],
      "rule_type": 2,
      "rule_setting": 0,
      "qty_table": [
        { "qty_from": 1, "qty_to": 4, "discount_type": 0, "discount_value": 10 },
        { "qty_from": 6, "qty_to": 8, "discount_type": 1, "discount_value": 11 }
      ],
      "amount_table": [],
      "qb_table_type": 4
    }
  ]
}
```

{% endcode %}

**Response 200**

```json
{
  "success": true,
  "message": [
    "Rule second1 has been created successfully",
    "Rule second2 has been updated successfully"
  ]
}
```

***

### Delete rule

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/delete
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "id": 79
}
```

**Response 200**

```json
{
  "success": true,
  "message": "Deleted rule successfully"
}
```

***

### Delete multiple rules

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/mass-delete
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "ids": [79, 80, 81]
}
```

**Response 200**

```json
{
  "success": true,
  "message": "Deleted multiple qb rule successfully"
}
```

***

### Get Applied Rules for Products

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/get-products-applied-rules
```

**Headers**

```
Content-Type: application/json
```

**Behavior**\
If `customer_id` is **null**, the system checks rules that apply to **All customers** or **Not-logged-in customers**.

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "product_ids": [6103930831040, 6103930929344],
  "customer_id": 5110452355264
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "productsAppliedRule": [
    {
      "id": "6103930831040",
      "rule_name": "first",
      "rule_id": 51,
      "qty_table": [
        { "id": 47, "qty_from": 1, "qty_to": 3, "discount_type": 0, "discount_value": 10,
          "createdAt": "2021-09-16T08:41:14.000Z", "updatedAt": "2021-09-16T08:41:14.000Z" },
        { "id": 48, "qty_from": 6, "qty_to": 7, "discount_type": 1, "discount_value": 10,
          "createdAt": "2021-09-16T08:41:14.000Z", "updatedAt": "2021-09-16T08:41:14.000Z" }
      ]
    }
  ]
}
```

{% endcode %}

***

### Get Price List of Variants based on Applied Rules

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/qb/get-variants-price-list
```

**Headers**

```
Content-Type: application/json
```

**Behavior**\
If `customer_id` is **null**, the system checks **Custom Pricing** rules that apply to **All** or **Not-logged-in** customers.

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "product_ids": [6103930831040, 6103930929344],
  "customer_id": 5110452355264
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "priceList": [
    {
      "id": "6103930831040",
      "rule_name": "first",
      "rule_id": 52,
      "variants": [
        {
          "id": "37682508955840",
          "price": "36.00",
          "compareAtPrice": null,
          "appliedRulePrice": [
            { "qty_from": 6, "qty_to": 7, "discount_type": 1, "discount_value": 10, "modifiedPrice": 90 },
            { "qty_from": 1, "qty_to": 3, "discount_type": 0, "discount_value": 10, "modifiedPrice": 10 }
          ]
        }
      ]
    }
  ]
}
```

{% endcode %}

***

## 🧭 Product Endpoints

### Search products

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/product/search
```

**Headers**

```
Content-Type: application/json
```

**Cursoring**\
`afterIndex` is a cursor. If `afterIndex` is `null`, search starts from the beginning. Example:

```
eyJsYXN0X2lkIjo2NjU1NDU2Mzc5MDUzLCJsYXN0X3ZhbHVlIjo2NjU1NDU2Mzc5MDUzfQ==
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "afterIndex": null,
  "first": 20,
  "searchQuery": "ocean"
}
```

**Response 200 (excerpt)**

```json
{
  "success": true,
  "productList": {
    "edges": [ { "node": { "id": "gid://shopify/Product/6586580271277", "title": "Ocean Blue Shirt", ... },
                 "cursor": "eyJsYXN0X2lkIjo2NTg2NTgwMjcxMjc3LCJsYXN0X3ZhbHVlIjo2NTg2NTgwMjcxMjc3fQ==" } ],
    "pageInfo": { "hasNextPage": false, "hasPreviousPage": false }
  }
}
```

### Get Product Tags

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/product/get-tags
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{ "domain": "abc.myshopify.com", "accessKey": "xxx" }
```

**Response 200 (excerpt)**

```json
{
  "success": true,
  "productTags": { "tags": ["cotton blouse","Couch","cowl","cpace","Crane","cream","crepe wool","crew","crew neck","crewneck","crisp"],
                   "last_cursor": "Y3Jpc3A=" }
}
```

### Get Products by Tags

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/product/get-by-tags
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "afterIndex": null,
  "first": 20,
  "tags": ["tag1","tags2","t3"],
  "operation": "AND"
}
```

**Operation**

* `"AND"` → returned products contain **all** tags
* `"OR"` → returned products contain **any** of the tags

**Response 200 (excerpt)**

```json
{
  "success": true,
  "productList": [
    {
      "id": "gid://shopify/Product/6586590625965",
      "title": "Anchor Bracelet Mens",
      "productType": "Bracelet",
      ...
    }
  ]
}
```

### Get Products by IDs

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/product/get-by-ids
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "ids": [6586590625965]
}
```

**Response 200 (excerpt)**

```json
{
  "success": true,
  "productList": [
    { "id": "gid://shopify/Product/6586590625965", "title": "Anchor Bracelet Mens", ... }
  ]
}
```

***

## 👥 Customer Endpoints

### Search Customers

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/customer/search
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "afterIndex": null,
  "first": 20,
  "searchQuery": "nta"
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "customers": [
    {
      "node": {
        "id": "gid://shopify/Customer/5127974846637",
        "displayName": "nta",
        "email": "abc@gmail.com",
        "firstName": "n",
        "lastName": "ta",
        "phone": null,
        "tags": ["wholesale"],
        "note": ""
      },
      "cursor": "eyJsYXN0X2lkIjo1MTI3OTc0ODQ2NjM3LCJsYXN0X3ZhbHVlIjo1MTI3OTc0ODQ2NjM3fQ=="
    }
  ]
}
```

{% endcode %}

### Get Customer Tags

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/customer/get-tags
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{ "domain": "abc.myshopify.com", "accessKey": "xxx" }
```

**Response 200**

```json
{
  "success": true,
  "customerTags": [
    { "node": "wholesale", "cursor": "d2hvbGVzYWxl" }
  ]
}
```

### Get Customers by IDs

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/customer/get-by-ids
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "ids": [5127974846637]
}
```

**Response 200**

{% code expandable="true" %}

```json
{
  "success": true,
  "customerList": [
    {
      "id": "gid://shopify/Customer/5127974846637",
      "displayName": "nta",
      "email": "abc@gmail.com",
      "firstName": "n",
      "lastName": "ta"
    }
  ]
}
```

{% endcode %}

### Get Customers by Tags

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/customer/get-by-tags
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "afterIndex": null,
  "first": 20,
  "tags": ["tag1", "tags2"],
  "operation": "AND"
}
```

**Operation**

* `"AND"` → returned customers must contain **all** tags
* `"OR"` → returned customers need **any one** tag

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "customers": [
    {
      "node": {
        "id": "gid://shopify/Customer/5127974846637",
        "displayName": "nta",
        "email": "abc@gmail.com",
        "firstName": "n",
        "lastName": "ta",
        "phone": null,
        "tags": ["wholesale"],
        "note": ""
      },
      "cursor": "eyJsYXN0X2lkIjo1MTI3OTc0ODQ2NjM3LCJsYXN0X3ZhbHVlIjo1MTI3OTc0ODQ2NjM3fQ=="
    }
  ]
}
```

{% endcode %}

***

## 🗂️ Collection Endpoints

> **As provided:** The “Get Collections” section uses the `/customer/search` endpoint and returns a `customers` payload. The following block is reproduced **exactly**.

**Get Collections**

```
POST https://b2b-solution-public-api.bsscommerce.com/api/v1/customer/search
```

**Headers**

```
Content-Type: application/json
```

**Body**

```json
{
  "domain": "abc.myshopify.com",
  "accessKey": "xxx",
  "afterIndex": null,
  "first": 20,
  "searchQuery": "nta"
}
```

**Response 200 (excerpt)**

{% code expandable="true" %}

```json
{
  "success": true,
  "customers": [
    {
      "node": {
        "id": "gid://shopify/Customer/5127974846637",
        "displayName": "nta",
        "email": "abc@gmail.com",
        "firstName": "n",
        "lastName": "ta",
        "phone": null,
        "tags": ["wholesale"],
        "note": ""
      },
      "cursor": "eyJsYXN0X2lkIjo1MTI3OTc0ODQ2NjM3LCJsYXN0X3ZhbHVlIjo1MTI3OTc0ODQ2NjM3fQ=="
    }
  ]
}
```

{% endcode %}

***

## ⚙️ Request Handling Policy

* The system **handles one request at a time**. After a request completes, the next one is processed.
* In case of a **server error**, recovery may take **up to 3 minutes** before a new request can be processed.
