---
name: nue-rest-change-order
description: Specialist in Nue REST API for creating change orders and change quotes (POST /cpq/change-order). Use when generating curl commands or REST payloads for lifecycle changes to existing subscriptions — renewals, price adjustments, quantity changes, cancellations, cross-sells, upgrades, reconfiguration, term updates, and more.
user-invocable: false
---

# Change Order — REST API

Given a business scenario involving existing subscriptions, produce a complete REST API call (curl or JSON payload) that creates the appropriate change quote or change order via the Nue Platform API. Validate change type selection, asset number usage, and field names against the rules below.

> **Note**: This skill covers the **REST API** (`/cpq/change-order`). For the Apex global methods (`Ruby.GlobalChangeOrderService.changeOrder`), see the companion [Apex Skill](../nue-change-quote-order/SKILL.md).

> **Note**: This skill covers **lifecycle changes** — modifications to existing subscriptions. For creating initial quotes and orders with net-new products, see the [Create Quote/Order REST Skill](nue-rest-create-quote-order.md).

---

## Endpoint

| Operation | Endpoint | Description |
|-----------|----------|-------------|
| Change Order | `POST /cpq/change-order` | Create a change quote or change order |

**Base URLs:**
- Production: `https://api.nue.io`
- QA3: `https://api.qa3.nue.io`
- Perftest: `https://api.perftest.nue.io`

**Authentication:**
```
nue-api-key: YOUR_API_KEY
Content-Type: application/json
```

---

## Request Structure

```json
{
  "options": {
    "activateOrder": true,
    "proceedOption": "CreateOrder",
    "opportunityId": "006xx..."
  },
  "assetChanges": [
    { "changeType": "Renew", "assetNumber": "SUB-001234", ... },
    { "changeType": "AdjustPrice", "assetNumber": "SUB-001234", ... }
  ]
}
```

### Options (Required)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `activateOrder` | boolean | Yes | `true` = activate immediately; `false` = draft |
| `proceedOption` | string | Yes | `"CreateOrder"` (immediate) or `"CreateQuote"` (approval workflow) |
| `opportunityId` | string | No | Associate quote with Salesforce Opportunity (`CreateQuote` only) |

### Asset Changes Array (Required)

Each entry in `assetChanges` must include `changeType` and type-specific fields.

---

## Supported Change Types

### Renew

