Getting Started with Order Management
This guide walks you through the complete order management lifecycle in the Nue Self-Service API. You'll learn the essential workflows from creating draft orders through activation, retrieval, modifications, and Salesforce synchronization.
Prerequisites
Before you begin, ensure you have:
- A valid Nue API key
- At least one customer created in your system
- Access to your product catalog and price book entries
- Basic understanding of REST APIs and JSON
Authentication
All order 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");Complete Order Lifecycle Workflow
This section demonstrates the typical end-to-end order process that most businesses follow.
Step 1: Create a New Order as Draft
The first step is creating a draft order to preview pricing and configuration before committing to the purchase.
Try it now: Create Draft Order →
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");
// Create a draft order with preview options
const draftOrderData = JSON.stringify({
"customer": {
"id": "d2e04653-ae90-49df-a986-134cf64f6d03"
},
"options": {
"previewInvoice": true,
"calculateTax": false
},
"effectiveDate": "2024-12-24",
"orderProducts": [
{
"priceBookEntryId": "01uEa000008IcdeIAC",
"quantity": 5,
"subscriptionStartDate": "2025-01-01",
"subscriptionTerm": 12
}
],
"name": "Annual Platform License",
"description": "Customer's annual subscription order"
});
fetch("https://api.nue.io/orders", {
method: 'POST',
headers: myHeaders,
body: draftOrderData
})
.then(response => response.json())
.then(result => {
console.log('Draft order created:', result);
// Save the order ID for next steps
const draftOrderId = result.data.order.id;
localStorage.setItem('draftOrderId', draftOrderId);
// Display order details
console.log(`Order ID: ${draftOrderId}`);
console.log(`Total Amount: $${result.data.order.totalAmount}`);
console.log(`Annual Contract Value: $${result.data.order.orderACV}`);
// If preview invoice was requested
if (result.data.previewInvoices) {
console.log('Preview Invoice:', result.data.previewInvoices[0]);
}
})
.catch(error => console.log('Error:', error));What happens: This creates a draft order showing exact pricing, terms, and future billing without any financial impact.
Step 2: Activate the Draft Order
Once the draft order is approved, activate it to create actual subscriptions and begin billing.
Try it now: Activate Draft Order →
// Get the draft order ID from Step 1
const draftOrderId = localStorage.getItem('draftOrderId');
const activationData = JSON.stringify({
"options": {
"generateInvoice": true,
"activateInvoice": false // Keep invoice as draft for now
},
"poNumber": "PO-2025-001",
"poDate": "2025-01-01",
"transactionHub": {
"externalSystem": "Stripe",
"externalId": "cus_dksiwd123",
"transactionType": "Customer"
}
});
fetch(`https://api.nue.io/orders/${draftOrderId}`, {
method: 'POST',
headers: myHeaders,
body: activationData
})
.then(response => response.json())
.then(result => {
console.log('Order activated successfully:', result);
// Store activated order details
const activatedOrder = result.data.order;
console.log(`Order Number: ${activatedOrder.orderNumber}`);
console.log(`Status: ${activatedOrder.status}`);
console.log(`Activated Date: ${activatedOrder.activatedDate}`);
// Access created subscriptions
if (result.data.subscriptions) {
result.data.subscriptions.forEach(subscription => {
console.log(`Subscription Created: ${subscription.name}`);
console.log(`Subscription ID: ${subscription.id}`);
});
}
// Save the customer ID for next steps
localStorage.setItem('customerId', activatedOrder.customerId);
})
.catch(error => console.log('Error:', error));What happens: The order status changes to "Activated", subscriptions are created, and the order automatically syncs to Salesforce.
Step 3: CoTerm New Order Products (Optional)
For organizations with existing subscriptions, you can align new order products with existing subscription end dates using the CoTerm capability. This eliminates the need to specify subscriptionTerm when you want the new service to end at the same time as an existing asset.
Try it now: Create CoTerm Order →
// Create a new order product that aligns with existing subscription
const coTermOrderData = JSON.stringify({
"customer": {
"id": "d2e04653-ae90-49df-a986-134cf64f6d03"
},
"options": {
"previewInvoice": true,
"calculateTax": false
},
"effectiveDate": "2025-05-06",
"billingPeriod": "Annual",
"orderProducts": [
{
"priceBookEntryId": "01uEa000008IcdeIAC",
"quantity": 1,
"subscriptionStartDate": "2025-05-06",
"coTermAsset": "SUB-00000270", // Aligns with this existing subscription
"addOns": [
{
"productOptionId": "01uEa000008IcdgIAC",
"productOptionQuantity": 2,
"subscriptionStartDate": "2025-05-06",
"coTermAsset": "SUB-00000270" // Add-ons can also use CoTerm
}
]
}
],
"name": "Additional Services - CoTerm Alignment",
"description": "New services aligned with existing subscription end date"
});
fetch("https://api.nue.io/orders", {
method: 'POST',
headers: myHeaders,
body: coTermOrderData
})
.then(response => response.json())
.then(result => {
console.log('CoTerm order created:', result);
const order = result.data.order;
console.log(`Order ID: ${order.id}`);
console.log(`Aligned with asset: SUB-00000270`);
// The new subscription will automatically end when SUB-00000270 ends
order.orderProducts.forEach(product => {
if (product.coTermAsset) {
console.log(`Product ${product.productName} aligned with ${product.coTermAsset}`);
}
});
})
.catch(error => {
if (error.message.includes('Asset not found')) {
console.error('CoTerm asset SUB-00000270 not found for this customer');
} else if (error.message.includes('Date mismatch')) {
console.error('Start date conflicts with CoTerm asset schedule');
} else {
console.error('Error:', error);
}
});What happens: The new subscription automatically inherits the end date from the specified asset (SUB-00000270), ensuring synchronized renewal cycles. The subscriptionTerm field is not required when using coTermAsset.
Co-Term Capability Benefits:
- Synchronized Renewals: All services renew together, simplifying contract management
- Simplified Billing: Consolidated renewal dates reduce administrative overhead
- Flexible Alignment: Works for both main products and add-ons
- Automatic Calculation: System calculates appropriate term based on existing asset end date
Error Handling: Common CoTerm errors include asset not found (verify the asset belongs to the customer) and date mismatches (ensure start date is compatible with the existing asset's schedule).
Step 4: Retrieve Customer Orders
After activation, retrieve the customer's order history to see the new order and any existing orders.
Try it now: Fetch Customer Orders →
// Get customer ID from previous step
const customerId = localStorage.getItem('customerId');
const customerIds = [customerId];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
fetch(`https://api.nue.io/orders?customerIds=${encodedIds}&includes=orderProducts&status=activated`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Customer orders retrieved:', result);
result.data.forEach(order => {
console.log(`\\nOrder: ${order.orderNumber}`);
console.log(`Status: ${order.status}`);
console.log(`Total: $${order.totalAmount}`);
console.log(`Placed: ${order.orderPlacedDate}`);
// Display products in this order
if (order.orderProducts) {
console.log('Products:');
order.orderProducts.forEach(product => {
console.log(` - ${product.productName}: ${product.quantity} x $${product.listPrice}`);
// Save subscription info for change orders
if (product.subscriptionStartDate) {
localStorage.setItem('assetNumber', product.name || `SUB-${product.id.slice(-6)}`);
}
});
}
// Check if PDF is available
if (order.orderPdf) {
console.log(`Order PDF: ${order.orderPdf}`);
}
});
})
.catch(error => console.log('Error:', error));What happens: You can see all activated orders for the customer, including the one just created.
Step 5: Create a Change Order (Customer Modification)
Later, when the customer wants to modify their subscription (increase quantity, upgrade, etc.), create a change order. Change orders support various modification types with specific behaviors.
Try it now: Create Change Order Preview →
Common Change Order Types
- UpdateQuantity: Delta increase/decrease - adds to current quantity (5 users + quantity 3 = 8 users total)
- UpdateTerm: Delta extension - adds months to current term (12 months + term 6 = 18 months total)
- Upgrade/Downgrade: Switch to different product tier
- Renew: Extend subscription for new term period
- Cancel: End subscription on specific date
// Use subscription info from Step 4
const assetNumber = localStorage.getItem('assetNumber') || 'SUB-00000279';
const changeOrderData = JSON.stringify({
"options": {
"previewInvoice": true,
"calculateTax": false
},
"assetChanges": [
{
"changeType": "UpdateQuantity",
"assetNumber": assetNumber,
"quantity": 8, // Increase from 5 to 8 users
"startDate": "2025-02-01"
}
]
});
fetch("https://api.nue.io/change-orders", {
method: 'POST',
headers: myHeaders,
body: changeOrderData
})
.then(response => response.json())
.then(result => {
console.log('Change order preview created:', result);
// Save change order ID
const changeOrderId = result.data.order.id;
localStorage.setItem('changeOrderId', changeOrderId);
// Display change impact
console.log(`Change Order ID: ${changeOrderId}`);
console.log(`New Total: $${result.data.order.totalAmount}`);
// Show pricing impact
if (result.data.previewInvoices) {
const invoice = result.data.previewInvoices[0];
console.log(`Next Invoice Amount: $${invoice.amount}`);
}
})
.catch(error => console.log('Error:', error));What happens: Creates a draft change order showing the pricing impact of the modification without making actual changes.
Step 6: Generate Quote Link for Approval
Create a shareable magic link for the change order to get customer approval or signatures. This generates a secure URL that customers can use to view their order details and download formatted quotes.
Try it now: Generate Draft Order PDF Link →
// Get change order ID from Step 5
const changeOrderId = localStorage.getItem('changeOrderId');
fetch(`https://api.nue.io/orders/magiclink/order/${changeOrderId}`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Quote magic link generated:', result);
const quoteLink = result.magicLink;
console.log(`Share this link for approval: ${quoteLink}`);
// Store the quote link
localStorage.setItem('changeOrderQuoteLink', quoteLink);
// In a real application, you might:
// - Email this link to the customer for review
// - Display it in your UI for easy access
// - Include it in approval workflows
// - Share with stakeholders who need to review the quote
})
.catch(error => console.log('Error:', error));Advanced: Generate Quote Link with Custom Template
// For custom branding, use a specific template
const templateId = "custom-branded-template";
fetch(`https://api.nue.io/orders/magiclink/order/${changeOrderId}/template/${templateId}`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Branded quote link generated:', result.magicLink);
});What happens: Generates a secure, shareable magic link that allows customers to view their order details and download professionally formatted quotes via a web interface.
Step 7: Activate the Change Order
After receiving approval, activate the change order to implement the modifications.
Try it now: Activate Draft Order →
// Get change order ID from Step 5
const changeOrderId = localStorage.getItem('changeOrderId');
const changeActivationData = JSON.stringify({
"options": {
"generateInvoice": true,
"activateInvoice": true // Activate invoice immediately for billing
},
"poNumber": "PO-2025-002-CHANGE",
"poDate": "2025-02-01"
});
fetch(`https://api.nue.io/orders/${changeOrderId}`, {
method: 'POST',
headers: myHeaders,
body: changeActivationData
})
.then(response => response.json())
.then(result => {
console.log('Change order activated:', result);
console.log(`Change Order Status: ${result.data.order.status}`);
console.log(`Updated Subscriptions:`, result.data.subscriptions);
// The subscription quantity is now updated
if (result.data.subscriptions) {
result.data.subscriptions.forEach(sub => {
console.log(`Subscription ${sub.name}: ${sub.quantity} units`);
});
}
})
.catch(error => console.log('Error:', error));What happens: The subscription is modified with the new quantity, billing is updated, and changes sync to Salesforce.
Step 8: Fetch Updated Orders
Finally, retrieve the customer's orders again to see all changes and confirm the updates.
Try it now: Fetch Customer Orders →
// Get customer ID and fetch all their orders
const customerId = localStorage.getItem('customerId');
const customerIds = [customerId];
const encodedIds = encodeURIComponent(JSON.stringify(customerIds));
fetch(`https://api.nue.io/orders?customerIds=${encodedIds}&includes=orderProducts`, {
method: 'GET',
headers: myHeaders
})
.then(response => response.json())
.then(result => {
console.log('Updated customer order history:', result);
// Display all orders chronologically
const orders = result.data.sort((a, b) =>
new Date(a.orderPlacedDate) - new Date(b.orderPlacedDate)
);
orders.forEach((order, index) => {
console.log(`\\n--- Order ${index + 1}: ${order.orderNumber} ---`);
console.log(`Type: ${order.name}`);
console.log(`Status: ${order.status}`);
console.log(`Date: ${order.orderPlacedDate}`);
console.log(`Total: $${order.totalAmount}`);
if (order.orderProducts) {
console.log('Products:');
order.orderProducts.forEach(product => {
console.log(` - ${product.productName}: ${product.quantity} units`);
});
}
});
// Calculate total customer value
const totalValue = orders.reduce((sum, order) => sum + order.totalAmount, 0);
console.log(`\\nTotal Customer Value: $${totalValue}`);
})
.catch(error => console.log('Error:', error));What happens: You can see the complete order history including both the original order and the change order, showing the customer's full journey.
Salesforce Synchronization
Throughout this entire workflow, several automatic synchronizations occur with Salesforce:
Customer Creation and Updates
- When the first order is activated, the customer record automatically syncs to Salesforce
- The externalId field populates with the Salesforce Account ID
- Customer type typically upgrades from "Prospect" to "Direct Customer"
Order and Subscription Management
- Activated orders create corresponding records in Salesforce
- Subscriptions appear as ongoing service agreements
- Change orders update existing subscription records
- All financial data (ACV, TCV, billing periods) syncs automatically
Monitoring Sync Status
You can check if orders have synced by looking for the externalId field:
// Check if order has synced to Salesforce
if (order.externalId) {
console.log(`Order synced to Salesforce: ${order.externalId}`);
} else {
console.log('Order pending Salesforce sync');
}Next Steps
Now that you understand the basic order management workflow, you can:
- Explore Advanced Order Workflows for complex scenarios like bulk operations and sophisticated bundles
- Learn Order Data Reference to understand all available fields and relationships
- Implement Custom Business Logic around your specific approval and billing processes
- Set up Webhooks for real-time notifications of order status changes
Move on to Advanced Order Workflows to learn about complex scenarios like multi-product bundles, approval workflows, and enterprise integrations.