---
title: Fetching Subscription Data
slug: fetching-subscription-data
docTags: 
createdAt: 2026-02-13T04:24:47.243Z
---

This guide provides comprehensive instructions for retrieving subscription data using the Nue Lifecycle Management API. Learn how to fetch customer subscriptions, create point-in-time snapshots, analyze upcoming changes, and implement efficient subscription data retrieval patterns.

## Prerequisites

Before you begin, ensure you have:

- A valid Nue API key with subscription read permissions
- Customer IDs for the subscriptions you want to retrieve
- Basic understanding of REST APIs and JSON
- Familiarity with subscription data structures and lifecycle

## Authentication

All subscription retrieval operations require authentication using your Nue API key in the `nue-api-key` header:

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

## REST Endpoints

The Nue API provides REST endpoints for flexible subscription data access:

```javascript
// Global subscription endpoints
GET https://api.nue.io/subscriptions                    // Get all subscriptions with pagination
GET https://api.nue.io/subscriptions/{subscriptionName} // Get a specific subscription by name

// Customer-scoped subscription endpoints  
GET https://api.nue.io/customers/{customerId}/subscriptions                    // Get subscriptions for a customer
GET https://api.nue.io/customers/{customerId}/subscriptions/{subscriptionName} // Get a specific subscription for a customer
```

### Filtering

Subscription endpoints support filtering using query parameters:

**Query Parameters**:

- `customerIds` - Array of customer IDs to filter by
- `name` - Subscription name to search for
- `status` - Filter by status: `Active`, `Expired`, `Canceled`, `Draft`
- `bundled` - Whether the subscription is a bundled component of a parent bundle (true/false)
- `subscriptionLevel` - Depth in the bundle hierarchy: `1` for a top-level subscription, `2` and above for nested options. Accepts a comma-separated list
- `snapshotDate` - Point-in-time snapshot date (YYYY-MM-DD)
- `history` - Include subscription history (true/false)
- `includes` - Include related data (e.g., `product`, `pricetags`)
- `page` - Page number for pagination
- `limit` - Number of results per page

Beyond the parameters above, any field on the subscription object can be used as an equality filter, for example `?quantity=5` or `?autoRenew=true`. Unknown field names and values of the wrong type are rejected with `400` rather than ignored; see [Filtering by Bundle Structure](docId\:coWtof7I3OE2Cw11lVmx2) for the details.

## Basic Subscription Retrieval

### Fetch All Subscriptions for Customer

**Try it now:** [Fetch Subscriptions →](https://api-docs.nue.io/fetch-subscriptions)

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

// Fetch all subscriptions for a customer
const customerIds = ["d2e04653-ae90-49df-a986-134cf64f6d03"];
const encodedCustomerIds = encodeURIComponent(JSON.stringify(customerIds));

fetch(`https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}`, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  console.log('Subscriptions retrieved successfully:', result);
  
  if (result.status === 'SUCCESS' && result.data) {
    console.log(`Found ${result.data.length} subscriptions for customer`);
    
    // Display subscription summary
    result.data.forEach((subscription, index) => {
      console.log(`\n${index + 1}. ${subscription.name || subscription.id}`);
      console.log(`   Status: ${subscription.status}`);
      console.log(`   Product: ${subscription.productId}`);
      console.log(`   Quantity: ${subscription.quantity}`);
      console.log(`   Start Date: ${subscription.subscriptionStartDate}`);
      console.log(`   End Date: ${subscription.subscriptionEndDate}`);
      console.log(`   Auto Renew: ${subscription.autoRenew}`);
      console.log(`   Total Value: $${subscription.totalAmount || subscription.tcv}`);
      console.log(`   List Price: $${subscription.listPrice}`);
      console.log(`   Sales Price: $${subscription.salesPrice}`);
      
      // Display term information
      if (subscription.subscriptionTerm) {
        console.log(`   Term: ${subscription.subscriptionTerm} months`);
      }
      
      // Display billing information
      if (subscription.billingPeriod) {
        console.log(`   Billing Period: ${subscription.billingPeriod}`);
      }
      if (subscription.billingTiming) {
        console.log(`   Billing Timing: ${subscription.billingTiming}`);
      }
      if (subscription.nextBillingDate) {
        console.log(`   Next Billing: ${subscription.nextBillingDate}`);
      }
    });
  }
})
.catch(error => console.log('Error:', error));
```

### Fetch Subscriptions for Multiple Customers

Retrieve subscriptions for multiple customers in a single API call:

```javascript
// Fetch subscriptions for multiple customers
const customerIds = [
  "d2e04653-ae90-49df-a986-134cf64f6d03",
  "cc5e1f0f-5e14-48cc-ab98-9e5b191aa46f",
  "f1b2c3d4-e5f6-7890-abcd-ef1234567890"
];

