Skip to content

shrirajh/azure-pricing-calculator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Pricing Calculator - TypeScript API Client

A comprehensive TypeScript library for interacting with Azure's pricing APIs and calculating costs for Azure services.

Based on reverse-engineering the Azure Pricing Calculator web application.

Features

  • Full API Client: Fetch pricing data for any Azure service
  • Price Calculator: Calculate costs with currency conversion, discounts, and billing options
  • Estimate Management: Create, save, and manage pricing estimates
  • Support Pricing: Calculate support tier costs including graduated premium pricing
  • MCA/EA Support: Handle Enterprise Agreement and Microsoft Customer Agreement pricing
  • Persistence: IndexedDB storage with localStorage fallback

Installation

npm install azure-pricing-calculator

Quick Start

import { 
  AzurePricingApiClient, 
  AzurePricingCalculator,
  HOURS_PER_MONTH 
} from 'azure-pricing-calculator';

// Initialize the API client
const api = new AzurePricingApiClient();

// Fetch required data
const currencies = await api.fetchCurrencies();
const vmPricing = await api.fetchVmPricing('us-east');

// Create calculator with currency data
const calc = new AzurePricingCalculator(currencies);

// Get price for a VM
const price = calc.getPrice(vmPricing, 'standard-d2s-v3', {
  region: 'us-east',
  billingOption: 'payg',
  quantity: HOURS_PER_MONTH,
});

console.log(`Monthly cost: ${calc.formatPrice(price.total)}`);

API Client

Initialization

import { AzurePricingApiClient } from 'azure-pricing-calculator';

const api = new AzurePricingApiClient({
  baseUrl: 'https://azure.microsoft.com', // optional
  culture: 'en-us', // optional
  deploymentVersion: '1.0.0', // optional, for cache busting
});

Fetching Pricing Data

// Fetch pricing for a specific service
const storagePricing = await api.fetchServicePricing('storage');

// Fetch VM pricing for a region
const vmPricing = await api.fetchVmPricing('us-east');

// Fetch with discount options
const eaPricing = await api.fetchServicePricing('virtual-machines', {
  discounts: { base: 'ea', additional: [] },
  enrollment: 'your-enrollment-number',
  showSkus: true,
  showResourceIds: true,
});

Available API Methods

Method Description
fetchServicePricing(slug, options?) Fetch pricing for any service
fetchVmPricing(region, options?) Fetch VM pricing for a region
fetchVmMetadata() Fetch VM series, sizes, OS options
fetchRegions() Fetch available Azure regions
fetchCurrencies() Fetch currency conversion rates
fetchCategories() Fetch product categories
fetchSupportPricing(options?) Fetch support tier pricing
fetchUserInfo() Fetch authenticated user info
initializeCalculator() Fetch all required initialization data

Calculator

Basic Usage

import { AzurePricingCalculator } from 'azure-pricing-calculator';

const calc = new AzurePricingCalculator(currencies, {
  currency: { value: 'USD', locked: false },
  discounts: { base: 'payg', additional: [] },
});

// Get a single price
const price = calc.getPrice(pricingData, 'standard-d2s-v3', {
  region: 'us-east',
  billingOption: 'payg',
  quantity: 730, // hours
});

console.log(price.value);  // Unit price in USD
console.log(price.total);  // Total in selected currency

Currency Conversion

// Set currency
calc.setCurrency({ value: 'EUR', locked: false });

// Convert a price
const eurPrice = calc.convertToCurrency(100); // USD to EUR

// Format for display
const formatted = calc.formatPrice(eurPrice); // "€92.00"

Billing Options

type BillingOption = 
  | 'payg'           // Pay-as-you-go
  | '1-year'         // 1 Year Reserved
  | '3-year'         // 3 Year Reserved
  | '1-year-savings' // 1 Year Savings Plan
  | '3-year-savings' // 3 Year Savings Plan
  // ... and more

// Get available billing options for a SKU
const options = calc.getAvailableBillingOptions(pricingData, 'standard-d2s-v3', 'us-east');

// Calculate savings
const savings = calc.calculateSavings(
  pricingData,
  'standard-d2s-v3',
  'us-east',
  730, // hours per month
  '3-year'
);
console.log(`Save ${savings.percentage}% with 3-year reserved`);

Support Pricing

const supportCost = calc.calculateSupportCost(
  supportPricing,
  'premium',      // tier: 'free' | 'developer' | 'standard' | 'prodirect' | 'premium'
  5000,           // monthly spend
  10000           // upfront spend (reserved instances)
);

