Quote Data Reference
Quote Data Reference
This page provides a complete field reference for the Nue CPQ Create Quote API, covering all request fields, response fields, error codes, warning codes, and pricing behavior rules.
Endpoints
Endpoint | Method | Description |
|---|---|---|
/cpq/quotes | POST | Create and persist a quote (commit mode) |
/cpq/quotes:preview | POST | Preview a quote without persisting (dry-run mode) |
Both endpoints accept the same request body and return the same response structure. The only difference is that preview mode omits quote.id, gives line items temporary temp_<uuid> ids, and does not persist data.
Authentication
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{...}'Request Body Fields (CreateQuoteRequest)
These are the top-level fields accepted in the request body. The request is a flat JSON object with quote header fields at the top level and a products array.
Field | Type | Required | Default | Description |
|---|---|---|---|---|
opportunityId | string | Yes | -- | The Opportunity ID to associate with the quote |
name | string | Yes | -- | The quote name |
subscriptionStartDate | date | Yes | -- | Start date in YYYY-MM-DD format |
subscriptionEndDate | date | No | Calculated from term | End date in YYYY-MM-DD format |
subscriptionTerm | number | Yes | -- | Term length (e.g., 12 for 12 months) |
subscriptionTermDimension | string | No | "Month" | "Month" or "Year" |
priceBookId | string | No | System default | The Price Book ID to use for pricing |
discount | number | No | 0 | Header-level discount percentage (0-100) |
discountAmount | number | No | 0 | Header-level fixed discount amount |
billingPeriod | string | No | Product default | "Monthly", "Quarterly", "Semi-Annually", "Annually" |
billingTiming | string | No | Product default | "In Advance" or "In Arrears" |
autoRenew | boolean | No | Product default | Auto-renewal setting for all products |
currencyIsoCode | string | No | Org default | ISO 4217 currency code (e.g., "USD", "EUR") |
priceTags | array | No | [] | Quote-level price/discount tags (array of PriceTagInput) |
products | array | Yes | -- | Array of AddQuoteProductRequest objects (at least one required) |
Any additional top-level fields beyond those listed above are treated as custom fields and stored on the quote header. Custom field names must match the API field names on your Quote object (e.g., Ruby__CustomText__c).
AddQuoteProductRequest Fields
Each entry in the products array (and recursively in addOns) accepts these fields.
Field | Type | Required | Default | Description |
|---|---|---|---|---|
productSku | string | Yes* | -- | Product SKU (either SKU or name required) |
productName | string | Yes* | -- | Product name (alternative to SKU) |
priceBookEntryId | string | No | -- | Direct PBE ID (bypasses SKU/UOM resolution) |
uom | string | Conditional | -- | Unit of Measure; required if priceBookEntryId is not provided |
quantity | number | No | Product default | Product quantity |
startDate | date | No | Quote start date | Per-product start date (YYYY-MM-DD) |
endDate | date | No | Calculated | Per-product end date (YYYY-MM-DD) |
subscriptionTerm | number | No | Quote term | Per-product term override |
subscriptionTermDimension | string | No | Quote dimension | Per-product term dimension override |
discount | number | No | 0 | Line-level discount percentage (0-100) |
discountAmount | number | No | 0 | Line-level fixed discount amount |
billingPeriod | string | No | Quote/product default | "Monthly", "Quarterly", "Semi-Annually", "Annually" |
billingTiming | string | No | Quote/product default | "In Advance" or "In Arrears" |
autoRenew | boolean | No | Quote/product default | Per-product auto-renew override |
evergreen | boolean | No | false | Whether the subscription is evergreen (no end date) |
renewalTerm | number | No | Same as term | Renewal term override |
priceTags | array | No | [] | Line-level price/discount tags (array of PriceTagInput) |
addOns | array | No | [] | Add-on products for bundles (recursive AddQuoteProductRequest) |
customPricingAttributes | array | No | [] | Custom attributes for multi-attribute PBE resolution |
customFields | object | No | {} | Line-level custom fields written onto the created line item, keyed by Salesforce API name on QuoteLineItem (e.g. { "CostCenter__c": "CC-1042" }). Applies recursively through addOns. An unknown field name is rejected |
productOptionId | string | No | -- | Targets a specific bundle option slot explicitly, for example a dynamic option. When set, productSku/productName become optional |
parentLineId | string | No | -- | Update API only. Adds this product as an option child under the existing bundle line with this id -- how you reconfigure a bundle. Omit for a top-level add |
*Either productSku or productName is required. If both are provided, SKU takes precedence for product resolution.
PriceTagInput Fields
Price tags are referenced by code or by ID. At least one of the two fields must be provided.
Field | Type | Required | Description |
|---|---|---|---|
code | string | One of code/id | The price tag code defined in the catalog (e.g., "VOLUME_DISCOUNT") |
id | string | One of code/id | The price tag record ID (e.g., "a1B2c3D4e5F6g7H8") |
Example:
{
"priceTags": [
{ "code": "VOLUME_DISCOUNT" },
{ "id": "a1B2c3D4e5F6g7H8" }
]
}CustomPricingAttribute Fields
Custom pricing attributes enable multi-attribute PBE resolution when a product has multiple PBEs differentiated by custom fields.
Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The API field name of the pricing attribute on the PBE (e.g., Ruby__PricingAttribute_1__c) |
value | string | Yes | The value to match against the PBE field |
Example:
{
"customPricingAttributes": [
{ "name": "Ruby__PricingAttribute_1__c", "value": "Technology Partner" },
{ "name": "Ruby__PricingAttribute_2__c", "value": "Enterprise" }
]
}When multiple attributes are provided, the engine uses AND logic -- all attributes must match for a PBE to be selected.
Response Structure
The quote and its line items are returned at the top level of the response body:
{
"quote": { ... },
"quoteLineItems": [ ... ]
}Field | Type | Description |
|---|---|---|
quote | object | The quote header with all calculated pricing fields |
quoteLineItems | array | Root line items; bundle children are nested in childrenLineItems on their parent |
There is no status, data, errors or warnings field. Detect failure from the HTTP status; see Validation Errors for the error body.
Quote Fields (Response)
The data.quote object in the response contains these fields.
Field | Type | Description |
|---|---|---|
id | string/null | Quote UUID (commit mode) or null (preview mode) |
name | string | Quote name |
opportunityId | string | Associated Opportunity ID |
totalAmount | number | Final calculated total after all discounts |
listAmount | number | Total list price before discounts |
discount | number | Applied header discount percentage |
discountAmount | number | Applied header discount amount |
subscriptionStartDate | date | Quote start date |
subscriptionEndDate | date | Quote end date |
subscriptionTerm | number | Subscription term length |
subscriptionTermDimension | string | Term dimension ("Month" or "Year") |
billingPeriod | string | Billing period |
billingTiming | string | Billing timing |
autoRenew | boolean | Auto-renewal setting |
currencyIsoCode | string | Currency code |
priceBookId | string | Price Book ID used for pricing |
status | string | Quote status |
createdDate | datetime | Creation timestamp (commit only) |
lastModifiedDate | datetime | Last modification timestamp (commit only) |
Any custom fields included in the request body also appear on the quote object in the response.
QuoteLineItemDTO Fields (Response)
Each entry in the data.quoteLineItems array contains these fields. Bundle children appear in the childrenLineItems array within the parent line item.
Field | Type | Description |
|---|---|---|
id | string/null | Line item UUID (commit) or null (preview) |
product | object | Product details: sku (string), name (string), id (string) |
quantity | number | Product quantity |
listUnitPrice | number | List price per unit per billing period |
listTotalPrice | number | Total list price: listUnitPrice x quantity x term |
totalPrice | number | Final price after all discounts |
discount | number | Applied discount percentage |
discountAmount | number | Applied discount amount |
systemDiscount | number | System-level discount (e.g., from QTA) |
startDate | date | Line item start date |
endDate | date | Line item end date |
subscriptionTerm | number | Line item subscription term |
subscriptionTermDimension | string | Term dimension |
billingPeriod | string | Billing period for this line |
billingTiming | string | Billing timing for this line |
autoRenew | boolean | Auto-renewal setting |
evergreen | boolean | Whether the line is evergreen |
renewalTerm | number | Renewal term |
uom | string | Unit of Measure |
revenueModel | string | Revenue model ("Recurring", "One-Time", "Usage") |
childrenLineItems | array | Nested add-on QuoteLineItemDTO objects (bundle children) |
Pricing Field Relationships
listUnitPrice -- from Price Book Entry
listTotalPrice = listUnitPrice x quantity x term -- for recurring products
listTotalPrice = listUnitPrice x quantity -- for one-time products
totalPrice = listTotalPrice x (1 - systemDiscount/100) x (1 - discount/100)Message Fields (Errors and Warnings)
Both error and warning objects share this structure:
Field | Type | Description |
|---|---|---|
code | string | Machine-readable error or warning code |
message | string | Human-readable description of the issue |
field | string | The field that caused the issue (when applicable) |
Error Code Reference
Error Code | HTTP Status | Description |
|---|---|---|
MISSING_PARAMETER | 400 | A required parameter is missing from the request |
QUOTE_NAME_REQUIRED | 400 | The name field is missing or empty |
QUOTE_OPPORTUNITYID_REQUIRED | 400 | The opportunityId field is missing or empty |
QUOTE_SUBSCRIPTIONTERM_INVALID | 400 | The subscriptionTerm is zero, negative, or not a number |
PRODUCT_SKU_OR_NAME_REQUIRED | 400 | A product entry has neither productSku nor productName |
PRODUCT_QUANTITY_INVALID | 400 | The quantity is zero, negative, or not a number |
PRODUCT_BILLINGPERIOD_INVALID | 400 | The billingPeriod value is not one of: Monthly, Quarterly, Semi-Annually, Annually |
PRODUCT_BILLINGTIMING_INVALID | 400 | The billingTiming value is not one of: In Advance, In Arrears |
PRODUCT_RENEWALTERM_INVALID | 400 | The renewalTerm is zero, negative, or not a number |
PRODUCT_SUBSCRIPTIONTERM_INVALID | 400 | A per-product subscriptionTerm override is invalid |
INVALID_INPUT | 400 | General invalid input (e.g., nonexistent SKU, malformed JSON) |
INVALID_ADDON_PRODUCT | 400 | The specified add-on is not a valid option for the parent bundle |
PRICEBOOK_ENTRY_MISMATCH | 400 | No PBE found matching the given SKU + UOM + currency + pricing attributes |
BUSINESS_LOGIC_ERROR | 400 | A business rule was violated (e.g., conflicting configurations) |
Warning Code Reference
Warning Code | Description |
|---|---|
DUPLICATE_PRICE_TAG | The same price tag was specified more than once on a product; deduplicated |
PRODUCT_DISCOUNT_APPLIED | Discount percentage takes precedence over discount amount on a product |
HEADER_DISCOUNT_APPLIED | Header-level discount percentage takes precedence over header discount amount |
PRODUCT_DISCOUNT_OVERRIDES_HEADER | A product-level discount overrides the header-level discount for that line |
DEFAULT_VALUE_APPLIED | A default value was applied for a missing optional field |
Pricing Formula
The pricing engine calculates prices using the following formula chain:
Recurring Products
listTotalPrice = listUnitPrice x quantity x term
subtotal = listTotalPrice x (1 - systemDiscount / 100)
totalPrice = subtotal x (1 - discount / 100)One-Time Products
listTotalPrice = listUnitPrice x quantity
subtotal = listTotalPrice x (1 - systemDiscount / 100)
totalPrice = subtotal x (1 - discount / 100)Fixed Amount Discount (Alternative)
When discountAmount is used instead of discount:
totalPrice = listTotalPrice - discountAmountDefault Values
Field | Default When Omitted |
|---|---|
subscriptionTermDimension | "Month" |
quantity | Product-specific default (typically 1) |
discount | 0 (no discount) |
discountAmount | 0 (no discount) |
startDate (product) | Quote subscriptionStartDate |
endDate (product) | Calculated from start date + term |
billingPeriod | Product configuration default |
billingTiming | Product configuration default |
autoRenew | Product configuration default |
evergreen | false |
currencyIsoCode | Org default currency |
priceBookId | System default Price Book |
Fallback Logic
Scenario | Behavior |
|---|---|
subscriptionEndDate omitted | Calculated as subscriptionStartDate + subscriptionTerm |
Product startDate omitted | Falls back to quote subscriptionStartDate |
Product subscriptionTerm omitted | Falls back to quote subscriptionTerm |
Product billingPeriod omitted | Falls back to quote billingPeriod, then product default |
Product billingTiming omitted | Falls back to quote billingTiming, then product default |
Product autoRenew omitted | Falls back to quote autoRenew, then product default |
priceBookId omitted | Uses the system default Price Book |
currencyIsoCode omitted | Uses the org's default currency |
Discount Propagation Rules
Rule | Behavior |
|---|---|
Header discount to lines | Applied to all lines without their own explicit discount |
Parent discount to children | Propagated to bundle children without their own explicit discount |
Explicit line discount | Overrides header discount for that specific line |
Explicit add-on discount | Overrides parent discount for that specific add-on |
Percentage vs amount conflict | Percentage takes precedence; amount is ignored (warning returned) |
System discount + discretionary | Stack multiplicatively: listPrice x (1 - systemDiscount) x (1 - discretionaryDiscount) |
Header discountAmount distribution | Fixed amount is distributed proportionally across eligible lines by list amount ratio |
Validation Constraints
Constraint | Rule |
|---|---|
name | Required; cannot be empty |
opportunityId | Required; must reference a valid Opportunity |
subscriptionTerm | Required; must be a positive number |
products | Required; array must contain at least one item |
discount range | Must be between 0 and 100 (inclusive) |
discount vs discountAmount | Mutually exclusive when both are non-zero; percentage takes precedence with warning |
billingPeriod values | "Monthly", "Quarterly", "Semi-Annually", "Annually" |
billingTiming values | "In Advance", "In Arrears" |
subscriptionTermDimension values | "Month", "Year" |
Product identification | Either productSku/productName or priceBookEntryId required |
uom | Required when priceBookEntryId is not provided |
Add-on validation | Add-on products must be valid options for the parent bundle |
Currency PBE | Every product must have a PBE in the requested currency |