Datto RMM Sites — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Datto RMM Sites (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Sites in Datto RMM represent client organizations or locations. Each site contains devices, has its own settings, and can have site-level variables. Sites provide organizational hierarchy and enable scoped operations - alerts, jobs, and reports can all be filtered by site.
autotask-crm; as adocumentation entity, itglue-organizations; as a SOC tenant, rocketcyber-accounts. None of these share IDs with a Datto RMM site.
datto-rmm-devices.
Account
└── Sites (many)
└── Devices (many per site)
└── Alerts, Jobs, Audit DataSites can represent:
| Identifier | Type | Description |
|---|---|---|
siteUid | string | Globally unique identifier |
siteId | integer | Legacy numeric ID |
name | string | Display name |
A Site carries identifiers, onDemand/splapiEnabled flags, optional proxySettings, device/alert counts, and a settings object (auto-patch approval, patch window, timezone). See references/fields.md for the complete interfaces.
async function findSiteByName(client, name) {
const response = await client.request('/api/v2/sites?max=250');
const sites = response.sites || [];
// Exact match first
const exact = sites.find(s =>
s.name.toLowerCase() === name.toLowerCase()
);
if (exact) return { found: true, site: exact };
// Partial match
const matches = sites.filter(s =>
s.name.toLowerCase().includes(name.toLowerCase())
);
if (matches.length === 0) {
return { found: false, suggestions: [] };
}
if (matches.length === 1) {
return { found: true, site: matches[0] };
}
return {
found: false,
ambiguous: true,
suggestions: matches.map(s => ({
name: s.name,
uid: s.uid,
deviceCount: s.devicesCount
}))
};
}Site health scoring (device status + alert priority weighted into a 0-100 score), a multi-site summary sorted by open alerts, an onboarding checklist validator, and a safe CRUD wrapper are in references/examples.md.
GET /api/v2/sites?max=250 - list all sitesGET /api/v2/site/{siteUid} - get a single siteGET /api/v2/site/{siteUid}/devices?max=250 - devices at a siteGET /api/v2/site/{siteUid}/alerts/open / .../alerts/resolved?max=250 - site-scoped alertsPOST /api/v2/sites - create a sitePOST /api/v2/site/{siteUid} - update a siteDELETE /api/v2/site/{siteUid} - delete a site (devices become unassigned, not deleted)See references/api.md for full request/response examples.
settings.timezone drives when the patch window actually runs.openAlertsCount/devicesCount are raw counts; any "healthy/warning/critical" status is computed client-side (see reference examples).See references/errors.md for the full site API error table.
Recommended Format: {ClientName} - {Location/Purpose}
Examples:
Acme Corp - Main OfficeAcme Corp - Remote WorkersTechStart Inc - Data CenterInternal - IT Department~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.