Comprehensive, fully-typed Node.js/TypeScript library for the Datto RMM API v2.
- Complete Datto RMM API v2 coverage (50+ endpoints)
- OAuth 2.0 token lifecycle management (100-hour expiry, auto-refresh)
- Platform-aware (6 platforms: Pinotage, Merlot, Concord, Vidal, Zinfandel, Syrah)
- Automatic pagination with nextPageUrl following
- Rate limiting (600 req/60s with IP block protection)
- 25+ typed alert context discriminated unions
- Unix timestamp handling (millisecond precision)
- Full TypeScript support with strict mode
npm install node-datto-rmmimport { DattoRmmClient } from 'node-datto-rmm';
const client = new DattoRmmClient({
apiKey: process.env.DATTO_API_KEY,
apiSecretKey: process.env.DATTO_API_SECRET,
platform: 'merlot', // or 'pinotage', 'concord', 'vidal', 'zinfandel', 'syrah'
});
// Get account info
const account = await client.account.get();
// List all devices with automatic pagination
for await (const device of client.account.devicesAll()) {
console.log(device.hostname, device.operatingSystem);
}
// Resolve an alert
await client.alerts.resolve('alert-uid-here');const client = new DattoRmmClient({
// Required
apiKey: 'your-api-key',
apiSecretKey: 'your-api-secret-key',
// Platform (required) - determines API base URL
platform: 'merlot',
// OR explicit API URL (alternative to platform)
// apiUrl: 'https://merlot-api.centrastage.net',
// Optional: timestamp format in responses
timestamps: 'date', // 'date' | 'number' | 'iso'
// Optional: rate limiting configuration
rateLimit: {
enabled: true,
maxRequests: 600,
windowMs: 60000,
throttleThreshold: 0.8,
},
});| Platform | API URL |
|---|---|
| pinotage | https://pinotage-api.centrastage.net |
| merlot | https://merlot-api.centrastage.net |
| concord | https://concord-api.centrastage.net |
| vidal | https://vidal-api.centrastage.net |
| zinfandel | https://zinfandel-api.centrastage.net |
| syrah | https://syrah-api.centrastage.net |
client.account.get()- Get account infoclient.account.users()- List usersclient.account.sites()/sitesAll()- List sitesclient.account.devices()/devicesAll()- List devicesclient.account.components()- List componentsclient.account.alertsOpen()/alertsOpenAll()- Open alertsclient.account.alertsResolved()/alertsResolvedAll()- Resolved alertsclient.account.variables()- List variablesclient.account.createVariable()/updateVariable()/deleteVariable()
client.sites.get(siteUid)- Get siteclient.sites.create(data)- Create siteclient.sites.update(siteUid, data)- Update siteclient.sites.devices(siteUid)/devicesAll(siteUid)- List site devicesclient.sites.settings(siteUid)- Get site settingsclient.sites.filters(siteUid)- Get site filtersclient.sites.alertsOpen(siteUid)/alertsResolved(siteUid)client.sites.variables(siteUid)- CRUD operations
client.devices.get(deviceUid)- Get by UIDclient.devices.getById(deviceId)- Get by numeric IDclient.devices.getByMac(macAddress)- Get by MAC addressclient.devices.move(deviceUid, siteUid)- Move to siteclient.devices.createQuickJob(deviceUid, data)- Create quick jobclient.devices.setUdf(deviceUid, data)- Set user-defined fieldsclient.devices.updateWarranty(deviceUid, data)- Update warranty
client.alerts.get(alertUid)- Get alertclient.alerts.resolve(alertUid)- Resolve alertclient.alerts.mute(alertUid)- Mute alert (deprecated)client.alerts.unmute(alertUid)- Unmute alert (deprecated)
client.audit.device(deviceUid)- Full device auditclient.audit.deviceSoftware(deviceUid)- Software inventoryclient.audit.deviceByMac(macAddress)- Audit by MACclient.audit.esxiHost(deviceUid)- ESXi host auditclient.audit.printer(deviceUid)- Printer audit
client.jobs.get(jobUid)- Get job statusclient.jobs.results(jobUid, deviceUid)- Get resultsclient.jobs.stdout(jobUid, deviceUid)- Get stdoutclient.jobs.stderr(jobUid, deviceUid)- Get stderrclient.jobs.components(jobUid)- Get components
client.filters.defaults()- Default filtersclient.filters.custom()- Custom filters
client.system.status()- API statusclient.system.requestRate()- Current rate limit statusclient.system.pagination()- Pagination settings
import {
DattoRmmError,
DattoRmmAuthenticationError,
DattoRmmNotFoundError,
DattoRmmRateLimitError,
DattoRmmIpBlockedError,
} from 'node-datto-rmm';
try {
const device = await client.devices.get('invalid-uid');
} catch (error) {
if (error instanceof DattoRmmNotFoundError) {
console.log('Device not found');
} else if (error instanceof DattoRmmRateLimitError) {
console.log('Rate limited, retry after:', error.retryAfter);
} else if (error instanceof DattoRmmIpBlockedError) {
console.log('IP blocked for 5 minutes');
}
}Apache-2.0