const encodedCustomerIds = encodeURIComponent(JSON.stringify(customerIds));

fetch(`https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}`, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS') {
    console.log(`Retrieved subscriptions for ${customerIds.length} customers`);
    
    // Group subscriptions by customer
    const subscriptionsByCustomer = {};
    
    result.data.forEach(subscription => {
      const customerId = subscription.customerId;
      if (!subscriptionsByCustomer[customerId]) {
        subscriptionsByCustomer[customerId] = [];
      }
      subscriptionsByCustomer[customerId].push(subscription);
    });
    
    // Display grouped results
    Object.keys(subscriptionsByCustomer).forEach(customerId => {
      const subscriptions = subscriptionsByCustomer[customerId];
      console.log(`\n--- Customer ${customerId} ---`);
      console.log(`Subscriptions: ${subscriptions.length}`);
      
      // Calculate totals
      const totalValue = subscriptions.reduce((sum, sub) => sum + (sub.totalAmount || 0), 0);
      const activeCount = subscriptions.filter(s => s.status === 'Active').length;
      
      console.log(`Active: ${activeCount}/${subscriptions.length}`);
      console.log(`Total Value: $${totalValue.toLocaleString()}`);
      
      subscriptions.forEach(subscription => {
        console.log(`  • ${subscription.name || subscription.id} - ${subscription.status} - $${subscription.totalAmount || 0}`);
      });
    });
  }
})
.catch(error => console.log('Error:', error));
```

## Filtered Subscription Retrieval

### Fetch Active Subscriptions Only

Filter subscriptions by status to retrieve only active subscriptions:

```javascript
const customerIds = ["d2e04653-ae90-49df-a986-134cf64f6d03"];
const encodedCustomerIds = encodeURIComponent(JSON.stringify(customerIds));

// Fetch only active subscriptions
const url = `https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}&status=Active`;

fetch(url, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS') {
    console.log('🟢 Active Subscriptions Retrieved');
    
    if (result.data && result.data.length > 0) {
      result.data.forEach(subscription => {
        console.log(`\n📦 ${subscription.name || subscription.id}`);
        console.log(`   Product: ${subscription.productId}`);
        console.log(`   Status: ${subscription.status}`);
        console.log(`   Quantity: ${subscription.quantity}`);
        console.log(`   Current Period: ${subscription.subscriptionStartDate} to ${subscription.subscriptionEndDate}`);
        console.log(`   Monthly Value: $${(subscription.totalAmount / (subscription.subscriptionTerm || 12)).toFixed(2)}`);
        console.log(`   Auto Renew: ${subscription.autoRenew ? 'Yes' : 'No'}`);
        
        // Show renewal information
        if (subscription.renewalTerm) {
          console.log(`   Renewal Term: ${subscription.renewalTerm} months`);
        }
        
        // Show bundling information
        if (subscription.bundled) {
          console.log(`   Bundled: Yes (Level ${subscription.subscriptionLevel})`);
        }
      });
    } else {
      console.log('No active subscriptions found for this customer');
    }
  }
})
.catch(error => console.log('Error:', error));
```

### Fetch Specific Subscription by Name

Retrieve a specific subscription using its name:

```javascript
const subscriptionName = "Enterprise Software License - Acme Corp";
const encodedName = encodeURIComponent(subscriptionName);

