Skip to content

TypeScript Client

The datto-rmm-api package provides a fully typed TypeScript client for the Datto RMM API.

Terminal window
pnpm add datto-rmm-api
import { createDattoClient, Platform } from 'datto-rmm-api';
// Create a client with OAuth credentials
const client = createDattoClient({
platform: Platform.MERLOT,
auth: {
apiKey: process.env.DATTO_API_KEY!,
apiSecret: process.env.DATTO_API_SECRET!,
},
});
// Make typed API calls
const { data, error } = await client.GET('/v2/account/devices');
if (error) {
console.error('API error:', error);
} else {
console.log('Devices:', data);
}

The Datto RMM API is hosted on multiple regional platforms. Choose the platform that matches your account:

import { Platform } from 'datto-rmm-api';
// Available platforms
Platform.PINOTAGE // https://pinotage-api.centrastage.net/api
Platform.MERLOT // https://merlot-api.centrastage.net/api
Platform.CONCORD // https://concord-api.centrastage.net/api
Platform.VIDAL // https://vidal-api.centrastage.net/api
Platform.ZINFANDEL // https://zinfandel-api.centrastage.net/api
Platform.SYRAH // https://syrah-api.centrastage.net/api

Provide your API key and secret, and the client will automatically manage token refresh:

const client = createDattoClient({
platform: Platform.MERLOT,
auth: {
apiKey: 'your-api-key',
apiSecret: 'your-api-secret',
},
});

The token manager:

  • Caches tokens in memory
  • Proactively refreshes tokens 5 minutes before expiry
  • Deduplicates concurrent refresh requests

For more control over token management (e.g., using a token store):

const client = createDattoClient({
platform: Platform.MERLOT,
auth: {
getToken: async () => {
return myTokenStore.getToken();
},
onAuthError: (error) => {
console.error('Auth failed:', error);
},
},
});
const { data, error } = await client.GET('/v2/account/devices');
if (data) {
for (const device of data.devices ?? []) {
console.log(device.hostname, device.intIpAddress);
}
}
const { data: device } = await client.GET('/v2/device/{deviceUid}', {
params: { path: { deviceUid: 'device-123' } },
});
console.log(device?.hostname, device?.lastSeen);
const { data } = await client.GET('/v2/device/{deviceUid}/alerts/open', {
params: { path: { deviceUid: 'device-123' } },
});
for (const alert of data?.alerts ?? []) {
console.log(alert.alertType, alert.message);
}
const { data, error } = await client.POST('/v2/alert/{alertUid}/resolve', {
params: { path: { alertUid: 'alert-456' } },
});
const { data } = await client.PUT('/v2/device/{deviceUid}/quickjob', {
params: { path: { deviceUid: 'device-123' } },
body: {
jobName: 'My Quick Job',
componentUid: 'component-789',
variables: {},
},
});
console.log('Job UID:', data?.job?.uid);
const { data } = await client.GET('/v2/account/sites');
for (const site of data?.sites ?? []) {
console.log(site.name, site.numberOfDevices);
}

Add custom middleware for logging, error handling, or other cross-cutting concerns:

const client = createDattoClient({
platform: Platform.MERLOT,
auth: { apiKey: '...', apiSecret: '...' },
middleware: [
{
onRequest({ request }) {
console.log('Request:', request.method, request.url);
return request;
},
onResponse({ response }) {
console.log('Response:', response.status);
return response;
},
},
],
});

All API types are exported for use in your application:

import type { components, paths } from 'datto-rmm-api/types';
// Use schema types
type Device = components['schemas']['Device'];
type Alert = components['schemas']['Alert'];
type Site = components['schemas']['Site'];
// Function with typed parameters
function processDevice(device: Device) {
console.log(device.hostname);
}
// Use path response types
type DevicesResponse = paths['/v2/account/devices']['get']['responses']['200']['content']['application/json'];

The client returns errors in the error field:

const { data, error, response } = await client.GET('/v2/account/devices');
if (error) {
// error contains the parsed error response
console.error('Error:', error);
// response contains the raw Response object
console.error('Status:', response?.status);
}

If the Datto RMM API is updated:

Terminal window
# Sync the latest OpenAPI spec
pnpm sync:openapi
# Regenerate clients
pnpm generate:api
# Rebuild
pnpm build