Custom Fields
17 min
custom fields the nue cpq quote api supports custom fields on quote headers and on individual line items custom field names in the request body map directly to fields on the quote and quotelineitem objects this allows you to set business specific metadata such as salesforce custom fields, department codes, regions, cost centers, or approval flags directly when creating, previewing, or updating a quote everything on this page applies identically to orders swap /cpq/quotes for /cpq/orders , quote for order , and quotelineitem for orderproduct how custom fields work when the api receives a create quote request, it processes all standard fields (like name , opportunityid , products ) through the pricing engine any additional top level fields in the request body are treated as header custom fields and stored on the quote header inside the products array, a customfields object sets line level custom fields on the line that product creates key behaviors behavior details flat json mapping header custom field names in the request map directly to quote object fields line level customfields a customfields object on any product (and recursively on addons ) writes straight onto that line item pricing engine passthrough custom fields survive the pricing engine they are not overwritten during pricing calculations preview and commit custom fields appear in both preview and commit responses supported types string, number, boolean, and date values are all supported updating existing records header and line custom fields are both patchable through the update quote api (see use case 5) authentication const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); use case 1 custom fields on quote header (committed) set custom fields as top level properties in the request body when creating a committed quote the field names must match the api names of the custom fields on your quote object (e g , salesforce custom field api names like ruby customtext c ) const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); const quotedata = { opportunityid "006xx000001abc123", name "enterprise license custom fields", subscriptionstartdate "2026 01 01", subscriptionenddate "2027 01 01", subscriptiontermdimension "month", subscriptionterm 12, "ruby customtext c" "hello", "ruby customnumber c" 42 50, "ruby customdate c" "2026 06 15", "ruby customcheckbox c" true, products \[ { productsku "nue on salesforce", uom "user/month", quantity 25 } ] }; fetch('https //api nue io/cpq/quotes', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { console log(`quote id ${result quote id}`); console log(`custom text ${result quote\['ruby customtext c']}`); // "hello" console log(`custom number ${result quote\['ruby customnumber c']}`); // 42 50 console log(`custom date ${result quote\['ruby customdate c']}`); // "2026 06 15" console log(`custom checkbox ${result quote\['ruby customcheckbox c']}`); // true console log(`total amount $${result quote totalamount}`); }) catch(error => console log('error ', error)); curl x post 'https //api nue io/cpq/quotes' \\ h 'nue api key your api key here' \\ h 'content type application/json' \\ d '{ "opportunityid" "006xx000001abc123", "name" "enterprise license custom fields", "subscriptionstartdate" "2026 01 01", "subscriptionenddate" "2027 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "ruby customtext c" "hello", "ruby customnumber c" 42 50, "ruby customdate c" "2026 06 15", "ruby customcheckbox c" true, "products" \[ { "productsku" "nue on salesforce", "uom" "user/month", "quantity" 25 } ] }' the response includes all custom fields on the quote object alongside the standard pricing fields the pricing engine calculates totalamount , listtotalprice , etc , without affecting the custom field values use case 2 custom fields on quote header (preview) custom fields work identically in preview mode they appear in the response even though no data is persisted const quotedata = { opportunityid "006xx000001abc123", name "preview with custom fields", subscriptionstartdate "2026 01 01", subscriptionenddate "2027 01 01", subscriptiontermdimension "month", subscriptionterm 12, "ruby customtext c" "preview value", "ruby customnumber c" 99 99, "ruby customdate c" "2026 12 31", products \[ { productsku "nue on salesforce", uom "user/month", quantity 10 } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { console log(`quote id ${result quote id}`); // undefined preview mode console log(`custom text ${result quote\['ruby customtext c']}`); // "preview value" console log(`custom number ${result quote\['ruby customnumber c']}`); // 99 99 console log(`custom date ${result quote\['ruby customdate c']}`); // "2026 12 31" console log(`total amount $${result quote totalamount}`); }) 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" "preview with custom fields", "subscriptionstartdate" "2026 01 01", "subscriptionenddate" "2027 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "ruby customtext c" "preview value", "ruby customnumber c" 99 99, "ruby customdate c" "2026 12 31", "products" \[ { "productsku" "nue on salesforce", "uom" "user/month", "quantity" 10 } ] }' the custom fields survive the pricing engine and appear in the preview response since this is preview mode, the quote object has no id and nothing is persisted use case 3 custom fields with bundle products when the pricing engine processes bundles, it calculates list prices, discounts, and totals for parent and child line items custom fields on the quote header are not affected by these calculations they pass through untouched const quotedata = { opportunityid "006xx000001abc123", name "bundle quote with custom fields", subscriptionstartdate "2026 01 01", subscriptionenddate "2027 01 01", subscriptiontermdimension "month", subscriptionterm 12, "ruby customtext c" "bundle deal", "ruby customnumber c" 1500 00, "ruby customdate c" "2026 03 01", discount 10, products \[ { productsku "enterprise bundle", uom "license/month", quantity 50, addons \[ { productsku "addon support", uom "license/month", quantity 1 }, { productsku "addon storage", uom "gb/month", quantity 200 } ] } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { // custom fields preserved after bundle pricing console log(`custom text ${result quote\['ruby customtext c']}`); // "bundle deal" console log(`custom number ${result quote\['ruby customnumber c']}`); // 1500 00 console log(`custom date ${result quote\['ruby customdate c']}`); // "2026 03 01" // pricing fields calculated normally console log(`total amount $${result quote totalamount}`); console log(`discount ${result quote discount}%`); }) 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" "bundle quote with custom fields", "subscriptionstartdate" "2026 01 01", "subscriptionenddate" "2027 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "ruby customtext c" "bundle deal", "ruby customnumber c" 1500 00, "ruby customdate c" "2026 03 01", "discount" 10, "products" \[ { "productsku" "enterprise bundle", "uom" "license/month", "quantity" 50, "addons" \[ { "productsku" "addon support", "uom" "license/month", "quantity" 1 }, { "productsku" "addon storage", "uom" "gb/month", "quantity" 200 } ] } ] }' the pricing engine calculates bundle totals, applies the 10% header discount to all eligible lines, and returns the custom fields unchanged on the quote header use case 4 line item custom fields custom fields on individual line items are supported directly in the rest request , on the same footing as the apex global methods add a customfields object to any entry in the products array keys are the api names of custom fields on the line object ( quotelineitem for quotes, orderproduct for orders); values are written straight onto the line the product creates customfields works recursively an entry inside addons carries its own customfields onto that add on's line this closes the two step workaround earlier releases had no line level slot in the rest request body, so integrations had to create the quote, read back the line item ids, and then patch each line through the objects api or graphql that second round trip is no longer needed line level customfields is accepted on post /cpq/quotes , post /cpq/quotes\ preview , post /cpq/orders , post /cpq/orders\ preview , and the addlineitems action of the \ update endpoints const quotedata = { opportunityid "006xx000001abc123", name "quote with line item custom fields", subscriptionstartdate "2026 01 01", subscriptionenddate "2027 01 01", subscriptiontermdimension "month", subscriptionterm 12, "ruby customtext c" "header value", // header custom field products \[ { productsku "nue on salesforce", uom "user/month", quantity 10, customfields { // line level custom fields "costcenter c" "cc 1042", "contractref c" "msa 2026 0417" } }, { productsku "enterprise bundle", uom "license/month", quantity 50, customfields { "costcenter c" "cc 2000" }, addons \[ { productsku "addon support", uom "license/month", quantity 1, customfields { "supporttier c" "platinum" } } ] } ] }; const res = await fetch('https //api nue io/cpq/quotes', { method 'post', headers myheaders, body json stringify(quotedata) }); const result = await res json(); console log(result quote\['ruby customtext c']); // "header value" console log(result quotelineitems\[0]\['costcenter c']); // "cc 1042" curl x post 'https //api nue io/cpq/quotes' \\ h 'nue api key your api key here' \\ h 'content type application/json' \\ d '{ "opportunityid" "006xx000001abc123", "name" "quote with line item custom fields", "subscriptionstartdate" "2026 01 01", "subscriptionenddate" "2027 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "products" \[ { "productsku" "nue on salesforce", "uom" "user/month", "quantity" 10, "customfields" { "costcenter c" "cc 1042", "contractref c" "msa 2026 0417" } }, { "productsku" "nue platform", "uom" "user/year", "quantity" 5, "customfields" { "costcenter c" "cc 2000" } } ] }' a field name that does not exist on the line object is rejected it is not silently dropped line level custom fields survive the pricing engine exactly as header custom fields do, and they appear in both preview and commit responses use case 5 custom fields on an existing quote the update quote api docid\ j9w7ufhjvphiej93bx5y9 patches custom fields on a quote that already exists on the header, on existing lines, and on lines you add in the same call note the naming difference between the two slots slot field naming updateheaderfields / updatelineitems → fieldvalues nue field names for standard fields ( quantity , paymentterm ); salesforce api names for custom fields ( costcenter c ) addlineitems → products\[] customfields salesforce api names on the line object curl x post 'https //api nue io/cpq/quotes/0q0cu000001abcxuav\ update' \\ h 'nue api key your api key here' \\ h 'content type application/json' \\ d '{ "iscommit" true, "recalc" "auto", "actions" \[ { "action" "updateheaderfields", "payload" { "fieldvalues" { "region c" "emea" } } }, { "action" "updatelineitems", "payload" { "lineitems" \[ { "lineitemid" "0qlcu00000abcdefgh", "fieldvalues" { "costcenter c" "cc 1042" } } ] } }, { "action" "addlineitems", "payload" { "products" \[ { "productsku" "nue platform", "uom" "user/month", "quantity" 5, "customfields" { "costcenter c" "cc 2000" } } ] } } ] }' setting a plain custom field does not re price the line it is persisted as is a custom field mapped as a line direct quantity tier attribute is the exception changing it can move the resolved pricing tier, so it triggers a re price see quantity tier attributes docid\ plcj0tpent2lihn0h6qgj custom field summary behavior supported notes quote header custom fields (commit) yes include as top level properties in the request body quote header custom fields (preview) yes fields appear in the response, not persisted line item custom fields on create yes customfields object on any entry in products , recursively through addons line item custom fields on add (update api) yes customfields on addlineitems → products\[] line item custom fields on an existing line yes updatelineitems → fieldvalues , keyed by salesforce api name header custom fields on an existing quote yes updateheaderfields → fieldvalues preserved during bundle pricing yes pricing engine does not overwrite custom fields preserved during discount calculation yes custom fields are independent of discount logic triggers a re price only for qta mapped fields a plain custom field is persisted without re pricing field naming conventions convention example notes salesforce custom fields ruby customtext c use the full api name including namespace prefix and c suffix standard custom fields customfield1 use camelcase for non salesforce custom fields date format "2026 06 15" use iso 8601 date format (yyyy mm dd) number format 42 50 use standard json number format boolean format true / false use json boolean values important notes custom field names must not conflict with standard field names (e g , avoid using name , discount , products , opportunityid ) if a custom field name matches a standard field, the standard field behavior takes precedence custom fields that do not exist on the quote object in your org are silently ignored during commit but still appear in preview responses