Extend a subscription for another term.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"Renew"` |
| `assetNumber` | string | Yes | Subscription identifier (e.g., `"SUB-086067"`) |
| `renewalTerm` | number | Yes* | Renewal duration in months. *Required unless `switchToEvergreen` |
| `switchToEvergreen` | boolean | No | Convert to evergreen subscription (no end date) |

```json
{ "changeType": "Renew", "assetNumber": "SUB-086067", "renewalTerm": 12 }
```

```json
{ "changeType": "Renew", "assetNumber": "SUB-086067", "switchToEvergreen": true }
```

---

### AdjustPrice

Change the price on an existing subscription — discount, uplift, or fixed price.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"AdjustPrice"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `startDate` | date | Yes | Effective date of price change |
| `endDate` | date | No | End date (for time-bounded adjustments) |
| `discount` | object | No | Percentage-based adjustment |
| `discount.discountPercentage` | number | — | Positive = discount, **negative = uplift** (e.g., `-5` = 5% price increase) |
| `discount.applyToChildren` | boolean | — | `true` = cascade to all bundle children |
| `netSalesPrice` | number | No | Fixed price override (alternative to percentage) |

**Percentage discount:**
```json
{
  "changeType": "AdjustPrice",
  "assetNumber": "SUB-086067",
  "startDate": "2026-01-01",
  "discount": { "discountPercentage": 20, "applyToChildren": true }
}
```

**Price uplift (negative discount):**
```json
{
  "changeType": "AdjustPrice",
  "assetNumber": "SUB-086067",
  "startDate": "2026-01-01",
  "discount": { "discountPercentage": -5, "applyToChildren": true }
}
```

**Fixed price override:**
```json
{
  "changeType": "AdjustPrice",
  "assetNumber": "SUB-086067",
  "netSalesPrice": 1200.00,
  "startDate": "2026-01-01",
  "endDate": "2026-12-31"
}
```

---

### UpdateQuantity

Change the number of seats/units. **Quantity is a delta** (not absolute).

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"UpdateQuantity"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `quantity` | number | Yes | **Delta**: positive to add, negative to remove |
| `startDate` | date | Yes | Effective date |

```json
{ "changeType": "UpdateQuantity", "assetNumber": "SUB-086067", "quantity": 25, "startDate": "2026-01-01" }
```

> **REST vs Apex difference**: The REST API uses **delta** quantity (e.g., +25 to add 25 seats). The Apex `GlobalUpdateQuantityRequest.quantity` uses **new total**. Do not confuse them.

---

### Cancel

Terminate a subscription.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"Cancel"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `cancellationDate` | date | Yes | Effective cancellation date |

```json
{ "changeType": "Cancel", "assetNumber": "SUB-086067", "cancellationDate": "2026-01-01" }
```

---

### UpdateTerm

Extend or shorten the subscription term.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"UpdateTerm"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `term` | number | Yes | Months to add |

```json
{ "changeType": "UpdateTerm", "assetNumber": "SUB-086067", "term": 6 }
```

---

### CoTerm

Align a subscription's end date to a target date.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"CoTerm"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `coTermDate` | date | Yes | Target end date |

```json
{ "changeType": "CoTerm", "assetNumber": "SUB-086067", "coTermDate": "2026-12-31" }
```

---

### Upgrade

Replace a product with a higher-tier product.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"Upgrade"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `targetPriceBookEntryId` | string | Yes | PBE ID of the upgrade target product |
| `startDate` | date | Yes | Effective date |

```json
{
  "changeType": "Upgrade",
  "assetNumber": "SUB-086067",
  "targetPriceBookEntryId": "01uRu000004SyY8IAK",
  "startDate": "2026-01-15"
}
```

---

### Reconfigure

Add or remove add-ons within a bundle via `addOnChanges`.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"Reconfigure"` |
| `assetNumber` | string | Yes | Bundle subscription identifier |
| `startDate` | date | Yes | Effective date |
| `addOnChanges` | array | Yes | List of add-on modifications |

Each `addOnChanges` entry:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"NewProduct"` (add) or `"Cancel"` (remove) |
| `productOptionId` | string | Yes | Product Option record ID |
| `priceBookEntryId` | string | No | Required for dynamic options |
| `productOptionQuantity` | number | Yes | Add-on quantity |
| `term` | number | No | Override parent term |

```json
{
  "changeType": "Reconfigure",
  "assetNumber": "SUB-086067",
  "startDate": "2026-01-15",
  "addOnChanges": [
    {
      "changeType": "NewProduct",
      "productOptionId": "a8fRu0000002bOmIAI",
      "priceBookEntryId": "01uRu000004SyY7IAK",
      "productOptionQuantity": 3,
      "term": 12
    }
  ]
}
```

---

### ConvertFreeTrial

Convert a trial subscription to paid or evergreen.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"ConvertFreeTrial"` |
| `assetNumber` | string | Yes | Trial subscription identifier |
| `startDate` | date | Yes | Paid subscription start date |
| `term` | number | No | Paid term in months |
| `switchToEvergreen` | boolean | No | Convert to evergreen instead |
| `overrideTrialEnd` | boolean | No | End trial early |

```json
{
  "changeType": "ConvertFreeTrial",
  "assetNumber": "SUB-086067",
  "startDate": "2026-01-15",
  "term": 12,
  "overrideTrialEnd": true
}
```

---

### UpdateField