fetch(`https://api.nue.io/subscriptions?name=${encodedName}`, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS' && result.data.length > 0) {
    const subscription = result.data[0];
    
    console.log('🎯 Specific Subscription Retrieved');
    console.log(`Name: ${subscription.name}`);
    console.log(`ID: ${subscription.id}`);
    console.log(`Customer: ${subscription.customerId}`);
    console.log(`Status: ${subscription.status}`);
    console.log(`Product: ${subscription.productId}`);
    console.log(`Quantity: ${subscription.quantity}`);
    console.log(`Total Contract Value: $${subscription.tcv}`);
    console.log(`Annual Contract Value: $${subscription.totalACV}`);
    console.log(`Subscription Period: ${subscription.subscriptionStartDate} to ${subscription.subscriptionEndDate}`);
    
    if (subscription.externalId) {
      console.log(`External ID: ${subscription.externalId}`);
    }
  } else {
    console.log('Subscription not found');
  }
})
.catch(error => console.log('Error:', error));
```

### Filtering by Bundle Structure

When a customer buys a bundle, Nue creates one subscription for the bundle itself and one for every option underneath it. A customer with a handful of bundles can easily own several dozen subscription rows, most of which are components rather than things the customer thinks of as purchases.

Two parameters let you ask for the rows you actually want instead of fetching everything and filtering client-side:

| Parameter           | Type    | Meaning                                                                                                                           |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `bundled`           | boolean | Whether the subscription is a bundled component priced as part of its parent.                                                     |
| `subscriptionLevel` | integer | Depth in the bundle hierarchy. `1` is a top-level subscription, `2` is an option inside it, `3` an option inside that, and so on. |

To show a customer what they bought, ask for the top level only:

```javascript
const url = `https://api.nue.io/subscriptions?customerId=${customerId}&subscriptionLevel=1`;

fetch(url, { method: 'GET', headers: myHeaders })
.then(response => response.json())
.then(result => {
  console.log(`Top-level subscriptions: ${result.data.length}`);
  result.data.forEach(s => console.log(`  ${s.name}: qty ${s.quantity}`));
})
.catch(error => console.log('Error:', error));
```

`subscriptionLevel` accepts a comma-separated list, so `?subscriptionLevel=1,2` returns a bundle and its immediate options but stops before the deeper tiers. The two parameters combine with each other and with every other filter, so `?bundled=true&subscriptionLevel=2` returns only the second-level rows that are priced as part of their parent.

:::hint{type="warning"}
`bundled=false`**&#x20;also matches subscriptions with no value set**

`?bundled=false` returns rows where `bundled` is `false` **or** where it was never populated. This is deliberate, since an unset value means "not a bundled component", but it does mean `bundled=true` and `bundled=false` partition the result set between them, and `bundled=false` may return more rows than a strict equality check would.
:::

### Filters Are Validated, Not Ignored

Any field on the subscription object can be used as an equality filter, not just the parameters listed above. Because of that, an unrecognised parameter cannot be silently discarded, because it is indistinguishable from a genuine field filter that the caller expects to be applied. Requests carrying one are rejected:

| Request                      | Result                                                                                                              |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `?customerId=001...&foo=bar` | `400`. `foo` is not a field on the subscription object                                                              |
| `?subscriptionLevel=abc`     | `400 INVALID_FILTER_VALUE`. *"Invalid value 'abc' for integer field 'subscriptionLevel'. Expected a whole number."* |
| `?bundled=yes`               | `400 INVALID_FILTER_VALUE`. *"Invalid value 'yes' for boolean field 'bundled'. Expected 'true' or 'false'."*        |

Boolean values are case-insensitive (`TRUE` works), but only `true` and `false` are accepted, so `1` and `0` are not. An out-of-range but well-formed integer such as `?subscriptionLevel=99` is a valid filter that simply matches nothing, and an empty value such as `?subscriptionLevel=` is treated as absent.

If you are migrating from an older integration, drop any stray query parameters before upgrading. A request that previously returned `200` while quietly ignoring an unknown parameter will now fail outright.

### Filters That a Snapshot Cannot Apply

`snapshotDate` reconstructs each subscription as it stood on a past date, which means some fields are recalculated rather than read from the stored row. A filter on one of those fields cannot be pushed down into the query.

Rather than dropping it silently, the response tells you:

```javascript
const url = `https://api.nue.io/subscriptions?customerId=${customerId}`
  + `&snapshotDate=2026-01-01&quantity=5`;

fetch(url, { method: 'GET', headers: myHeaders })
.then(response => response.json())
.then(result => {
  // 207 PARTIAL_SUCCESS: the snapshot was produced, one filter was not applied
  console.log(result.status);

  result.warnings
    .filter(w => w.code === 'FILTER_NOT_SUPPORTED_WITH_SNAPSHOT')
    .forEach(w => console.log(w.message));
})
.catch(error => console.log('Error:', error));
```

The request returns `207 PARTIAL_SUCCESS` with a `FILTER_NOT_SUPPORTED_WITH_SNAPSHOT` warning naming the filters that were skipped. Treat any `207` as "the rows are right but narrower filtering did not happen" and apply the remaining condition yourself.

`bundled` and `subscriptionLevel` are both stored fields, so they apply normally alongside `snapshotDate` and do not trigger this warning.

## Including Related Data

### Fetch Subscriptions with Product Details

Include product information in the subscription response:

```javascript
const customerIds = ["d2e04653-ae90-49df-a986-134cf64f6d03"];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));

