Inventory & Products | Products | Qty Discounts | Set Qty Discounts

Setting Product Quantity Discounts

This document outlines the procedure for making API calls to create, update, or delete product quantity discount data via https://easycms.fi/public_api/set_products_qty_discount/.

Important Notes

  • All parameters marked as MANDATORY are required
  • This endpoint handles three operations: CREATE, UPDATE, and DELETE
  • The pid parameter is MANDATORY for all operations
  • Duplicate min_qty values are not allowed for the same product

Product Quantity Discount Data Management

Manage quantity discount tiers for products to offer tiered pricing based on purchase quantity.

Endpoint and Method

  • Endpoint: https://easycms.fi/public_api/set_products_qty_discount/
  • Method: POST only
  • Content-Type: application/json

Parameters | Payload

  • TOKEN (api_key): Your unique API key for authentication. How to Create API Credentials.
  • username: Your login username.
  • password: Your login password.
  • account: Your specific account ID.

Required Parameters (for all operations)

Parameter Type Description
pid integer Product ID (MANDATORY)

For CREATE (no id provided)

Parameter Type Required Description
min_qty double Yes Minimum quantity for discount tier
discount double Yes Discount amount
discount_type integer Yes One of 0 (percentage), 1 (gross total line), or 3 (gross per product). Value 2 ("none") is an admin-UI-only sentinel and is rejected by this endpoint with INVALID_DISCOUNT_TYPE.

For UPDATE (id provided)

Parameter Type Required Description
id string Yes Discount record ID to update
min_qty double No New minimum quantity
discount double No New discount amount
discount_type integer No New discount type

For DELETE (id provided with _delete flag)

Parameter Type Required Description
id string Yes Discount record ID to delete
_delete boolean Yes Must be true to confirm deletion



Discount Types

Value Label Description
0 percentage Discount is a percentage off the original price (e.g., 5 = 5% off)
1 gross_total_line Discount represents the total gross price for ALL min_qty units (e.g., 85.00 = €85.00 total for 50 units)
2 none No discount type selected (placeholder, not stored in DB)
3 gross_per_product Discount represents the gross price per single unit (e.g., 12.50 = €12.50 per unit)



Call Examples in Different Languages


# CREATE a new quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}'

# UPDATE an existing quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "min_qty": 15,
  "discount": 7.50
}'

# DELETE a quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "_delete": true
}'

// CREATE a new quantity discount tier
$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://easycms.fi/public_api/set_products_qty_discount",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode([
    'username' => 'USERNAME', 
    'password' => 'PASSWORD', 
    'account' => 'ACCOUNT_ID',
    'pid' => 12345,
    'min_qty' => 10,
    'discount' => 5.00,
    'discount_type' => 0
  ]),
  CURLOPT_HTTPHEADER => array(
    "Authorization1: TOKEN",
    "Content-Type: application/json"
  ),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

import requests
import json

url = "https://easycms.fi/public_api/set_products_qty_discount"
headers = {
    "Authorization1": "TOKEN",
    "Content-Type": "application/json"
}

# CREATE a new quantity discount tier
payload = {
    'username': 'USERNAME', 
    'password': 'PASSWORD', 
    'account': 'ACCOUNT_ID',
    'pid': 12345,
    'min_qty': 10,
    'discount': 5.00,
    'discount_type': 0
}
response = requests.post(url, headers=headers, json=payload)
print(response.text)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

// CREATE a new quantity discount tier
String jsonBody = """
{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}
""";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://easycms.fi/public_api/set_products_qty_discount"))
    .headers("Authorization1", "TOKEN", "Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

const https = require('https');

// CREATE a new quantity discount tier
const data = JSON.stringify({
  username: 'USERNAME', 
  password: 'PASSWORD', 
  account: 'ACCOUNT_ID',
  pid: 12345,
  min_qty: 10,
  discount: 5.00,
  discount_type: 0
});

const options = {
  hostname: 'easycms.fi',
  path: '/public_api/set_products_qty_discount',
  method: 'POST',
  headers: {
    'Authorization1': 'TOKEN',
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
};

const req = https.request(options, (res) => {
  let responseData = '';
  res.on('data', (chunk) => { responseData += chunk; });
  res.on('end', () => { console.log(responseData); });
});
req.on('error', (e) => { console.error(e); });
req.write(data);
req.end();

import okhttp3.OkHttpClient
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody

fun main() {
    val client = OkHttpClient()
    val mediaType = "application/json".toMediaType()

    // CREATE a new quantity discount tier
    val jsonBody = """
    {
      "username": "USERNAME",
      "password": "PASSWORD",
      "account": "ACCOUNT_ID",
      "pid": 12345,
      "min_qty": 10,
      "discount": 5.00,
      "discount_type": 0
    }
    """.trimIndent()

    val requestBody = jsonBody.toRequestBody(mediaType)

    val request = Request.Builder()
        .url("https://easycms.fi/public_api/set_products_qty_discount")
        .post(requestBody)
        .addHeader("Authorization1", "TOKEN")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")
        println(response.body?.string())
    }
}




Handling Endpoint Results

When you make a request to the endpoint, you receive a JSON response containing various keys and values. Here's an explanation of the response keys and their meanings:


{
  "status": "success",
  "message": "Quantity discount created successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345,
    "min_qty": 10,
    "discount": 5.00,
    "discount_type": 0
  }
}
    

{
  "status": "success",
  "message": "Quantity discount updated successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345,
    "discount": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "pid": 12345,
      "crp_id": "PROD-001",
      "min_qty": 15,
      "discount": 7.50,
      "discount_type": 0,
      "datenew": "2024-01-15 10:30:00"
    }
  },
  "changes": {
    "min_qty": {"old": 10, "new": 15},
    "discount": {"old": 5.00, "new": 7.50}
  }
}
    

{
  "status": "success",
  "message": "Quantity discount deleted successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345
  }
}
    

Error Handling

Here are the possible error messages and their meanings:

Error Code HTTP Status Description
MISSING_PID 400 Product ID is required
INVALID_PID 400 Product ID must be a valid positive integer
PRODUCT_NOT_FOUND 404 The product does not exist
MISSING_REQUIRED_FIELDS 400 Required fields missing for create operation
INVALID_DISCOUNT_TYPE 400 Discount type must be 0 (percentage), 1 (gross total line), or 3 (gross per product). Value 2 is the admin-only "none" sentinel and is rejected by this endpoint.
INVALID_MIN_QTY 400 Minimum quantity must be greater than 0
INVALID_DISCOUNT 400 Discount cannot be negative
DISCOUNT_NOT_FOUND 404 Discount record not found
DUPLICATE_MIN_QTY 400 A discount tier already exists for this min_qty
NO_CHANGES 400 No fields provided for update
MISSING_ID 400 Discount ID is required for deletion
UPDATE_FAILED 500 Failed to update record
CREATE_FAILED 500 Failed to create record
DELETE_FAILED 500 Failed to delete record
METHOD_NOT_ALLOWED 405 Only POST method is allowed
UN-AUTHORIZED 401 Incorrect username or password

Error Response Example

{
  "status": "error",
  "error_code": "MISSING_REQUIRED_FIELDS",
  "message": "Missing required field: min_qty"
}

Use Cases

Create a Percentage Discount Tier

Offer 5% off when customers order 10 or more units:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}

Create a Gross Total Line Tier

Set a total gross price of €85.00 for all 50 units when ordering 50 or more:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 50,
  "discount": 85.00,
  "discount_type": 1
}

Create a Gross Per Product Tier

Set a gross price of €12.50 per unit for orders of 100 or more units:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 100,
  "discount": 12.50,
  "discount_type": 3
}

Update Discount Amount

Change the discount from 5% to 7.5%:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "discount": 7.50
}

Remove a Discount Tier

Delete a discount tier that is no longer needed:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "_delete": true
}

Best Practices

  1. Plan your tiers carefully: Set up logical quantity breaks (e.g., 10, 25, 50, 100)
  2. Avoid overlapping tiers: Each min_qty should be unique per product
  3. Use appropriate discount types: Percentage for smaller discounts, gross total line for bulk package deals, gross per product for per-unit bulk pricing
  4. Test your pricing: Verify the final price calculations work as expected
  5. Keep tiers organized: Delete unused tiers to maintain clean data

Related Endpoints

This document outlines the procedure for making API calls to create, update, or delete product quantity discount data via https://easycms.fi/public_api/set_products_qty_discount/.