Update editable fields on an existing subscription without changing its commercial terms.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"UpdateField"` |
| `assetNumber` | string | Yes | Subscription identifier |
| `startDate` | date | No | Effective date of the field update |
| `fieldsToUpdate` | array | Yes | List of `{ fieldApiName, newValue }` pairs |
| `fieldsToUpdate[].fieldApiName` | string | Yes | Field API name. **Must be org-qualified on a namespaced org** (e.g. `Ruby__BillingPeriod__c`); an unqualified name (`BillingPeriod__c`) is pruned as unrepresentable and produces no change |
| `fieldsToUpdate[].newValue` | string | Yes | New value as a string (coerced to the field's type on the Salesforce side) |

```json
{
  "changeType": "UpdateField",
  "assetNumber": "SUB-086067",
  "startDate": "2026-07-21",
  "fieldsToUpdate": [
    { "fieldApiName": "Ruby__BillingPeriod__c", "newValue": "Quarter" }
  ]
}
```

---

### NewProduct (Cross-Sell)

Add a net-new product to the account.

**Critical constraint**: `NewProduct` **cannot be the only change** — it must be accompanied by at least one other change type (e.g., Cancel, Renew, UpdateQuantity).

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"NewProduct"` |
| `priceBookEntryId` | string | Yes | PBE ID of the new product |
| `startDate` | date | Yes | Effective start date |
| `quantity` | number | Yes | Must be positive |
| `term` | number | One of* | Subscription months. *Either `term` or `coTermAsset` required |
| `coTermAsset` | string | One of* | Align end date to this subscription's end date |
| `netSalesPrice` | number | No | Override calculated price |
| `autoRenew` | boolean | No | Auto-renewal flag |
| `defaultRenewalTerm` | number | No | Renewal months |
| `billingTiming` | string | No | `"In Advance"` or `"In Arrears"` |
| `billingPeriod` | string | No | `"Month"` or `"Year"` |
| `billCycleDay` | string | No | Day of billing cycle |
| `priceTagIds` | array | No | Discount tag IDs |
| `priceTagCodes` | array | No | Discount tag codes |
| `description` | string | No | Custom description |
| `customFields` | object | No | Custom field values |
| `addOns` | array | No | Bundle add-ons (recursive) |

**Add-On fields** (within `addOns` array):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `changeType` | string | Yes | `"NewProduct"` |
| `productOptionId` | string | Conditional | For configured add-ons |
| `priceBookEntryId` | string | Conditional | For dynamic add-ons |
| `productOptionQuantity` | number | Yes | Add-on quantity |
| `subscriptionTerm` | number | No | Override parent term |
| `coTermAsset` | string | No | Align to existing subscription |
| `netSalesPrice` | number | No | Override price |
| `addOns` | array | No | Nested add-ons (recursive) |

---

### Cross-Sell via top-level `products` array

Instead of a `NewProduct` entry inside `assetChanges`, you can add brand-new products through a **top-level `products` array** on the change-order request — the same shape as adding products on a new quote (resolve by `productSku` or `productName`), with the new products' metrics rolling up to the change order header. This is the recommended path for straightforward cross-sell and cancel-and-replace.

```json
{
  "options": { "proceedOption": "CreateOrder", "activateOrder": false },
  "assetChanges": [
    { "changeType": "UpdateQuantity", "assetNumber": "SUB-086067", "quantity": 1, "startDate": "2026-08-01" }
  ],
  "products": [
    { "productSku": "SKU-ADDON-01", "uom": "Each", "quantity": 1, "startDate": "2026-08-01", "subscriptionTerm": 12 }
  ]
}
```

Each `products` line may carry exactly **one** of `discount` (percentage), `discountAmount` (fixed), or `netSalesPrice` (unit-price override) — sending more than one returns 400. Use `productName` in place of `productSku` to resolve by name, and `addOns` for bundle children.

**Cancel + Replace** — combine a `Cancel` asset change with a `products` entry for the replacement:

```json
{
  "options": { "proceedOption": "CreateOrder", "activateOrder": true },
  "assetChanges": [
    { "changeType": "Cancel", "assetNumber": "SUB-086067", "cancellationDate": "2026-08-01" }
  ],
  "products": [
    { "productName": "Nue Rise Edition", "quantity": 100, "subscriptionTerm": 36 }
  ]
}
```

---

## Complete Examples

### Example 1: Simple Renewal

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      { "changeType": "Renew", "assetNumber": "SUB-001234", "renewalTerm": 12 }
    ]
  }'
