/saas/pax8-mcp
  • JavaScript 100%
Find a file
2026-03-06 14:18:04 -06:00
examples Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
src Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
tests Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
.env.example Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
.gitignore Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
COMPLETION_SUMMARY.md Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
IMPLEMENTATION_GUIDE.md Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
package.json Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
QUICK_REFERENCE.md Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00
README.md Initial import from SharePoint mirror 2026-03-06 14:18:04 -06:00

Pax8 API Integration Tool

A reusable Node.js API client for retrieving Pax8 subscription data with automatic caching, pagination handling, and enriched company/product information.

Features

OAuth 2.0 Authentication - Secure token management with automatic caching and refresh
Paginated Subscriptions Fetching - Automatically handles all pages of results
Company & Product Lookups - Cached enrichment of subscription data with names
Flexible Filtering - Filter subscriptions by company, product, status, billing term
Subscription Summary - Extract Company, Product, Quantity, Next Renewal Date, Commitment Duration
Error Handling - Comprehensive error messages for auth failures, rate limits, API errors
Fully Tested - Jest unit tests for all modules with mocked API calls

Installation

  1. Clone or download this repository

  2. Install dependencies

npm install
  1. Set up environment variables
cp .env.example .env
  1. Add your Pax8 API credentials to .env

Quick Start

Basic Usage

const Pax8Client = require('./src/pax8-client');

// Create client (loads credentials from .env)
const client = new Pax8Client();

// Get subscription summary with all required fields
const summary = await client.getSubscriptionSummary();
console.log(summary);

/* Output:
[
  {
    Company: 'Acme Corp',
    Product: 'Microsoft 365 Business Standard',
    Quantity: 50,
    'Next Renewal Date': '2025-12-31',
    'Commitment Duration': '3-Year'
  },
  ...
]
*/

Get All Subscriptions (Enriched with Company & Product Names)

const enriched = await client.getAllSubscriptionsEnriched();
console.log(enriched);

Get Subscriptions for Specific Company

const companyId = 'f7fc273a-8d86-45c9-a26f-ffd42416adda';
const subs = await client.getCompanySubscriptions(companyId);

Filter Subscriptions

const summary = await client.getSubscriptionSummary({
  companyId: 'company-uuid',  // Optional: filter by company
  productId: 'product-uuid',  // Optional: filter by product
  status: 'Active',           // Optional: default is 'Active'
});

API Reference

Pax8Client

Main facade class combining all functionality.

Constructor

new Pax8Client(options)

Options:

  • clientId (string): Pax8 Client ID. Defaults to PAX8_CLIENT_ID env var.
  • clientSecret (string): Pax8 Client Secret. Defaults to PAX8_CLIENT_SECRET env var.
  • validateOnInit (boolean): Validate config on creation. Default: true.

Methods

getSubscriptionSummary(options)

Fetches subscriptions with Company, Product, Quantity, Next Renewal Date, and Commitment Duration.

Parameters:

{
  status: 'Active',        // Filter by status (optional, default: 'Active')
  companyId: 'uuid',       // Filter by company (optional)
  productId: 'uuid',       // Filter by product (optional)
  fetchAll: true           // Fetch all pages (optional, default: true)
}

Returns: Promise resolving to array of subscription summaries

Example:

const summary = await client.getSubscriptionSummary({
  status: 'Active',
  companyId: 'comp-123'
});
// Returns:
// [
//   {
//     Company: 'Acme Corp',
//     Product: 'Cloud Suite',
//     Quantity: 10,
//     'Next Renewal Date': '2025-12-31',
//     'Commitment Duration': '3-Year',
//     _subscription: { id, status, billingTerm, price, ... }
//   }
// ]
getAllSubscriptionsEnriched(options)

Fetches all subscriptions with company and product names added.

Parameters: Same as getSubscriptionSummary

Returns: Promise resolving to array of enriched subscription objects

getCompanySubscriptions(companyId, options)

Fetches subscriptions for a specific company.

Parameters:

  • companyId (string): Company UUID
  • options (Object): Query options (size, sort, etc.)

Returns: Promise resolving to array of subscriptions with product names

clearCaches()

Clears all internal caches (companies, products, tokens).

client.clearCaches();
getStatus()

Returns cache and token status information.

const status = client.getStatus();
// Returns:
// {
//   token: { hasToken: true, isValid: true, expiresAt: '...' },
//   companies: { cachedCompanies: 150, cacheValid: true, cacheAge: 5000 },
//   products: { cachedProducts: 500, cacheValid: true, cacheAge: 5000 }
// }

Auth Module

Low-level authentication handling.

const auth = require('./src/pax8-client/auth');

// Get access token (cached automatically)
const token = await auth.getAccessToken(clientId, clientSecret);

// Check token validity
const status = auth.getTokenCacheStatus();

// Clear cache
auth.clearTokenCache();

Subscriptions Module

Direct access to subscription fetching.

const subs = require('./src/pax8-client/subscriptions');

// Get all subscriptions
const all = await subs.getAllSubscriptions(token);

// Get subscriptions for company
const byCompany = await subs.getSubscriptionsForCompany(token, 'comp-id');

// Get subscriptions for product
const byProduct = await subs.getSubscriptionsForProduct(token, 'prod-id');

// Get only active subscriptions
const active = await subs.getActiveSubscriptions(token);

Companies Module

Company lookup and caching.