Important Notes

  • All parameters marked as MANDATORY are required
  • This endpoint handles three operations: CREATE, UPDATE, and DELETE
  • The pid parameter is MANDATORY for all operations
  • Duplicate min_qty values are not allowed for the same product

Product Quantity Discount Data Management

Manage quantity discount tiers for products to offer tiered pricing based on purchase quantity.

Endpoint and Method

  • Endpoint: https://easycms.fi/public_api/set_products_qty_discount/
  • Method: POST only
  • Content-Type: application/json

Parameters | Payload

  • TOKEN (api_key): Your unique API key for authentication. How to Create API Credentials.
  • username: Your login username.
  • password: Your login password.
  • account: Your specific account ID.

Required Parameters (for all operations)

Parameter Type Description
pid integer Product ID (MANDATORY)

For CREATE (no id provided)

Parameter Type Required Description
min_qty double Yes Minimum quantity for discount tier
discount double Yes Discount amount
discount_type integer Yes One of 0 (percentage), 1 (gross total line), or 3 (gross per product). Value 2 ("none") is an admin-UI-only sentinel and is rejected by this endpoint with INVALID_DISCOUNT_TYPE.

For UPDATE (id provided)

Parameter Type Required Description
id string Yes Discount record ID to update
min_qty double No New minimum quantity
discount double No New discount amount
discount_type integer No New discount type

For DELETE (id provided with _delete flag)

Parameter Type Required Description
id string Yes Discount record ID to delete
_delete boolean Yes Must be true to confirm deletion



Discount Types

Value Label Description
0 percentage Discount is a percentage off the original price (e.g., 5 = 5% off)
1 gross_total_line Discount represents the total gross price for ALL min_qty units (e.g., 85.00 = €85.00 total for 50 units)
2 none No discount type selected (placeholder, not stored in DB)
3 gross_per_product Discount represents the gross price per single unit (e.g., 12.50 = €12.50 per unit)



Call Examples in Different Languages


# CREATE a new quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}'

# UPDATE an existing quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "min_qty": 15,
  "discount": 7.50
}'

# DELETE a quantity discount tier
curl -X POST 'https://easycms.fi/public_api/set_products_qty_discount' \
-H 'Authorization1: TOKEN' \
-H 'Content-Type: application/json' \
-d '{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "_delete": true
}'

// CREATE a new quantity discount tier
$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://easycms.fi/public_api/set_products_qty_discount",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode([
    'username' => 'USERNAME', 
    'password' => 'PASSWORD', 
    'account' => 'ACCOUNT_ID',
    'pid' => 12345,
    'min_qty' => 10,
    'discount' => 5.00,
    'discount_type' => 0
  ]),
  CURLOPT_HTTPHEADER => array(
    "Authorization1: TOKEN",
    "Content-Type: application/json"
  ),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

import requests
import json

url = "https://easycms.fi/public_api/set_products_qty_discount"
headers = {
    "Authorization1": "TOKEN",
    "Content-Type": "application/json"
}

# CREATE a new quantity discount tier
payload = {
    'username': 'USERNAME', 
    'password': 'PASSWORD', 
    'account': 'ACCOUNT_ID',
    'pid': 12345,
    'min_qty': 10,
    'discount': 5.00,
    'discount_type': 0
}
response = requests.post(url, headers=headers, json=payload)
print(response.text)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