Full Estimate Calculation

const result = calc.calculateEstimate(
  modules,           // Array of CalculatorModule
  supportPricing,    // Support pricing data
  'standard',        // Support tier
  10                 // Markup percentage
);

console.log(result.moduleTotal);      // Sum of all modules
console.log(result.supportTotal);     // Support cost
console.log(result.markup);           // Markup amount
console.log(result.estimatePrice);    // Final monthly price
console.log(result.estimateUpfrontPrice); // Upfront costs

Estimate Management

Using EstimateManager

import { EstimateManager } from 'azure-pricing-calculator';

const manager = new EstimateManager(api, currencies);
await manager.initialize();

// Create a new estimate
const estimate = await manager.createEstimate('My Azure Estimate');

// Add a service
await manager.addModule(estimate.id, 'virtual-machines', 'v4', 'us-east');

// Get current totals
const totals = manager.getEstimateTotals(estimate.id);
console.log(`Monthly: ${totals.estimatePrice}`);

Storage

import { storage } from 'azure-pricing-calculator';

// Get all saved estimates
const estimates = await storage.getEstimates();

// Save an estimate
await storage.upsertEstimate(estimate);

// Export all data
const backup = await storage.exportData();

// Import data
await storage.importData(backup);

Types

Key Interfaces

interface Estimate {
  id: string;
  estimateName: string;
  modules: CalculatorModule[];
  discounts: Discounts;
  currentCurrency: CurrentCurrency;
  supportLevel: SupportTier;
  estimatePrice: number;
  estimateUpfrontPrice: number;
  // ... and more
}

interface PriceResult {
  value: number;       // Unit price in USD
  total: number;       // Total in selected currency
  pricingType: string; // e.g., "Consumption"
  sku: string[];       // Part numbers
  resourceId: string[];// Resource GUIDs
  region: string;
  offerKind: 'v2-flat' | 'v2-graduated' | 'v3-flat' | 'v3-graduated';
}

interface ServicePricingResponse {
  schema: ServiceSchema;
  offers: Offers;
  graduatedOffers?: GraduatedOffers;
  skus?: SkuMappings;
  regions?: Region[];
}

Discount Programs

Discount Description
payg Pay-as-you-go (default, no discount)
ea Enterprise Agreement (volume discounts)
mca Microsoft Customer Agreement (negotiated rates)
csp Cloud Solution Provider (partner pricing)
devtest Dev/Test pricing (reduced rates)
// Using EA pricing
const pricing = await api.fetchServicePricing('virtual-machines', {
  discounts: { base: 'ea', additional: ['msdn'] },
  enrollment: 'your-enrollment-number',
});

API Endpoints

The client interacts with these Azure endpoints:

Endpoint Purpose
/api/v{2,3,4}/pricing/{service}/calculator/ Service pricing
/api/v2/currencies/ Currency rates
/api/v2/pricing/calculator/regions/ Available regions
/api/v2/calculator/resources/ UI strings
/api/v2/calculator/config/ Feature flags
/user/info/ Authentication

Constants

import { 
  HOURS_PER_MONTH,  // 730
  HOURS_PER_DAY,    // 24
  DAYS_PER_MONTH,   // 31
  BILLING_MONTHS,   // { payg: 1, '1-year': 12, '3-year': 36, ... }
  DEFAULT_REGION,   // 'global'
} from 'azure-pricing-calculator';

Error Handling

import { HttpError } from 'azure-pricing-calculator';

try {
  const pricing = await api.fetchServicePricing('invalid-service');
} catch (error) {
  if (error instanceof HttpError) {
    console.log(`HTTP ${error.status}: ${error.message}`);
    console.log(`URL: ${error.url}`);
  }
}

Browser vs Node.js

This library works in both environments:

  • Browser: Uses native fetch and IndexedDB
  • Node.js: Requires node-fetch and uses localStorage fallback
// Node.js setup
import fetch from 'node-fetch';
globalThis.fetch = fetch;

Examples

See the examples/ directory for complete examples:

  • basic-vm-pricing.ts - Simple VM price lookup
  • full-estimate.ts - Complete estimate with multiple services
  • compare-billing.ts - Compare PAYG vs Reserved pricing
  • export-estimate.ts - Export estimate to JSON/Excel

License

MIT

Disclaimer

This library is not officially supported by Microsoft. It is based on publicly accessible APIs from the Azure Pricing Calculator. Use at your own risk.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors