Getting Started with Subscription Management
This guide walks you through essential subscription management operations in the Nue Self-Service API. You'll learn how to retrieve subscription data, understand different view types, update subscription settings, and implement client-side pricing for dynamic subscription changes.
Prerequisites
Before you begin, ensure you have:
- A valid Nue API key
- Customer accounts with active subscriptions
- Basic understanding of REST APIs and JSON
- Familiarity with subscription lifecycle concepts
Authentication
All subscription operations require authentication using your Nue API key in the nue-api-key header:
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");Understanding Subscription Views
The Nue API provides two primary ways to view subscription data, each optimized for different use cases.
Current Contract View
Shows the complete subscription with all changes (past, present, and future) in a single timeline view.
Best for:
- Customer service dashboards
- Complete subscription management
- Planning future modifications
- Understanding full contract terms
Snapshot View
Shows exactly what the subscription looked like at a specific point in time.
Best for:
- Historical billing analysis
- Audit and compliance reporting
- Change impact analysis
- Point-in-time financial reporting
Retrieving Customer Subscriptions
Fetch All Subscriptions for Customers
Try it now: Fetch Customer Subscriptions →
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");
// Fetch subscriptions for multiple customers
const customerIds = [
"d2e04653-ae90-49df-a986-134cf64f6d03",
"cc5e1f0f-5e14-48cc-ab98-9e5b191aa46f"
];
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('Customer subscriptions retrieved:', result);
if (result.status === 'SUCCESS' && result.data) {
result.data.forEach(subscription => {
console.log(`\nSubscription: ${subscription.name}`);
console.log(`Customer: ${subscription.customerId}`);
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(`Total Amount: $${subscription.totalAmount || 'N/A'}`);
});
}
})
.catch(error => console.log('Error:', error));Fetch Subscriptions with Related Data
Include additional information using the includes parameter:
// Include product and pricing tag information
const includes = "product,pricetags";
const url = `https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}&includes=${includes}`;
fetch(url, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Subscriptions with related data:', result);
if (result.status === 'SUCCESS' && result.data) {
result.data.forEach(subscription => {
console.log(`\nSubscription: ${subscription.name}`);
// Access product information
if (subscription.product) {
console.log(`Product Details:`);
console.log(` Name: ${subscription.product.name}`);
console.log(` SKU: ${subscription.product.sku}`);
console.log(` Description: ${subscription.product.description}`);
}
// Access pricing tag information
if (subscription.pricetags && subscription.pricetags.length > 0) {
console.log(`Applied Price Tags:`);
subscription.pricetags.forEach(tag => {
console.log(` - ${tag.name} (${tag.code})`);
});
}
});
}
})
.catch(error => console.log('Error:', error));Filter Subscriptions by Status
Retrieve only subscriptions in specific states:
// Get only active subscriptions
const activeUrl = `https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}&status=Active`;
fetch(activeUrl, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
if (result.status === 'SUCCESS' && result.data) {
console.log(`Found ${result.data.length} active subscriptions`);
result.data.forEach(subscription => {
console.log(`Active: ${subscription.name} - $${subscription.totalAmount || 0}`);
});
}
})
.catch(error => console.log('Error:', error));
// Available status filters: Active, Expired, CanceledRetrieving Specific Subscriptions
Fetch by Subscription Name
Try it now: Fetch Customer Subscriptions →
// Fetch a specific subscription by name
const subscriptionName = "SUB-00000279";
fetch(`https://api.nue.io/subscriptions?name=${subscriptionName}`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
if (result.status === 'SUCCESS' && result.data && result.data.length > 0) {
const subscription = result.data[0];
console.log('Subscription details:', subscription);
console.log(`Name: ${subscription.name}`);
console.log(`Product: ${subscription.productId}`);
console.log(`Customer: ${subscription.customerId}`);
console.log(`Term: ${subscription.subscriptionTerm} months`);
console.log(`Auto-Renew: ${subscription.autoRenew}`);
console.log(`Current Period: ${subscription.subscriptionStartDate} to ${subscription.subscriptionEndDate}`);
// Display financial information
console.log(`\nFinancial Summary:`);
console.log(` Total Amount: $${subscription.totalAmount || 0}`);
console.log(` Total ACV: $${subscription.totalACV || 0}`);
console.log(` Total TCV: $${subscription.tcv || 0}`);
} else {
console.log('Subscription not found');
}
})
.catch(error => console.log('Error:', error));Include Subscription History
For detailed change tracking, include the subscription's modification history:
const subscriptionName = "SUB-00000279";
fetch(`https://api.nue.io/subscriptions?name=${subscriptionName}&history=true`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
if (result.status === 'SUCCESS' && result.data && result.data.length > 0) {
const subscription = result.data[0];
console.log('Subscription with history:', subscription);
// Access historical changes
if (subscription.subscriptionHistory) {
console.log('\nSubscription Change History:');
subscription.subscriptionHistory.forEach((change, index) => {
console.log(`${index + 1}. ${change.changeDate}: ${change.changeType}`);
console.log(` Quantity: ${change.oldQuantity} → ${change.newQuantity}`);
console.log(` Amount: $${change.oldAmount} → $${change.newAmount}`);
});
}
}
})
.catch(error => console.log('Error:', error));Creating Subscription Snapshots
Point-in-Time Subscription Analysis
Generate snapshots to see exactly what subscriptions looked like on specific dates:
// Create a snapshot for a specific date
const snapshotDate = "2025-01-15"; // YYYY-MM-DD format
fetch(`https://api.nue.io/subscriptions?customerIds=${encodedCustomerIds}&snapshotDate=${snapshotDate}`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log(`Subscription snapshot for ${snapshotDate}:`, result);
if (result.status === 'SUCCESS' && result.data) {
result.data.forEach(subscription => {
console.log(`\nSnapshot: ${subscription.name}`);
console.log(`Status on ${snapshotDate}: ${subscription.status}`);
console.log(`Quantity on ${snapshotDate}: ${subscription.quantity}`);
console.log(`Total amount on ${snapshotDate}: $${subscription.totalAmount || 'N/A'}`);
// Upcoming changes from that date
if (subscription.upcomingChanges) {
console.log('Upcoming changes from this date:');
subscription.upcomingChanges.forEach(change => {
console.log(` ${change.startDate}: ${change.changeType} - ${change.description}`);
});
}
});
}
})
.catch(error => console.log('Error:', error));Updating Subscription Settings
Update Auto-Renewal Settings
Try it now: Update Subscription →
// Update a subscription's auto-renewal setting
const subscriptionId = "7c8a3e45-1d2f-4a5b-9c7e-3f4a5b6c7d8e";
const updateData = JSON.stringify({
"autoRenew": true
});
fetch(`https://api.nue.io/subscriptions/${subscriptionId}`, {
method: 'PATCH',
headers: myHeaders,
body: updateData
})
.then(response => response.json())
.then(result => {
console.log('Subscription updated:', result);
if (result.status === 'SUCCESS') {
console.log('Auto-renewal successfully enabled');
console.log('Updated subscription:', result.data);
}
})
.catch(error => console.log('Error:', error));Update Custom Fields
Modify custom subscription attributes:
// Update custom fields
const subscriptionId = "7c8a3e45-1d2f-4a5b-9c7e-3f4a5b6c7d8e";
const customFieldUpdate = JSON.stringify({
"Ruby__Custom_Field__c": "Updated Value",
"ServiceTier__c": "Premium",
"AccountManager__c": "John Smith"
});
fetch(`https://api.nue.io/subscriptions/${subscriptionId}`, {
method: 'PATCH',
headers: myHeaders,
body: customFieldUpdate
})
.then(response => response.json())
.then(result => {
console.log('Custom fields updated:', result);
if (result.status === 'SUCCESS') {
console.log('Custom fields successfully updated');
}
})
.catch(error => console.log('Error:', error));Client-Side Pricing Engine Integration
Retrieve Pricing Data for Dynamic Quotes
Try it now: Fetch Pricing Data →
// Get pricing data for client-side calculations
const customerIds = ["d2e04653-ae90-49df-a986-134cf64f6d03"];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
fetch(`https://api.nue.io/subscriptions/pricing-engine-input?customerIds=${encodedIds}`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Pricing engine data:', result);
if (result.status === 'SUCCESS' && result.data) {
// This data can be used with Nue UI components for real-time pricing
const pricingData = result.data;
// Example: Display available subscriptions for modification
Object.keys(pricingData).forEach(customerId => {
const customerData = pricingData[customerId];
if (customerData.changes) {
console.log(`Pricing data for customer ${customerId}:`);
customerData.changes.forEach(change => {
console.log(`- Change type: ${change.changeType}`);
console.log(` Quantity: ${change.quantity}`);
console.log(` Total price: $${change.totalPrice}`);
});
}
});
}
})
.catch(error => console.log('Error:', error));Building a Subscription Dashboard
Here's a comprehensive example of building a customer subscription dashboard:
async function buildSubscriptionDashboard(customerId) {
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");
try {
// Fetch all customer subscriptions with product details
const customerIds = [customerId];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
const response = await fetch(
`https://api.nue.io/subscriptions?customerIds=${encodedIds}&includes=product,pricetags`,
{
method: 'GET',
headers: myHeaders
}
);
const result = await response.json();
if (result.status !== 'SUCCESS' || !result.data) {
throw new Error('Failed to fetch subscriptions');
}
const subscriptions = result.data;
// Organize subscriptions by status
const dashboard = {
active: [],
expired: [],
canceled: [],
summary: {
totalSubscriptions: subscriptions.length,
totalMonthlyValue: 0,
totalAnnualValue: 0,
nextRenewal: null
}
};
subscriptions.forEach(subscription => {
const subData = {
id: subscription.id,
name: subscription.name,
productId: subscription.productId,
quantity: subscription.quantity,
status: subscription.status,
startDate: subscription.subscriptionStartDate,
endDate: subscription.subscriptionEndDate,
totalAmount: subscription.totalAmount || 0,
totalACV: subscription.totalACV || 0,
autoRenew: subscription.autoRenew,
pricetags: subscription.pricetags || []
};
// Categorize by status
if (subscription.status === 'Active') {
dashboard.active.push(subData);
dashboard.summary.totalAnnualValue += subData.totalACV;
// Track next renewal
const endDate = new Date(subscription.subscriptionEndDate);
if (!dashboard.summary.nextRenewal || endDate < new Date(dashboard.summary.nextRenewal)) {
dashboard.summary.nextRenewal = subscription.subscriptionEndDate;
}
} else if (subscription.status === 'Expired') {
dashboard.expired.push(subData);
} else if (subscription.status === 'Canceled') {
dashboard.canceled.push(subData);
}
});
// Display dashboard
console.log('\n🏢 Customer Subscription Dashboard');
console.log('=====================================');
console.log(`\n📊 Summary:`);
console.log(` Total Subscriptions: ${dashboard.summary.totalSubscriptions}`);
console.log(` Annual Contract Value: $${dashboard.summary.totalAnnualValue.toFixed(2)}`);
console.log(` Next Renewal: ${dashboard.summary.nextRenewal || 'None scheduled'}`);
console.log(`\n✅ Active Subscriptions (${dashboard.active.length}):`);
dashboard.active.forEach(sub => {
console.log(` 📋 ${sub.name}`);
console.log(` Product: ${sub.productId}`);
console.log(` Quantity: ${sub.quantity}`);
console.log(` Value: $${sub.totalAmount}`);
console.log(` Ends: ${sub.endDate}`);
console.log(` Auto-Renew: ${sub.autoRenew ? '✅' : '❌'}`);
if (sub.pricetags.length > 0) {
console.log(` Applied Discounts: ${sub.pricetags.map(t => t.name).join(', ')}`);
}
console.log('');
});
if (dashboard.expired.length > 0) {
console.log(`\n⏰ Expired Subscriptions (${dashboard.expired.length}):`);
dashboard.expired.forEach(sub => {
console.log(` 📋 ${sub.name} - Expired: ${sub.endDate}`);
});
}
if (dashboard.canceled.length > 0) {
console.log(`\n❌ Canceled Subscriptions (${dashboard.canceled.length}):`);
dashboard.canceled.forEach(sub => {
console.log(` 📋 ${sub.name} - Canceled: ${sub.endDate}`);
});
}
return dashboard;
} catch (error) {
console.error('Failed to build subscription dashboard:', error);
throw error;
}
}
// Usage
buildSubscriptionDashboard('d2e04653-ae90-49df-a986-134cf64f6d03')
.then(dashboard => {
console.log('Dashboard data ready for UI rendering');
// Use dashboard data to render UI components
});Common Patterns and Best Practices
Error Handling
Always implement robust error handling for subscription operations:
async function safeSubscriptionFetch(customerIds, options = {}) {
try {
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 error! status: ${response.status}`);
}
const result = await response.json();
if (result.status !== 'SUCCESS' || !result.data) {
throw new Error('Unexpected response format');
}
return result.data;
} catch (error) {
console.error('Subscription fetch error:', error);
// Return empty array for graceful degradation
return [];
}
}Caching Strategy
Implement appropriate caching for subscription data:
class SubscriptionCache {
constructor(ttlMinutes = 30) {
this.cache = new Map();
this.ttl = ttlMinutes * 60 * 1000;
}
set(key, data) {
this.cache.set(key, {
data,
timestamp: Date.now()
});
}
get(key) {
const cached = this.cache.get(key);
if (!cached) return null;
if (Date.now() - cached.timestamp > this.ttl) {
this.cache.delete(key);
return null;
}
return cached.data;
}
async getSubscriptions(customerIds, options = {}) {
const cacheKey = `${customerIds.join(',')}-${JSON.stringify(options)}`;
const cached = this.get(cacheKey);
if (cached) {
console.log('Using cached subscription data');
return cached;
}
console.log('Fetching fresh subscription data');
const subscriptions = await safeSubscriptionFetch(customerIds, options);
this.set(cacheKey, subscriptions);
return subscriptions;
}
}
// Usage
const subscriptionCache = new SubscriptionCache(30); // 30-minute cache
const subscriptions = await subscriptionCache.getSubscriptions(['customer-id']);Next Steps
Now that you understand basic subscription operations, you can:
- Explore the Subscription Data Reference for complete field documentation
- Learn Advanced Subscription Workflows for complex scenarios and integrations
- Implement client-side pricing for real-time subscription modifications
- Build comprehensive dashboards with subscription analytics
Move on to Subscription Data Reference to understand all available fields and data structures, or Advanced Subscription Workflows for complex integration scenarios.