// CREATE a new quantity discount tier
String jsonBody = """
{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}
""";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://easycms.fi/public_api/set_products_qty_discount"))
    .headers("Authorization1", "TOKEN", "Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

const https = require('https');

// CREATE a new quantity discount tier
const data = JSON.stringify({
  username: 'USERNAME', 
  password: 'PASSWORD', 
  account: 'ACCOUNT_ID',
  pid: 12345,
  min_qty: 10,
  discount: 5.00,
  discount_type: 0
});

const options = {
  hostname: 'easycms.fi',
  path: '/public_api/set_products_qty_discount',
  method: 'POST',
  headers: {
    'Authorization1': 'TOKEN',
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
};

const req = https.request(options, (res) => {
  let responseData = '';
  res.on('data', (chunk) => { responseData += chunk; });
  res.on('end', () => { console.log(responseData); });
});
req.on('error', (e) => { console.error(e); });
req.write(data);
req.end();

import okhttp3.OkHttpClient
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody

fun main() {
    val client = OkHttpClient()
    val mediaType = "application/json".toMediaType()

    // CREATE a new quantity discount tier
    val jsonBody = """
    {
      "username": "USERNAME",
      "password": "PASSWORD",
      "account": "ACCOUNT_ID",
      "pid": 12345,
      "min_qty": 10,
      "discount": 5.00,
      "discount_type": 0
    }
    """.trimIndent()

    val requestBody = jsonBody.toRequestBody(mediaType)

    val request = Request.Builder()
        .url("https://easycms.fi/public_api/set_products_qty_discount")
        .post(requestBody)
        .addHeader("Authorization1", "TOKEN")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")
        println(response.body?.string())
    }
}




Handling Endpoint Results

When you make a request to the endpoint, you receive a JSON response containing various keys and values. Here's an explanation of the response keys and their meanings:


{
  "status": "success",
  "message": "Quantity discount created successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345,
    "min_qty": 10,
    "discount": 5.00,
    "discount_type": 0
  }
}
    

{
  "status": "success",
  "message": "Quantity discount updated successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345,
    "discount": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "pid": 12345,
      "crp_id": "PROD-001",
      "min_qty": 15,
      "discount": 7.50,
      "discount_type": 0,
      "datenew": "2024-01-15 10:30:00"
    }
  },
  "changes": {
    "min_qty": {"old": 10, "new": 15},
    "discount": {"old": 5.00, "new": 7.50}
  }
}
    

{
  "status": "success",
  "message": "Quantity discount deleted successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "pid": 12345
  }
}
    

Error Handling

Here are the possible error messages and their meanings:

Error Code HTTP Status Description
MISSING_PID 400 Product ID is required
INVALID_PID 400 Product ID must be a valid positive integer
PRODUCT_NOT_FOUND 404 The product does not exist
MISSING_REQUIRED_FIELDS 400 Required fields missing for create operation
INVALID_DISCOUNT_TYPE 400 Discount type must be 0 (percentage), 1 (gross total line), or 3 (gross per product). Value 2 is the admin-only "none" sentinel and is rejected by this endpoint.
INVALID_MIN_QTY 400 Minimum quantity must be greater than 0
INVALID_DISCOUNT 400 Discount cannot be negative
DISCOUNT_NOT_FOUND 404 Discount record not found
DUPLICATE_MIN_QTY 400 A discount tier already exists for this min_qty
NO_CHANGES 400 No fields provided for update
MISSING_ID 400 Discount ID is required for deletion
UPDATE_FAILED 500 Failed to update record
CREATE_FAILED 500 Failed to create record
DELETE_FAILED 500 Failed to delete record
METHOD_NOT_ALLOWED 405 Only POST method is allowed
UN-AUTHORIZED 401 Incorrect username or password

Error Response Example

{
  "status": "error",
  "error_code": "MISSING_REQUIRED_FIELDS",
  "message": "Missing required field: min_qty"
}

Use Cases

Create a Percentage Discount Tier

Offer 5% off when customers order 10 or more units:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 10,
  "discount": 5.00,
  "discount_type": 0
}

Create a Gross Total Line Tier

Set a total gross price of €85.00 for all 50 units when ordering 50 or more:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 50,
  "discount": 85.00,
  "discount_type": 1
}

Create a Gross Per Product Tier

Set a gross price of €12.50 per unit for orders of 100 or more units:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "min_qty": 100,
  "discount": 12.50,
  "discount_type": 3
}

Update Discount Amount

Change the discount from 5% to 7.5%:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "discount": 7.50
}

Remove a Discount Tier

Delete a discount tier that is no longer needed:

{
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "pid": 12345,
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "_delete": true
}

Best Practices

  1. Plan your tiers carefully: Set up logical quantity breaks (e.g., 10, 25, 50, 100)
  2. Avoid overlapping tiers: Each min_qty should be unique per product
  3. Use appropriate discount types: Percentage for smaller discounts, gross total line for bulk package deals, gross per product for per-unit bulk pricing
  4. Test your pricing: Verify the final price calculations work as expected
  5. Keep tiers organized: Delete unused tiers to maintain clean data

Related Endpoints