Comprehensive, fully-typed Node.js/TypeScript library for the IT Glue API.
- Complete API coverage - Every documented IT Glue endpoint is implemented
- Strong TypeScript types - Full type definitions for all request/response payloads
- JSON:API abstraction - Unwrap the JSON:API envelope so consumers work with clean objects
- Automatic pagination - Iterator/generator patterns for seamless multi-page retrieval
- Rate limit handling - Built-in request throttling (3000 req / 5 min) with backoff
- Zero live API testing - Full test suite with mocked HTTP responses
npm install node-it-glueimport { ITGlueClient } from 'node-it-glue';
const client = new ITGlueClient({
apiKey: 'ITG.xxxxxxxxxxxxxxxxxxxxxxxx',
region: 'us', // 'us' | 'eu' | 'au'
});
// List organizations
const { data, meta } = await client.organizations.list({
filter: { organizationStatusId: 1 },
page: { size: 50 },
});
console.log(`Found ${meta.totalCount} organizations`);
for (const org of data) {
console.log(org.name);
}
// Auto-paginate all configurations for an org
for await (const config of client.configurations.listAll({
filter: { organizationId: 12345 },
})) {
console.log(config.name, config.serialNumber);
}const client = new ITGlueClient({
apiKey: 'ITG.xxxxxxxxxxxxxxxxxxxxxxxx', // Required
region: 'us', // 'us' | 'eu' | 'au' (default: 'us')
// OR explicit base URL:
// baseUrl: 'https://api.itglue.com',
timeout: 30000, // Request timeout in ms (default: 30000)
rateLimiter: { // Rate limiting options
enabled: true, // Enable rate limiting (default: true)
maxRequests: 3000, // Max requests per window (default: 3000)
windowMs: 300000, // Window duration in ms (default: 5 minutes)
throttleThreshold: 0.8, // Start throttling at 80% (default: 0.8)
retryAfterMs: 5000, // Retry delay (default: 5000)
maxRetries: 3 // Max retry attempts (default: 3)
}
});| Region | Base URL |
|---|---|
us |
https://api.itglue.com |
eu |
https://api.eu.itglue.com |
au |
https://api.au.itglue.com |
All list methods return paginated results. You can manually paginate:
const page1 = await client.organizations.list({ page: { size: 50, number: 1 } });
const page2 = await client.organizations.list({ page: { size: 50, number: 2 } });Or use automatic pagination with async iterators:
// Iterate through all items
for await (const org of client.organizations.listAll()) {
console.log(org.name);
}
// Collect all into an array
const allOrgs = await client.organizations.listAll().toArray();IT Glue supports extensive filtering options:
const orgs = await client.organizations.list({
filter: {
name: 'Acme',
organizationTypeId: 42,
organizationStatusId: 1,
excludeId: [100, 200],
createdAt: { gt: '2024-01-01' },
updatedAt: { lt: '2025-01-01' },
},
sort: 'name', // or '-name' for descending
page: { size: 100, number: 1 },
include: 'locations', // sideload related resources
});The library provides typed error classes for different error scenarios:
import {
ITGlueClient,
ITGlueNotFoundError,
ITGlueValidationError,
ITGlueAuthenticationError,
ITGlueRateLimitError,
} from 'node-it-glue';
try {
await client.organizations.get('12345');
} catch (error) {
if (error instanceof ITGlueNotFoundError) {
console.error('Organization not found');
} else if (error instanceof ITGlueValidationError) {
console.error('Validation errors:', error.getErrorMessages());
} else if (error instanceof ITGlueAuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof ITGlueRateLimitError) {
console.error('Rate limited, retry after:', error.retryAfter);
} else {
throw error;
}
}// List
const { data, meta } = await client.organizations.list(params?);
// List all (auto-paginate)
for await (const org of client.organizations.listAll(params?)) { }
// Get
const org = await client.organizations.get(id, params?);
// Create
const newOrg = await client.organizations.create(data);
// Update
const updated = await client.organizations.update(id, data);
// Delete
await client.organizations.delete(id);const { data } = await client.organizationTypes.list(params?);
const newType = await client.organizationTypes.create(data);
const updated = await client.organizationTypes.update(id, data);const { data } = await client.organizationStatuses.list(params?);
const newStatus = await client.organizationStatuses.create(data);
const updated = await client.organizationStatuses.update(id, data);// List all configurations
const { data } = await client.configurations.list();
// List configurations for an organization
const { data } = await client.configurations.listByOrg(orgId);
// Get with related data
const config = await client.configurations.get(id, {
include: 'configuration_interfaces,related_items',
});
// Create
const newConfig = await client.configurations.create({
organizationId: 123,
configurationTypeId: 1,
name: 'Server-01',
});// Configuration Types
const { data } = await client.configurationTypes.list();
const type = await client.configurationTypes.create({ name: 'Server' });
// Configuration Statuses
const { data } = await client.configurationStatuses.list();
const status = await client.configurationStatuses.create({ name: 'Active' });
// Configuration Interfaces (nested under configurations)
const { data } = await client.configurationInterfaces.listByConfig(configId);
const iface = await client.configurationInterfaces.create({
configurationId: 123,
name: 'eth0',
ipAddress: '192.168.1.1',
});// List contacts
const { data } = await client.contacts.list();
// List contacts for an organization
const { data } = await client.contacts.listByOrg(orgId);
// Create a contact
const contact = await client.contacts.create({
organizationId: 123,
firstName: 'John',
lastName: 'Doe',
contactTypeId: 1,
});const { data } = await client.contactTypes.list();
const type = await client.contactTypes.create({ name: 'Technical' });// List documents
const { data } = await client.documents.list();
// List documents for an organization
const { data } = await client.documents.listByOrg(orgId);
// Create a document
const doc = await client.documents.create({
organizationId: 123,
name: 'Network Diagram',
});
// Publish a document
await client.documents.publish(docId);// Document Sections
const { data } = await client.documentSections.listByDoc(docId);
const section = await client.documentSections.create(docId, {
name: 'Overview',
content: '<p>Introduction...</p>',
});
// Document Images
const { data } = await client.documentImages.list();
const image = await client.documentImages.create({
documentId: 123,
content: base64ImageData,
});// List passwords (values hidden by default)
const { data } = await client.passwords.list();
// List passwords with values visible
const { data } = await client.passwords.list({ showPassword: true });
// Get a password with value
const pwd = await client.passwords.get(id, { showPassword: true });
// Create a password
const newPwd = await client.passwords.create({
organizationId: 123,
name: 'Admin Password',
password: 'secret123',
passwordCategoryId: 1,
});// Password Categories
const { data } = await client.passwordCategories.list();
const cat = await client.passwordCategories.create({ name: 'Server Credentials' });
// Password Folders (nested under organizations)
const { data } = await client.passwordFolders.listByOrg(orgId);
const folder = await client.passwordFolders.create(orgId, { name: 'Production' });// List flexible asset types
const { data: types } = await client.flexibleAssetTypes.list();
// List flexible assets (requires filter)
const { data } = await client.flexibleAssets.list({
filter: { flexibleAssetTypeId: 123 },
});
// Create a flexible asset
const asset = await client.flexibleAssets.create({
organizationId: 123,
flexibleAssetTypeId: 456,
traits: {
'custom-field-1': 'value1',
'custom-field-2': 'value2',
},
});// Flexible Asset Types
const { data } = await client.flexibleAssetTypes.list();
const type = await client.flexibleAssetTypes.create({
name: 'Network Documentation',
icon: 'sitemap',
});
// Flexible Asset Fields (nested under types)
const { data } = await client.flexibleAssetFields.listByType(typeId);
const field = await client.flexibleAssetFields.create({
flexibleAssetTypeId: 123,
name: 'IP Range',
kind: 'Text',
});// List locations for an organization
const { data } = await client.locations.listByOrg(orgId);
// Create a location
const loc = await client.locations.create({
organizationId: 123,
name: 'Main Office',
addressLine1: '123 Main St',
city: 'Springfield',
postalCode: '12345',
countryId: 1,
regionId: 1,
});// Users (read-only creation, can update)
const { data } = await client.users.list();
const user = await client.users.get(userId);
const updated = await client.users.update(userId, { firstName: 'Jane' });
// Bulk update users
const results = await client.users.bulkUpdate({
users: [
{ id: 1, firstName: 'Jane' },
{ id: 2, lastName: 'Smith' },
],
});
// User Metrics
const { data } = await client.userMetrics.list({
filter: { userId: 123, date: '2024-01-01' },
});
// Groups
const { data } = await client.groups.list();
const group = await client.groups.create({ name: 'Admins' });// Manufacturers
const { data } = await client.manufacturers.list();
const mfg = await client.manufacturers.create({ name: 'Dell' });
// Models (nested under manufacturers)
const { data } = await client.models.listByManufacturer(mfgId);
const model = await client.models.create({ manufacturerId: 1, name: 'PowerEdge R640' });
// Platforms (read-only)
const { data } = await client.platforms.list();
// Operating Systems (read-only)
const { data } = await client.operatingSystems.list();
// Countries (read-only)
const { data } = await client.countries.list();
const country = await client.countries.get(countryId);
// Regions (nested under countries, read-only)
const { data } = await client.regions.listByCountry(countryId);// Domains (nested under organizations, read-only)
const { data } = await client.domains.listByOrg(orgId);
// Expirations (read-only)
const { data } = await client.expirations.list();
const exp = await client.expirations.get(expId);
// Logs (read-only)
const { data } = await client.logs.list();
for await (const log of client.logs.listAll()) {
console.log(log.action);
}
// Attachments (nested under various resources)
const { data } = await client.attachments.list('configurations', configId);
const att = await client.attachments.create('configurations', configId, {
name: 'diagram.png',
content: base64Data,
});
await client.attachments.delete('configurations', configId, attachmentId);
// Related Items
await client.relatedItems.create('configurations', configId, {
destinationType: 'passwords',
destinationId: passwordId,
});
await client.relatedItems.delete('configurations', configId, relatedItemId);
// Exports
const exportJob = await client.exports.create({
organizationIds: [123, 456],
includePasswords: true,
});
const status = await client.exports.get(exportJob.id);
// Checklists (nested under organizations)
const { data } = await client.checklists.listByOrg(orgId);
const checklist = await client.checklists.get(checklistId);
const updated = await client.checklists.update(checklistId, { completed: true });| Resource | Methods |
|---|---|
organizations |
list, listAll, get, create, update, delete |
organizationTypes |
list, listAll, get, create, update |
organizationStatuses |
list, listAll, get, create, update |
configurations |
list, listAll, listByOrg, listAllByOrg, get, create, update, delete |
configurationTypes |
list, listAll, get, create, update, delete |
configurationStatuses |
list, listAll, get, create, update, delete |
configurationInterfaces |
listByConfig, create, update, delete |
contacts |
list, listAll, listByOrg, listAllByOrg, get, create, update, delete |
contactTypes |
list, listAll, get, create, update |
documents |
list, listAll, listByOrg, listAllByOrg, get, create, update, delete, publish |
documentSections |
listByDoc, create, update, delete |
documentImages |
list, create, delete |
passwords |
list, listAll, listByOrg, listAllByOrg, get, create, update, delete |
passwordCategories |
list, listAll, get, create, update, delete |
passwordFolders |
listByOrg, create, update, delete |
flexibleAssetTypes |
list, listAll, get, create, update, delete |
flexibleAssetFields |
listByType, create, update, delete |
flexibleAssets |
list, listAll, get, create, update, delete |
locations |
listByOrg, create, update, delete |
users |
list, listAll, get, update, bulkUpdate |
userMetrics |
list, listAll |
groups |
list, listAll, get, create, update, delete |
manufacturers |
list, listAll, get, create, update |
models |
listByManufacturer, create, update |
platforms |
list |
operatingSystems |
list |
countries |
list, listAll, get |
regions |
listByCountry |
domains |
listByOrg |
expirations |
list, listAll, get |
logs |
list, listAll |
attachments |
list, create, update, delete |
relatedItems |
create, update, delete |
exports |
list, listAll, get, create, delete |
checklists |
listByOrg, get, update, delete |
The library automatically handles IT Glue's rate limits (3000 requests per 5 minutes):
- Request tracking - Counts requests within the rolling window
- Preemptive throttling - Slows down when approaching the limit (default: 80%)
- 429 handling - Automatically retries with exponential backoff
- Configurable - Adjust thresholds or disable entirely
Monitor rate limit status:
const status = client.getRateLimitStatus();
console.log(`Requests: ${status.currentCount}/${status.maxRequests}`);
console.log(`Remaining: ${status.remaining}`);
console.log(`Is throttling: ${status.isThrottling}`);IT Glue uses the JSON:API specification. This library transparently handles:
- Deserialization - Flattens
attributesand converts kebab-case to camelCase - Serialization - Wraps data in JSON:API envelope for POST/PATCH requests
- Relationships - Preserves relationship links in a normalized format
- Pagination meta - Converts pagination info to camelCase
Raw API response:
{
"data": {
"id": "123",
"type": "organizations",
"attributes": {
"name": "Acme Corp",
"organization-type-name": "Customer",
"created-at": "2024-01-15T10:30:00.000Z"
}
}
}Deserialized client response:
{
id: '123',
type: 'organizations',
name: 'Acme Corp',
organizationTypeName: 'Customer',
createdAt: '2024-01-15T10:30:00.000Z'
}# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Type checking
npm run typecheck
# Build
npm run buildApache-2.0
Contributions are welcome! Please read our contributing guidelines before submitting a pull request.