---
title: Multi-Currency
slug: multi-currency
createdAt: 2026-03-17T21:13:53.778Z
---

# Multi-Currency

The Nue CPQ Quote API supports creating quotes in different currencies when your org has multi-currency enabled. Set the `currencyIsoCode` field at the quote level to control which currency the pricing engine uses for PBE resolution and amount calculations.

## Prerequisites

Before using multi-currency quotes, ensure the following:

1. **Multi-currency is enabled** in your Nue org
2. **Price Book Entries (PBEs) exist** for the target currency -- each product must have a PBE in the requested currency
3. **Currency ISO codes** follow the ISO 4217 standard (e.g., `USD`, `EUR`, `GBP`, `JPY`)

If a product does not have a Price Book Entry for the requested currency, the API returns an error.

## Setting the Currency

Include `currencyIsoCode` as a top-level field in the request body:

```json
{
  "opportunityId": "006xx000001abc123",
  "name": "EUR Quote",
  "currencyIsoCode": "EUR",
  "products": [...]
}
```

The pricing engine resolves PBEs in the specified currency and calculates all amounts in that currency.

### PBE Currency Matching

| Request Currency | PBE Currency                | Result                            |
| ---------------- | --------------------------- | --------------------------------- |
| `"EUR"`          | EUR PBE exists              | EUR PBE is used; amounts in EUR   |
| `"EUR"`          | No EUR PBE                  | Error: `PRICEBOOK_ENTRY_MISMATCH` |
| (omitted)        | Default currency PBE exists | Default org currency is used      |
| (omitted)        | No default PBE              | Error: `PRICEBOOK_ENTRY_MISMATCH` |

## Authentication

```javascript
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");
```

## Use Case 1: EUR Standalone Product

Create a preview quote for a standalone product priced in Euros.

```javascript
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");

const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "EU Enterprise License",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "EUR",
  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(`Currency: ${result.quote.currencyIsoCode}`);  // "EUR"
  console.log(`Total Amount: ${result.quote.totalAmount}`);
})
.catch(error => console.log('Error:', error));
```

```bash
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": "EU Enterprise License",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "EUR",
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 10 }
    ]
  }'
```

The pricing engine resolves the EUR Price Book Entry for `NUE_ON_SALESFORCE` and returns all amounts in Euros.

***

## Use Case 2: USD Baseline Comparison

Create the same quote in USD for side-by-side comparison with the EUR quote.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "US Enterprise License",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "USD",
  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(`Currency: ${result.quote.currencyIsoCode}`);  // "USD"
  console.log(`Total Amount: $${result.quote.totalAmount}`);
})
.catch(error => console.log('Error:', error));
```

```bash
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": "US Enterprise License",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "USD",
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 10 }
    ]
  }'
```

The USD and EUR quotes use different PBEs with potentially different list prices. Compare `totalAmount` values across both responses.

***

## Use Case 3: No PBE for Requested Currency (Error)

If you request a currency for which no Price Book Entry exists, the API returns an error.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "JPY Quote -- No PBE",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "JPY",
  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 => {
  if (result.status === 400) {
    console.log('Error:', result.message);
    // "No Price Book Entry found for product NUE_ON_SALESFORCE with currency JPY"
  }
})
.catch(error => console.log('Error:', error));
```

```bash
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": "JPY Quote -- No PBE",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "JPY",
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 10 }
    ]
  }'
```

**Expected error response:**

```json
{
  "status": 400,
  "error": "Failed to create quote",
  "message": "No Price Book Entry found for product NUE_ON_SALESFORCE with currency JPY"
}
```

***

## Use Case 4: EUR Bundles

Multi-currency works with bundles. All products in the bundle -- parent and add-ons -- must have PBEs in the target currency.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "EUR Bundle Quote",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "EUR",
  products: [
    {
      productSku: "ENTERPRISE_BUNDLE",
      uom: "License/Month",
      quantity: 20,
      addOns: [
        { productSku: "ADDON_SUPPORT", uom: "License/Month", quantity: 1 },
        { productSku: "ADDON_STORAGE", uom: "GB/Month", quantity: 100 }
      ]
    }
  ]
};

fetch('https://api.nue.io/cpq/quotes:preview', {
  method: 'POST',
  headers: myHeaders,
  body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
  console.log(`Currency: ${result.quote.currencyIsoCode}`);  // "EUR"
  console.log(`Bundle total: ${result.quote.totalAmount}`);
  const parent = result.quoteLineItems[0];
  console.log(`Parent: ${parent.totalPrice}`);
  parent.childrenLineItems.forEach(child => {
    console.log(`  ${child.product.sku}: ${child.totalPrice}`);
  });
})
.catch(error => console.log('Error:', error));
```

```bash
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": "EUR Bundle Quote",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "EUR",
    "products": [
      {
        "productSku": "ENTERPRISE_BUNDLE",
        "uom": "License/Month",
        "quantity": 20,
        "addOns": [
          { "productSku": "ADDON_SUPPORT", "uom": "License/Month", "quantity": 1 },
          { "productSku": "ADDON_STORAGE", "uom": "GB/Month", "quantity": 100 }
        ]
      }
    ]
  }'