// Include product details in the response
const urlWithProducts = `https://api.nue.io/subscriptions?customerIds=${encodedIds}&includes=product`;

fetch(urlWithProducts, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS' && result.data) {
    result.data.forEach(subscription => {
      console.log(`\n📦 Subscription: ${subscription.name || subscription.id}`);
      console.log(`   Status: ${subscription.status}`);
      console.log(`   Quantity: ${subscription.quantity}`);
      console.log(`   Value: $${subscription.totalAmount}`);
      
      // Display product information if included
      if (subscription.product) {
        console.log(`\n   📋 Product Details:`);
        console.log(`     Name: ${subscription.product.name}`);
        console.log(`     SKU: ${subscription.product.sku}`);
        console.log(`     Category: ${subscription.product.productCategory}`);
        console.log(`     Price Model: ${subscription.product.priceModel}`);
      }
      
      // Display pricing tags if included
      if (subscription.pricetags && subscription.pricetags.length > 0) {
        console.log(`\n   🏷️  Applied Price Tags:`);
        subscription.pricetags.forEach(tag => {
          console.log(`     • ${tag.name}: ${tag.type} - ${tag.value}`);
        });
      }
    });
  }
})
.catch(error => console.log('Error:', error));
```

### Controlling How Much Product Detail Is Returned

By default `includes=product` returns the complete product, including its full product option graph. For a bundle with a deep option tree that graph is usually far larger than the rest of the response, and if you only need to identify which product a subscription is on, you are paying for data you will not read.

Pass `productDetail=root` to get the product's own identity and pricing without the option graph:

```javascript
const urlRootDetail = `https://api.nue.io/subscriptions?customerIds=${encodedIds}`
  + `&includes=product&productDetail=root`;

fetch(urlRootDetail, { method: 'GET', headers: myHeaders })
.then(response => response.json())
.then(result => {
  result.data.forEach(subscription => {
    const p = subscription.product;
    if (p) {
      // Still present: identity and pricing
      console.log(`${subscription.name}: ${p.sku} (${p.priceModel})`);
      console.log(`  price book entries: ${p.priceBookEntries.length}`);

      // Not present: productOptions and productFeatures
    }
  });
})
.catch(error => console.log('Error:', error));
```

What each value returns:

| Value            | Product content                                                                                                                                 |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `full` (default) | The complete product, including `productOptions` and `productFeatures` and everything nested beneath them.                                      |
| `root`           | `id`, `sku`, `name`, `priceModel`, `status`, `publishStatus`, `uom` and `priceBookEntries`. `productOptions` and `productFeatures` are omitted. |

Notes:

- `productDetail` requires `includes=product`. Sending it without that returns `400 INVALID_PARAMETER_COMBINATION`. It is not ignored.
- Any value other than `full` or `root` returns `400 INVALID_PARAMETER`. The value is case-insensitive, so `ROOT` and `Root` both work, and an empty `productDetail=` is treated as `full`.
- In `root` mode the `productOptions` and `productFeatures` keys are absent from the product object rather than present and empty, so check for the key before iterating.
- Pricing is unaffected. `priceBookEntries` is returned in full in both modes.

Use `root` for subscription lists, renewal views, and anywhere you are displaying what a customer already owns. Use `full` when you need the sellable configuration, for example when building a change order against the bundle.

### Fetch with All Available Data

Include all available related data:

```javascript
// Include all available data types
const urlWithAll = `https://api.nue.io/subscriptions?customerIds=${encodedIds}&includes=product,pricetags`;

