Price Tags
Price Tags
Price tags modify pricing through volume, tiered, or ramp calculations. They allow you to define dynamic pricing rules that are evaluated at quote time, giving you flexible pricing beyond simple per-unit rates.
Use this guide when you need to apply catalog-defined pricing dimensions or discount dimensions to quote line items -- whether by referencing tags explicitly in the request or relying on auto-attached tags from product configuration.
Price Tag Types
Type | Description | Effect |
|---|---|---|
PriceDimension (price tag) | Overrides or sets the unit price | Replaces the base unit price from the Price Book Entry |
DiscountDimension (discount tag) | Applies a percentage or fixed amount discount | Reduces the price after the base unit price is resolved |
Tag Evaluation Modes
Mode | Description | Example |
|---|---|---|
Volume | A single tier is selected based on the total quantity; all units use that tier's price | 0-100 units = $10, 100-500 units = $8, 500+ units = $6 |
Tiered | Units are distributed across tiers; each tier prices only the units within its range | First 100 units at $10, the next 400 at $8, the remainder at $6 |
Ramp | Different rates apply across time periods within the subscription term | Months 1-3 at 50% off, months 4-6 at 25% off, months 7-12 at full price |
Tier Ranges
A tier matches when startUnit < quantity <= endUnit: the lower bound is exclusive and the upper bound is inclusive. Consecutive tiers share a boundary, so each tier's startUnit is the previous tier's endUnit, and the first tier starts at 0 so that a quantity of 1 is covered:
Tier | startUnit | endUnit | Covers |
|---|---|---|---|
1 | 0 | 100 | 1-100 |
2 | 100 | 200 | 101-200 |
3 | 200 | 300 | 201-300 |
A quantity outside every tier -- above the last endUnit, or in a gap left by non-adjacent tiers -- receives no adjustment from the tag. The request still succeeds and no error is returned, so verify the pricing fields on the line item to confirm a tier was applied.
How Tags Are Applied
Price tags reach a line item through two mechanisms:
- Auto-attached: Configured directly on the product in the catalog. These tags are applied automatically whenever the product appears on a quote. No action is required in the API request.
- Request-applied: Specified explicitly in the priceTags array on the product input. These are evaluated in addition to any auto-attached tags.
PriceTagInput Structure
Tags can be referenced by code or by ID. You must provide one or the other -- not both.
"priceTags": [
{ "code": "VOLUME_TIER_ENTERPRISE" },
{ "id": "a1B2c3D4e5F6g7H8" }
]Field | Type | Required | Description |
|---|---|---|---|
code | string | One of code/id | The price tag code defined in the catalog |
id | string | One of code/id | The price tag record ID |
Important: Provide either code or id on a tag entry, not both. Sending both returns 400 -- priceTags[0]: Only one of [code, id] should be set. Referencing a tag by code and by id are otherwise equivalent.A tag code that does not resolve is silently ignored: the request returns 200, the line is priced with no discount, and the tag is absent from the response priceTags array. Check priceTags in the response to confirm a tag was actually attached.
Response: priceTags
Each response line item carries a priceTags array listing the tags that were attached to that line. Every entry is the tag definition, including its full tier table:
"priceTags": [
{
"name": "Volume Tier Enterprise",
"id": "a0iHE000001WRqvYAG",
"recordType": "DiscountDimension",
"priceDimensionType": "Quantity",
"priceType": "Volume",
"active": true,
"startTime": null,
"endTime": null,
"priceTiers": [
{
"tierNumber": 1,
"startUnit": 0.00,
"startUnitDimension": null,
"endUnit": 100.00,
"endUnitDimension": null,
"chargeModel": "PerUnit",
"amount": null,
"discountPercentage": 0.00
},
{
"tierNumber": 2,
"startUnit": 100.00,
"startUnitDimension": null,
"endUnit": null,
"endUnitDimension": null,
"chargeModel": "PerUnit",
"amount": null,
"discountPercentage": 20.00
}
]
}
]priceTags does not report the resolved outcome
The array tells you which tags were attached and what their tiers are -- it does not say which tier matched or what was applied. Read the pricing fields on the line item itself to see the result:
- A price tag resolves the unit price, so compare listPrice and listTotalPrice.
- A discount tag lands in systemDiscount (percentage) and systemDiscountAmount (currency), then subtotal = listTotalPrice - systemDiscountAmount.
- Tag discounts do not populate discount or discountAmount; those hold discretionary discounts you pass in the request and stay 0 when only a tag applied.
For example, a 500-unit line at $2.00 with the tag above returns listTotalPrice: 12000, systemDiscount: 20, systemDiscountAmount: 2400 and totalPrice: 9600, while discount and discountAmount remain 0.
Authentication Setup
All examples below use the following headers:
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");Use Case 1: Apply a Discount Tag by ID
Reference a discount tag using its record ID. The tag's discount logic (percentage, amount, tiered, etc.) is evaluated by the pricing engine.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Discount Tag by ID",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 100,
priceTags: [{ id: "a1B2c3D4e5F6g7H8" }]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`List price: $${line.listTotalPrice}`);
console.log(`After tag: $${line.totalPrice}`);
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Discount Tag by ID",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 100,
"priceTags": [{ "id": "a1B2c3D4e5F6g7H8" }]
}
]
}'The pricing engine looks up the tag by its record ID, resolves the discount logic, and applies it to the line. The priceTags array in the response confirms which tag was attached; read systemDiscount and systemDiscountAmount on the line to see what it applied.
Use Case 2: Apply a Discount Tag by Code
Reference a discount tag using its code. This is often more readable and portable across environments than using IDs.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Discount Tag by Code",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 100,
priceTags: [{ code: "REGR_DISC_QTY_TIERED" }]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`List price: $${line.listTotalPrice}`);
console.log(`Discounted price: $${line.totalPrice}`);
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Discount Tag by Code",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 100,
"priceTags": [{ "code": "REGR_DISC_QTY_TIERED" }]
}
]
}'The REGR_DISC_QTY_TIERED tag evaluates the quantity (100) against its tiered discount schedule and applies the appropriate discount.
Use Case 3: Apply a Price Tag by Code (Unit Price Override)
A PriceDimension tag overrides the unit price from the Price Book Entry. This is used for volume pricing, tiered pricing, or any scenario where the per-unit rate depends on quantity or other factors.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Price Tag Override",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 500,
priceTags: [{ code: "VOLUME_TIER_ENTERPRISE" }]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`Unit price (after tag): $${line.listUnitPrice}`);
console.log(`Total: $${line.totalPrice}`);
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Price Tag Override",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 500,
"priceTags": [{ "code": "VOLUME_TIER_ENTERPRISE" }]
}
]
}'The VOLUME_TIER_ENTERPRISE tag evaluates the quantity (500) against its tier table and sets the appropriate unit price. The resolved price shows up in the line's listPrice and listTotalPrice; priceTags echoes the tag definition and its tiers.
Use Case 4: Price Tag and Discount Tag on the Same Line
You can apply both a price tag and a discount tag to the same product. The price tag resolves the unit price first, then the discount tag reduces the result.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Price + Discount Tags Combined",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 500,
priceTags: [
{ code: "VOLUME_TIER_ENTERPRISE" },
{ code: "LOYALTY_DISCOUNT_10PCT" }
]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`List unit price (from price tag): $${line.listUnitPrice}`);
console.log(`Total after discount tag: $${line.totalPrice}`);
console.log('Attached tags:', line.priceTags);
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Price + Discount Tags Combined",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 500,
"priceTags": [
{ "code": "VOLUME_TIER_ENTERPRISE" },
{ "code": "LOYALTY_DISCOUNT_10PCT" }
]
}
]
}'Execution order: The volume price tag sets the unit price based on the 500-unit tier, then the loyalty discount tag reduces the total by 10%. Both tags appear in the line's priceTags array, and the combined effect is visible in systemDiscount and systemDiscountAmount.
Use Case 5: Auto-Attached Tags (No Request Input Needed)
If a product has auto-attached tags configured in the catalog, they are applied automatically. You do not need to include a priceTags array in the request. The response still shows the applied tags.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Auto-Attached Tags Only",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE", // Has auto-attached VOLUME_TIER tag in catalog
uom: "User/Month",
quantity: 200
// No priceTags array -- auto-attached tags are applied automatically
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`Unit price (from auto-attached tag): $${line.listUnitPrice}`);
console.log(`Total: $${line.totalPrice}`);
console.log('Attached tags:', line.priceTags);
// priceTags shows the auto-attached tag even though none were in the request
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Auto-Attached Tags Only",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 200
}
]
}'The pricing engine automatically evaluates the product's catalog-configured tags. If you also specify request-applied tags in priceTags, both auto-attached and request-applied tags are evaluated together.
Use Case 6: Different Tags on Different Lines
Each product in the products array can have its own priceTags, allowing different pricing strategies per line.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Per-Line Tag Assignment",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 500,
priceTags: [{ code: "VOLUME_TIER_ENTERPRISE" }]
},
{
productSku: "ANALYTICS_ADDON",
uom: "User/Month",
quantity: 100,
priceTags: [{ code: "REGR_DISC_QTY_TIERED" }]
},
{
productSku: "DATA_EXPORT",
uom: "User/Month",
quantity: 50
// No priceTags -- uses base Price Book Entry price (or auto-attached tags)
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
result.quoteLineItems.forEach(item => {
const tags = item.priceTags || [];
console.log(`${item.product.sku}: $${item.listUnitPrice}/unit → $${item.totalPrice} total (${tags.length} tags applied)`);
});
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Per-Line Tag Assignment",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 500,
"priceTags": [{ "code": "VOLUME_TIER_ENTERPRISE" }]
},
{
"productSku": "ANALYTICS_ADDON",
"uom": "User/Month",
"quantity": 100,
"priceTags": [{ "code": "REGR_DISC_QTY_TIERED" }]
},
{
"productSku": "DATA_EXPORT",
"uom": "User/Month",
"quantity": 50
}
]
}'Each product is priced independently. PLATFORM_BASE uses a volume tier tag, ANALYTICS_ADDON uses a quantity-tiered discount tag, and DATA_EXPORT uses its base price (or auto-attached tags from the catalog).
Use Case 7: Ramp Discount Tags (Multi-Period)
Ramp discount tags apply different discount rates over different time periods within the subscription term. For example, a tag might give 50% off for the first 3 months, then 25% off for months 4-6, and full price thereafter. Ramp tags are configured in the catalog with time-based tiers. You apply them the same way as any other tag.
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Ramp Discount Schedule",
subscriptionStartDate: "2025-01-01",
subscriptionEndDate: "2026-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "PLATFORM_BASE",
uom: "User/Month",
quantity: 50,
priceTags: [{ code: "RAMP_ONBOARDING_DISCOUNT" }]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const line = result.quoteLineItems[0];
console.log(`Total (with ramp): $${line.totalPrice}`);
console.log('Attached tags:', line.priceTags);
// The total reflects the blended price across all ramp periods
})
.catch(error => console.log('Error:', error));curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Ramp Discount Schedule",
"subscriptionStartDate": "2025-01-01",
"subscriptionEndDate": "2026-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "PLATFORM_BASE",
"uom": "User/Month",
"quantity": 50,
"priceTags": [{ "code": "RAMP_ONBOARDING_DISCOUNT" }]
}
]
}'The pricing engine evaluates the ramp schedule against the subscription dates and calculates a blended total across all ramp periods. The line's priceTags echoes the ramp tag with its tier table; the blended result is in systemDiscountAmount and totalPrice.
Tag Application Summary
Scenario | Request Input | What Happens |
|---|---|---|
Auto-attached tag only | No priceTags array needed | Catalog-configured tags are applied automatically |
Request-applied tag by code | priceTags: [{ code: "..." }] | Tag looked up by code and evaluated |
Request-applied tag by ID | priceTags: [{ id: "..." }] | Tag looked up by record ID and evaluated |
Auto-attached + request-applied | priceTags array with additional tags | Both are evaluated; combined result |
Price + discount tags together | Multiple entries in priceTags | Price tag resolves unit price first, then discount tag reduces |
Different tags per line | Each product has its own priceTags | Tags evaluated independently per line |
Ramp tag | priceTags: [{ code: "RAMP_..." }] | Time-based tiers evaluated against subscription dates |
Price Tag Field Reference
Field | Type | Location | Description |
|---|---|---|---|
priceTags | array | Product input | Array of PriceTagInput objects |
priceTags[].code | string | PriceTagInput | Tag code from the catalog (use code OR id) |
priceTags[].id | string | PriceTagInput | Tag record ID (use code OR id) |
priceTags | array | Response line item | Tag definitions attached to this line, each with its priceTiers. Does not report which tier resolved -- see systemDiscount / systemDiscountAmount |
Next Steps
- Discounts -- Apply header, parent, and line-level discretionary discounts
- Subscription Terms -- Configure term lengths, billing periods, and renewal settings
- Bundles -- Work with bundle products and add-ons
- Create Quote Overview -- Return to the full API reference