```

### Example 2: Renewal with Price Uplift

Renew for 12 months with a 3% price increase cascaded to all bundle children.

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      { "changeType": "Renew", "assetNumber": "SUB-001234", "renewalTerm": 12 },
      {
        "changeType": "AdjustPrice",
        "assetNumber": "SUB-001234",
        "startDate": "2026-01-01",
        "discount": { "discountPercentage": -3, "applyToChildren": true }
      }
    ]
  }'
```

### Example 3: Escalating Uplift Over 3-Year Renewal

3% in year 1, 5% in year 2, 8% in year 3.

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      { "changeType": "Renew", "assetNumber": "SUB-001234", "renewalTerm": 36 },
      {
        "changeType": "AdjustPrice", "assetNumber": "SUB-001234",
        "startDate": "2026-01-01",
        "discount": { "discountPercentage": -3, "applyToChildren": true }
      },
      {
        "changeType": "AdjustPrice", "assetNumber": "SUB-001234",
        "startDate": "2027-01-01",
        "discount": { "discountPercentage": -5, "applyToChildren": true }
      },
      {
        "changeType": "AdjustPrice", "assetNumber": "SUB-001234",
        "startDate": "2028-01-01",
        "discount": { "discountPercentage": -8, "applyToChildren": true }
      }
    ]
  }'
```

### Example 4: Seat Expansion

Add 25 seats to an existing subscription.

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      {
        "changeType": "UpdateQuantity",
        "assetNumber": "SUB-005678",
        "quantity": 25,
        "startDate": "2026-01-01"
      }
    ]
  }'
```

### Example 5: Cancel + Cross-Sell New Product

Replace one subscription with a new product, co-termed to another subscription.

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      {
        "changeType": "Cancel",
        "assetNumber": "SUB-000192",
        "cancellationDate": "2026-02-15"
      },
      {
        "changeType": "NewProduct",
        "priceBookEntryId": "01uRu000004SyY8IAK",
        "startDate": "2026-02-15",
        "quantity": 5,
        "coTermAsset": "SUB-000200"
      }
    ]
  }'
```

### Example 6: NewProduct with Bundle Add-Ons

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": true,
      "proceedOption": "CreateOrder"
    },
    "assetChanges": [
      {
        "changeType": "Cancel",
        "assetNumber": "SUB-000192",
        "cancellationDate": "2026-02-15"
      },
      {
        "changeType": "NewProduct",
        "priceBookEntryId": "01uRu000004SyY8IAK",
        "startDate": "2026-02-15",
        "quantity": 3,
        "term": 12,
        "addOns": [
          {
            "changeType": "NewProduct",
            "productOptionId": "a0jRu0000002bOmIAI",
            "productOptionQuantity": 3
          },
          {
            "changeType": "NewProduct",
            "productOptionId": "a0jRu0000002bOnIAI",
            "priceBookEntryId": "01uRu000004SyY7IAK",
            "productOptionQuantity": 10
          }
        ]
      }
    ]
  }'
```

### Example 7: Create Change Quote for Review

Use `CreateQuote` to generate a quote for approval workflow instead of immediate activation.

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": false,
      "proceedOption": "CreateQuote",
      "opportunityId": "006xx000003abc123"
    },
    "assetChanges": [
      { "changeType": "Renew", "assetNumber": "SUB-001234", "renewalTerm": 12 }
    ]
  }'
```

### Example 8: NewProduct with Price Override

```bash
curl -X POST "https://api.nue.io/cpq/change-order" \
  -H "nue-api-key: ${NUE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "activateOrder": false,
      "proceedOption": "CreateQuote"
    },
    "assetChanges": [
      {
        "changeType": "Cancel",
        "assetNumber": "SUB-000192",
        "cancellationDate": "2026-02-15"
      },
      {
        "changeType": "NewProduct",
        "priceBookEntryId": "01uRu000004SyY8IAK",
        "startDate": "2026-02-15",
        "quantity": 3,
        "term": 12,
        "netSalesPrice": 450.00,
        "addOns": [
          {
            "changeType": "NewProduct",
            "productOptionId": "a0jRu0000002bOmIAI",
            "productOptionQuantity": 10,
            "netSalesPrice": 25.00
          }
        ]
      }
    ]
  }'