```

If any add-on is missing an EUR PBE, the entire quote request fails with a `PRICEBOOK_ENTRY_MISMATCH` error.

***

## Use Case 5: EUR with Discounts

Discounts work identically regardless of currency. The discount percentage is applied to the currency-specific list price.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "EUR with Discount",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "EUR",
  discount: 10,
  products: [
    { productSku: "NUE_ON_SALESFORCE", uom: "User/Month", quantity: 10, discount: 15 }
  ]
};

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 (EUR): ${line.listTotalPrice}`);
  console.log(`Discount: ${line.discount}%`);       // 15% (line-level overrides header)
  console.log(`Total price (EUR): ${line.totalPrice}`);
})
.catch(error => console.log('Error:', error));
```

```bash
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": "EUR with Discount",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "EUR",
    "discount": 10,
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 10, "discount": 15 }
    ]
  }'
```

The line-level 15% discount overrides the header-level 10% discount, applied to the EUR list price.

***

## Use Case 6: EUR with Quantity Scaling

Quantity scaling works the same across currencies. The pricing formula `listPrice x quantity x term` uses the currency-specific list price.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "EUR Quantity Scaling",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  currencyIsoCode: "EUR",
  products: [
    { productSku: "NUE_ON_SALESFORCE", uom: "User/Month", quantity: 5 }
  ]
};

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 (EUR): ${line.listUnitPrice}`);
  console.log(`Quantity: ${line.quantity}`);           // 5
  console.log(`Term: 12 months`);
  console.log(`List total: ${line.listTotalPrice}`);   // unitPrice * 5 * 12
  console.log(`Total: ${line.totalPrice}`);
})
.catch(error => console.log('Error:', error));
```

```bash
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": "EUR Quantity Scaling",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "currencyIsoCode": "EUR",
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 5 }
    ]
  }'
```

The `listTotalPrice` is calculated as `EUR listUnitPrice x 5 x 12`.

***

## Use Case 7: Missing currencyIsoCode in Multi-Currency Org

When `currencyIsoCode` is omitted in a multi-currency org, the pricing engine falls back to the org's default currency.

```javascript
const quoteData = {
  opportunityId: "006xx000001abc123",
  name: "Default Currency Fallback",
  subscriptionStartDate: "2026-01-01",
  subscriptionEndDate: "2027-01-01",
  subscriptionTermDimension: "Month",
  subscriptionTerm: 12,
  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(`Currency: ${result.quote.currencyIsoCode}`);  // Org's default (e.g., "USD")
  console.log(`Total Amount: ${result.quote.totalAmount}`);
})
.catch(error => console.log('Error:', error));
```

```bash
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": "Default Currency Fallback",
    "subscriptionStartDate": "2026-01-01",
    "subscriptionEndDate": "2027-01-01",
    "subscriptionTermDimension": "Month",
    "subscriptionTerm": 12,
    "products": [
      { "productSku": "NUE_ON_SALESFORCE", "uom": "User/Month", "quantity": 10 }
    ]
  }'
```

The response's `currencyIsoCode` reflects the org's default currency. PBE resolution uses that default currency.

## Multi-Currency Behavior Summary

| Behavior              | Description                                                         |
| --------------------- | ------------------------------------------------------------------- |
| **Currency field**    | Set `currencyIsoCode` at the quote level (top-level property)       |
| **PBE resolution**    | Engine resolves PBEs matching the requested currency                |
| **All-or-nothing**    | Every product in the quote must have a PBE in the target currency   |
| **Discount behavior** | Percentage discounts work identically across currencies             |
| **Amount discounts**  | Fixed `discountAmount` values are in the specified currency         |
| **Default fallback**  | If `currencyIsoCode` is omitted, the org's default currency is used |
| **Bundle support**    | All bundle components must have PBEs in the target currency         |

## Troubleshooting

| Symptom                          | Likely Cause                             | Resolution                                                    |
| -------------------------------- | ---------------------------------------- | ------------------------------------------------------------- |
| `PRICEBOOK_ENTRY_MISMATCH` error | No PBE exists for the requested currency | Create PBEs in the target currency for all products           |
| Partial bundle failure           | One add-on missing a currency PBE        | Ensure all bundle components have PBEs in the target currency |
| Unexpected currency in response  | `currencyIsoCode` not set in request     | Explicitly set `currencyIsoCode` in the request body          |
| Wrong amounts                    | PBE list price not set for currency      | Verify the list price on the currency-specific PBE            |