fetch(urlWithAll, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS' && result.data) {
    result.data.forEach(subscription => {
      console.log(`\n🎯 Complete Subscription Details: ${subscription.name || subscription.id}`);
      console.log(`   Status: ${subscription.status}`);
      console.log(`   Customer: ${subscription.customerId}`);
      console.log(`   Period: ${subscription.subscriptionStartDate} to ${subscription.subscriptionEndDate}`);
      
      // Financial Summary
      console.log(`\n   💰 Financial Details:`);
      console.log(`     List Price: $${subscription.listPrice || 0}`);
      console.log(`     Sales Price: $${subscription.salesPrice || 0}`);
      console.log(`     Total Amount: $${subscription.totalAmount || 0}`);
      console.log(`     TCV: $${subscription.tcv || 0}`);
      console.log(`     ACV: $${subscription.totalACV || 0}`);
      
      // Product Details
      if (subscription.product) {
        console.log(`\n   📋 Product:`);
        console.log(`     ${subscription.product.name} (${subscription.product.sku})`);
        console.log(`     Category: ${subscription.product.productCategory}`);
        console.log(`     Price Model: ${subscription.product.priceModel}`);
      }
      
      // Bundle Information
      if (subscription.bundled) {
        console.log(`\n   📦 Bundle Details:`);
        console.log(`     Bundled: Yes`);
        console.log(`     Level: ${subscription.subscriptionLevel}`);
        console.log(`     Parent: ${subscription.parentSubscriptionObject || 'N/A'}`);
      }
      
      // Billing Information
      console.log(`\n   🧾 Billing:`);
      console.log(`     Billing Account: ${subscription.billingAccountId}`);
      console.log(`     Billing Timing: ${subscription.billingTiming || 'Standard'}`);
      
      // Renewal Information
      console.log(`\n   🔄 Renewal:`);
      console.log(`     Auto Renew: ${subscription.autoRenew ? 'Yes' : 'No'}`);
      console.log(`     Renewal Term: ${subscription.renewalTerm || 'Same as original'} months`);
      console.log(`     Evergreen: ${subscription.evergreen ? 'Yes' : 'No'}`);
    });
  }
})
.catch(error => console.log('Error:', error));
```

## Point-in-Time Snapshots and Historical Analysis

Subscription snapshots provide powerful capabilities for historical analysis, compliance reporting, and business intelligence. Unlike the current contract view which shows the complete subscription timeline, snapshots show the exact state of subscriptions as they existed on a specific date.

### Understanding Subscription Snapshots

Snapshots show the exact state of subscriptions as they existed on a specific date, including upcoming changes scheduled from that point forward.

**Key differences from current contract view:**

- **Current view**: Complete timeline for operational management
- **Snapshot view**: Point-in-time state for historical analysis and compliance

**Primary use cases:**

- Historical billing reconciliation
- Compliance and audit reporting
- Change impact analysis

### Fetch Snapshot by Customer

Generate a point-in-time snapshot to see subscription state at a specific date:

```javascript
// Fetch snapshot by customer IDs
const customerIds = ["d2e04653-ae90-49df-a986-134cf64f6d03"];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
const snapshotDate = "2025-06-26";

fetch(`https://api.nue.io/subscriptions?customerIds=${encodedIds}&snapshotDate=${snapshotDate}&includes=upcomingChanges`, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS' && result.data) {
    console.log(`📸 Customer Snapshot for ${snapshotDate}`);
    
    result.data.forEach(subscription => {
      console.log(`\n📦 ${subscription.name}`);
      console.log(`   Status: ${subscription.status}`);
      console.log(`   Quantity: ${subscription.quantity}`);
      console.log(`   Period: ${subscription.subscriptionStartDate} to ${subscription.subscriptionEndDate}`);
      
      // Show upcoming changes from snapshot date
      if (subscription.upcomingChanges && subscription.upcomingChanges.length > 0) {
        console.log(`   📅 Upcoming Changes:`);
        subscription.upcomingChanges.forEach(change => {
          console.log(`     • ${change.changeType} on ${change.startDate}`);
        });
      }
    });
  }
})
.catch(error => console.log('Error:', error));
```

### Fetch Snapshot by Subscription Name

Retrieve snapshot for a specific subscription by name:

```javascript
// Fetch snapshot by subscription name
const subscriptionName = "Enterprise License - Customer";
const snapshotDate = "2025-06-26";