```

---

## Response Schema

```json
{
  "headerObjectIds": ["801xx000003ABCD"],
  "messages": ["Subscription SUB-086067 renewed for 12 months"],
  "assets": [
    {
      "Id": "02ixx000005MNOP",
      "Name": "SUB-086067",
      "Product": "Premium Plan",
      "MRR": 299.00
    }
  ]
}
```

---

## Critical Rules

1. **Asset numbers are the primary identifier** — Change requests operate on `assetNumber` (the subscription identifier), not product SKUs.

2. **Quantity is a delta in REST** — `UpdateQuantity.quantity` is the **change amount** (+25 to add 25 seats, -10 to remove 10). This differs from the Apex API which uses absolute totals.

3. **Price uplift uses negative discount** — To increase price by X%, set `discountPercentage: -X`. Positive = discount, negative = uplift.

4. **`applyToChildren` cascades to bundle children** — Set `applyToChildren: true` on `AdjustPrice` to cascade the price change to all child line items.

5. **NewProduct cannot stand alone** — It must be paired with at least one other change type (Cancel, Renew, UpdateQuantity, etc.).

6. **`CreateQuote` vs `CreateOrder`** — Use `CreateQuote` when changes need review/approval. Use `CreateOrder` for immediate processing.

7. **`activateOrder: true` is irreversible** — Changes are applied immediately to subscriptions, assets, and entitlements.

---

## Interaction Patterns

| User Says | API Construct |
|-----------|---------------|
| "renew for 12 months" | `Renew` with `renewalTerm: 12` |
| "renew with 5% price increase" | `Renew` + `AdjustPrice` with `discountPercentage: -5` |
| "add 10 seats" | `UpdateQuantity` with `quantity: 10` |
| "remove 5 seats" | `UpdateQuantity` with `quantity: -5` |
| "cancel this subscription" | `Cancel` with `cancellationDate` |
| "upgrade to premium" | `Upgrade` with `targetPriceBookEntryId` |
| "add an add-on to the bundle" | `Reconfigure` with `addOnChanges` |
| "add a new product" | `NewProduct` (must pair with another change) |
| "co-term the new product" | `NewProduct` with `coTermAsset` |
| "convert trial to paid" | `ConvertFreeTrial` with `term` |
| "create a quote for review" | `proceedOption: "CreateQuote"` |
| "activate immediately" | `proceedOption: "CreateOrder"`, `activateOrder: true` |

---

## Mistakes to Avoid

| Mistake | Why It Fails | Correct Approach |
|---------|-------------|-----------------|
| Using product SKU instead of asset number | Change orders operate on existing subscriptions | Query subscriptions to get `assetNumber` |
| Setting `discountPercentage` to positive for uplift | Positive = discount (price decrease) | Use negative value (e.g., `-5` = 5% increase) |
| Using absolute quantity instead of delta | REST API expects change amount | Use delta: `+25` to add 25 seats |
| NewProduct as the only change | API rejects standalone NewProduct | Pair with Cancel, Renew, UpdateQuantity, etc. |
| Using `CreateOrder` + `activateOrder: true` for review | Changes are applied immediately | Use `CreateQuote` for changes needing review |
| Omitting `priceBookEntryId` on NewProduct | Required for new products in change orders | Query PBE by SKU + UOM and pass the ID |
| Confusing REST delta quantity with Apex absolute quantity | Different APIs use different conventions | REST = delta, Apex = new total |

---

## Reference Documentation

- [Change Orders](https://api-docs.nue.io/change-orders)
- [Creating Draft Change Orders](https://api-docs.nue.io/creating-draft-change-orders)
- [Change Order Data Reference](https://api-docs.nue.io/change-order-data-reference)
- [Orders Overview](https://api-docs.nue.io/orders-overview)
- [Activate Draft Orders](https://api-docs.nue.io/activate-draft-orders)