const companies = require('./src/pax8-client/companies');

// Get all companies
const all = await companies.getAllCompanies(token);

// Get specific company
const company = await companies.getCompanyById(token, 'comp-id');

// Get company name
const name = await companies.getCompanyName(token, 'comp-id');

// Get company name map (companyId → name)
const map = await companies.getCompanyNameMap(token);
// { 'comp-1': 'Acme Corp', 'comp-2': 'Tech Inc', ... }

// Cache management
companies.clearCache();
const status = companies.getCacheStatus();

Products Module

Product lookup and caching.

const products = require('./src/pax8-client/products');

// Get all products
const all = await products.getAllProducts(token);

// Get specific product
const product = await products.getProductById(token, 'prod-id');

// Get product name
const name = await products.getProductName(token, 'prod-id');

// Get product name map (productId → name)
const map = await products.getProductNameMap(token);

// Cache management
products.clearCache();
const status = products.getCacheStatus();

Subscription Summary Data Format

The main output of getSubscriptionSummary() is an array of objects with these fields:

Field Type Description
Company string Company name from Pax8
Product string Product name from Pax8
Quantity number Number of licenses/seats
Next Renewal Date string ISO date (YYYY-MM-DD) or 'N/A'
Commitment Duration string e.g., "3-Year", "Annual", "Monthly", or 'N/A'
_subscription object Original subscription data (hidden by default)

Example Response

[
  {
    Company: 'Acme Corporation',
    Product: 'Microsoft 365 Business Premium',
    Quantity: 50,
    'Next Renewal Date': '2026-05-15',
    'Commitment Duration': '3-Year'
  },
  {
    Company: 'Acme Corporation',
    Product: 'Adobe Creative Cloud',
    Quantity: 10,
    'Next Renewal Date': '2024-12-31',
    'Commitment Duration': 'Annual'
  },
  {
    Company: 'TechStart Inc',
    Product: 'Slack Workspace',
    Quantity: 75,
    'Next Renewal Date': 'N/A',
    'Commitment Duration': 'Monthly'
  }
]

Testing

Run the test suite:

npm test

Run tests in watch mode:

npm run test:watch

View coverage report:

npm test -- --coverage

Error Handling

The client provides detailed error messages:

Authentication Errors

try {
  const client = new Pax8Client();
  await client.getSubscriptionSummary();
} catch (error) {
  if (error.message.includes('Missing required environment variables')) {
    console.error('Set PAX8_CLIENT_ID and PAX8_CLIENT_SECRET in .env');
  }
  if (error.message.includes('authentication failed')) {
    console.error('Invalid Pax8 credentials');
  }
}

API Errors

try {
  const summary = await client.getSubscriptionSummary();
} catch (error) {
  if (error.message.includes('429')) {
    console.error('Rate limit exceeded (1000 calls/minute)');
  }
  if (error.message.includes('401')) {
    console.error('Unauthorized - check credentials');
  }
  if (error.message.includes('404')) {
    console.error('Resource not found');
  }
}

Caching

The client implements intelligent caching to minimize API calls:

  • Token Cache: Access tokens are cached for 24 hours with automatic refresh 5 minutes before expiry
  • Company Cache: Company names are cached for 1 hour
  • Product Cache: Product names are cached for 1 hour

Clear caches manually when needed:

client.clearCaches();

Rate Limiting

Pax8 API allows 1000 successful requests per minute. The client automatically handles pagination but does not implement rate limiting. If you expect to exceed this limit:

  • Implement exponential backoff for retries
  • Use filtering to reduce data fetched
  • Batch operations across multiple client instances

Performance Tips

  1. Use filters to reduce data returned:

    const summary = await client.getSubscriptionSummary({ 
      status: 'Active',
      companyId: 'specific-company'
    });
    
  2. Reuse the same client instance to benefit from caching:

    const client = new Pax8Client();
    const summary1 = await client.getSubscriptionSummary();
    const summary2 = await client.getSubscriptionSummary(); // Uses cached companies/products
    
  3. Only fetch what you need:

    // Get raw data without company/product enrichment for faster response
    const raw = await subscriptions.getAllSubscriptions(token);
    

Troubleshooting

Missing required environment variables

Solution: Copy .env.example to .env and fill in your credentials:

cp .env.example .env
# Edit .env with your Pax8 API credentials

authentication failed (401): Unauthorized

Solution: Verify your credentials:

  1. Log in to https://app.pax8.com
  2. Go to Settings > Integrations > API Keys
  3. Create a new API credential or verify existing one
  4. Update .env file

No subscriptions returned

Solution: Check filters and account status:

  1. Verify the account actually has subscriptions
  2. Try removing filters: await client.getSubscriptionSummary({})
  3. Check subscription status: use status: null to include all (except the code defaults to 'Active')

Slow performance

Solution: Implement pagination:

// Instead of fetching all, get one page
const summary = await client.getSubscriptionSummary({
  fetchAll: false  // Only returns first page
});

API Documentation

For detailed Pax8 API documentation, visit:

Contributing

This is a read-only client library. For Pax8 API issues, contact: integrations@pax8.com

License

MIT

Support

For issues with this client:

  1. Check the error messages in Troubleshooting section
  2. Review the test suite in tests/pax8-client.test.js for usage examples
  3. Ensure all environment variables are set correctly
  4. Contact your Pax8 account representative for API credential issues