fetch(`https://api.nue.io/subscriptions?name=${encodeURIComponent(subscriptionName)}&snapshotDate=${snapshotDate}&includes=upcomingChanges`, {
  method: 'GET',
  headers: myHeaders
})
.then(response => response.json())
.then(result => {
  if (result.status === 'SUCCESS' && result.data.length > 0) {
    const subscription = result.data[0];
    
    console.log(`📸 Subscription Snapshot: ${subscription.name}`);
    console.log(`   Snapshot Date: ${subscription.snapshotDate}`);
    console.log(`   Customer: ${subscription.customerId}`);
    console.log(`   Status: ${subscription.status}`);
    console.log(`   Quantity: ${subscription.quantity}`);
    console.log(`   ACV: $${subscription.totalACV}`);
    
    // Show what changes were scheduled from this snapshot date
    if (subscription.upcomingChanges && subscription.upcomingChanges.length > 0) {
      console.log(`\n📅 Changes scheduled from ${snapshotDate}:`);
      subscription.upcomingChanges.forEach(change => {
        console.log(`   • ${change.changeType} on ${change.startDate}`);
        if (change.changeInQuantity) {
          console.log(`     Quantity change: ${change.changeInQuantity > 0 ? '+' : ''}${change.changeInQuantity}`);
        }
      });
    } else {
      console.log(`\n📅 No changes scheduled from ${snapshotDate}`);
    }
  }
})
.catch(error => console.log('Error:', error));
```

### Snapshot Response Structure

Key snapshot-specific fields:

```json
{
  "status": "SUCCESS",
  "data": [
        {
            "autoRenew": false,
            "billingAccountId": "001Aq00000qemnyIAA",
            "customerId": "001Aq00000qemnyIAA",
            "externalId": "a0tAq00000WTI7BIAX",
            "externalName": "SUB-000004",
            "id": "a0tAq00000WTI7BIAX",
            "name": "SUB-000004",
            "orderProductId": "802Aq00000MuogcIAB",
            "priceBookEntryId": "01uAq000006A1e6IAC",
            "productId": "01tAq00000DJScOIAX",
            "quantity": 1,
            "snapshotDate": "2025-11-09",
            "status": "Active",
            "subscriptionEndDate": "2026-11-05",
            "subscriptionStartDate": "2025-11-06",
            "subscriptionTerm": 12,
            "tax": 0,
            "totalAmount": 106.8,
            "totalPrice": 106.8,
            "uom": {
                "termDimension": "Month"
            }
        }
  ],
  "warnings": []
}
```

### Subscription History Analysis

Fetch subscription history for trend analysis:

```javascript
async function analyzeSubscriptionHistory(subscriptionName) {
  const encodedName = encodeURIComponent(subscriptionName);
  const url = `https://api.nue.io/subscriptions?name=${encodedName}&history=true`;
  
  try {
    const response = await fetch(url, {
      method: 'GET',
      headers: myHeaders
    });
    
    const result = await response.json();
    
    if (result.status === 'SUCCESS' && result.data.length > 0) {
      console.log(`📈 Subscription History Analysis: ${subscriptionName}`);
      console.log('='.repeat(60));
      
      // Sort by version to show evolution
      const sortedHistory = result.data.sort((a, b) => a.subscriptionVersion - b.subscriptionVersion);
      
      sortedHistory.forEach((version, index) => {
        console.log(`\n${index + 1}. Version ${version.subscriptionVersion}`);
        console.log(`   Period: ${version.subscriptionStartDate} to ${version.subscriptionEndDate}`);
        console.log(`   Status: ${version.status}`);
        console.log(`   Quantity: ${version.quantity}`);
        console.log(`   Total Amount: $${version.totalAmount || 0}`);
        console.log(`   Modified: ${version.lastModifiedDate} by ${version.lastModifiedById}`);
        
        // Compare with previous version
        if (index > 0) {
          const previous = sortedHistory[index - 1];
          const quantityChange = version.quantity - previous.quantity;
          const amountChange = (version.totalAmount || 0) - (previous.totalAmount || 0);
          
          if (quantityChange !== 0 || amountChange !== 0) {
            console.log(`   📊 Changes from previous version:`);
            if (quantityChange !== 0) {
              console.log(`     Quantity: ${quantityChange > 0 ? '+' : ''}${quantityChange}`);
            }
            if (amountChange !== 0) {
              console.log(`     Amount: ${amountChange > 0 ? '+' : ''}$${amountChange.toLocaleString()}`);
            }
          }
        }
      });
      
      // Generate summary insights
      console.log(`\n💡 History Insights:`);
      console.log(`   Total Versions: ${sortedHistory.length}`);
      
      const firstVersion = sortedHistory[0];
      const currentVersion = sortedHistory[sortedHistory.length - 1];
      
      const totalQuantityChange = currentVersion.quantity - firstVersion.quantity;
      const totalAmountChange = (currentVersion.totalAmount || 0) - (firstVersion.totalAmount || 0);
      
      console.log(`   Quantity Evolution: ${firstVersion.quantity} → ${currentVersion.quantity} (${totalQuantityChange > 0 ? '+' : ''}${totalQuantityChange})`);
      console.log(`   Value Evolution: $${firstVersion.totalAmount || 0} → $${currentVersion.totalAmount || 0} (${totalAmountChange > 0 ? '+' : ''}$${totalAmountChange.toLocaleString()})`);
      
      return sortedHistory;
    } else {
      console.log('No subscription history found');
      return [];
    }
  } catch (error) {
    console.error('History analysis failed:', error);
    return [];
  }
}

// Usage example
analyzeSubscriptionHistory("Enterprise Software License - Acme Corp")
  .then(history => {
    console.log(`Analysis complete: ${history.length} versions analyzed`);
  });
```

## Query Parameters Reference

| Parameter               | Type           | Required | Description                                                                                                                                                                                                | Options                                                     |
| ----------------------- | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| <br />customerIds       | Array\[String] | \*       | JSON-encoded array of customer IDs                                                                                                                                                                         | <br />\["customer-uuid-1", "customer-uuid-2"]               |
| <br />name              | String         | \*       | Specific subscription name to fetch                                                                                                                                                                        | <br />"Enterprise License - Customer"                       |
| <br />snapshotDate      | String         | No       | Point-in-time snapshot date (YYYY-MM-DD)                                                                                                                                                                   | <br />"2025-06-26"                                          |
| <br />status            | String         | No       | Filter by subscription status                                                                                                                                                                              | , , <br />"active"<br />"expired"<br />"canceled"           |
| <br />version           | String         | No       | Filter by version type                                                                                                                                                                                     | , <br />"latest"<br />"snapshot"                            |
| <br />history           | Boolean        | No       | Include subscription history                                                                                                                                                                               | , <br />true<br />false                                     |
| <br />includes          | String         | No       | Related data to include                                                                                                                                                                                    | , , <br />"product"<br />"pricetags"<br />"upcomingChanges" |
| <br />productDetail     | String         | No       | How much of each product to return.  omits the product option graph and keeps identity and pricing. Defaults to . Requires ; sending it alone returns .<br />root<br />full<br />includes=product<br />400 | , <br />"full"<br />"root"                                  |
| <br />bundled           | Boolean        | No       | Whether the subscription is a bundled component priced as part of its parent.  also matches rows where the value was never set.<br />false                                                                 | , <br />true<br />false                                     |
| <br />subscriptionLevel | Integer        | No       | Depth in the bundle hierarchy.  is top level, higher values are nested options. Accepts a comma-separated list.<br />1                                                                                     | , , <br />1<br />2<br />"1,2"                               |

\*Either `customerIds` or `name` is required

## Response Structure

### Regular Subscription Response (200 OK)

```json
{
  "status": "SUCCESS",
  "data": [
    {
      "actualSubscriptionTerm": 12,
      "autoRenew": true,
      "billCycleDay": "7th of Month",
      "billCycleStartMonth": "03",
      "billingAccountId": "81dd1eb9-7a2c-4486-be76-b1ac2f88bbb1",
      "billingPeriod": "Annual",
      "billingTiming": "In Advance",
      "bundled": true,
      "createdById": "74ef82c9-a9d7-4262-8331-ba7ac33d1f76",
      "createdDate": "2025-07-02T23:12:30.582Z",
      "customerId": "81dd1eb9-7a2c-4486-be76-b1ac2f88bbb1",
      "evergreen": false,
      "id": "f594fd3a-3659-4039-ae5c-b2c6863d98a5",
      "lastModifiedById": "74ef82c9-a9d7-4262-8331-ba7ac33d1f76",
      "lastModifiedDate": "2025-07-02T23:12:30.621Z",
      "listPrice": 19.9,
      "name": "SUB-00000309",
      "nextBillingDate": "2025-07-01",
      "orderOnDate": "2025-07-02",
      "orderProductId": "03139976-1cc2-4430-8f61-996e641c8745",
      "parentId": "3b573778-89c0-491d-a972-bd3073d9add4",
      "parentObjectType": "Subscription",
      "priceBookEntryId": "01u7z000005YNBAAA4",
      "priceBookId": "01s7z000006Dt4rAAC",
      "productId": "01t7z00000DXt09AAD",
      "quantity": 2,
      "renewalTerm": 12,
      "rootId": "3b573778-89c0-491d-a972-bd3073d9add4",
      "salesPrice": 19.9,
      "status": "Active",
      "subscriptionCompositeId": "SUB-00000309_1",
      "subscriptionEndDate": "2026-06-30",
      "subscriptionLevel": 2,
      "subscriptionStartDate": "2025-07-01",
      "subscriptionTerm": 12,
      "subscriptionVersion": 1,
      "taxAmount": 0,
      "tcv": 0,
      "totalACV": 0,
      "totalAmount": 0,
      "totalPrice": 0,
      "totalTCV": 0,
      "uomId": "a0s7z00000HYFPTAA5"
    }
  ],
  "warnings": []
}
```

### Snapshot Response (with snapshotDate)

```json
{
  "status": "SUCCESS", 
  "data": [
    {
      "id": "subscription-uuid",
      "name": "Enterprise Software License",
      "customerId": "customer-uuid",
      "snapshotDate": "2025-06-26",
      "status": "active",
      "quantity": 100,
      "upcomingChanges": [
        {
          "changeType": "UpdateQuantity",
          "startDate": "2025-07-01"
        }
      ]
    }
  ],
  "warnings": []
}
```

## Error Handling

### Common Retrieval Errors

| Error                                                             | Description                                                                                                                                         | Resolution                                                                                                                   |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| <br />INVALID\_CUSTOMER\_ID                                       | Customer ID format invalid                                                                                                                          | Verify customer ID format                                                                                                    |
| <br />INVALID\_FILTER\_VALUE                                      | A filter value does not match the field's type, for example  on an integer field, or  on a boolean field.<br />subscriptionLevel=abc<br />bundled=1 | Send a whole number for integer fields and / for boolean fields. The message names the offending field.<br />true<br />false |
| <br />INVALID\_PARAMETER\_COMBINATION                             |  was supplied without .<br />productDetail<br />includes=product                                                                                    | Add , or drop .<br />includes=product<br />productDetail                                                                     |
| Unknown filter field ()<br />400                                  | A query parameter does not correspond to any field on the subscription object. Previously such parameters were ignored.                             | Remove stray parameters from the request.                                                                                    |
|  (warning, )<br />FILTER\_NOT\_SUPPORTED\_WITH\_SNAPSHOT<br />207 | A filter was combined with  on a field that a snapshot recalculates, so it could not be applied.<br />snapshotDate                                  | Not an error. The data is correct but unfiltered on that field. Apply the condition client-side, or drop .<br />snapshotDate |
| <br />SUBSCRIPTION\_NOT\_FOUND                                    | Named subscription doesn't exist                                                                                                                    | Check subscription name spelling                                                                                             |
| <br />INVALID\_SNAPSHOT\_DATE                                     | Snapshot date format invalid                                                                                                                        | Use YYYY-MM-DD format                                                                                                        |
| <br />PARAMETER\_CONFLICT                                         | Conflicting parameters used                                                                                                                         | Review parameter restrictions                                                                                                |

### Robust Subscription Fetching

```javascript
async function safeSubscriptionFetch(customerIds, options = {}) {
  try {
    // Validate inputs
    if (!Array.isArray(customerIds) || customerIds.length === 0) {
      throw new Error('CustomerIds must be a non-empty array');
    }
    
    const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
    let url = `https://api.nue.io/subscriptions?customerIds=${encodedIds}`;
    
    // Add optional parameters
    if (options.status) {
      url += `&status=${options.status}`;
    }
    
    if (options.includes) {
      url += `&includes=${options.includes}`;
    }
    
    if (options.snapshotDate) {
      url += `&snapshotDate=${options.snapshotDate}`;
    }
    
    const response = await fetch(url, {
      method: 'GET',
      headers: myHeaders
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    
    const result = await response.json();
    
    if (result.status !== 'SUCCESS') {
      throw new Error(`API Error: ${result.message || 'Unknown error'}`);
    }
    
    return {
      subscriptions: result.data || [],
      found: result.data?.length || 0,
      requested: customerIds.length,
      warnings: result.warnings || []
    };
    
  } catch (error) {
    console.error('Subscription fetch error:', error);
    return {
      subscriptions: [],
      found: 0,
      requested: customerIds.length,
      error: error.message
    };
  }
}
```

## Best Practices

### Data Retrieval

1. **Use appropriate filters** to reduce data transfer
2. **Include related data** selectively based on needs
3. **Leverage snapshots** for historical analysis
4. **Monitor upcoming changes** proactively

### Performance Optimization

1. **Batch customer queries** efficiently
2. **Cache frequently accessed** subscription data
3. **Use status filters** to focus on relevant subscriptions
4. **Implement pagination** for large datasets

### Business Intelligence

1. **Track subscription trends** over time
2. **Monitor renewal patterns** and auto-renew rates
3. **Analyze product adoption** across subscriptions
4. **Generate renewal forecasts** from expiration data

This comprehensive guide enables you to efficiently retrieve and analyze subscription data using the Nue Lifecycle Management API, supporting everything from simple lookups to complex portfolio analysis and predictive renewal management.
