Datto RMM Jobs — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Datto RMM Jobs (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.
Jobs in Datto RMM execute component scripts on devices. Quick jobs run immediately; scheduled jobs run at specified times. Each job can accept variables, produces output (stdout/stderr), and has a status lifecycle. This skill covers job execution, monitoring, and results retrieval.
agent procedures and exposes kaseya_vsa_run_procedure; use kaseya-vsa-api-patterns.
per run; account and site variables are a separate persistent store in datto-rmm-variables.
| Type | Description | Use Case |
|---|---|---|
| Quick Job | Runs immediately | Ad-hoc tasks, troubleshooting |
| Scheduled Job | Runs at specified time | Maintenance, recurring tasks |
| Policy Job | Runs based on policy | Automated responses |
Created → Queued → Running → Completed/Failed
│
└─→ TimeoutComponents are the scripts/programs that jobs execute:
A Job carries identifiers, target device/site, component, status, start/complete timestamps, exitCode/stdout/stderr results, and input variables. A Component declares its own typed ComponentVariable[] (name, type, required, default). See references/fields.md for the complete interfaces.
async function runJobAndWait(client, deviceUid, componentUid, variables = {}, options = {}) {
const { timeoutMs = 300000, pollIntervalMs = 5000 } = options;
// Create the job
const createResponse = await client.request(
`/api/v2/device/${deviceUid}/quickjob`,
{
method: 'POST',
body: JSON.stringify({ componentUid, variables })
}
);
const jobUid = createResponse.jobUid;
const startTime = Date.now();
// Poll for completion
while (true) {
const job = await client.request(`/api/v2/job/${jobUid}`);
if (job.status === 'completed' || job.status === 'failed' || job.status === 'timeout') {
return {
success: job.status === 'completed' && job.exitCode === 0,
job
};
}
// Check timeout
if (Date.now() - startTime > timeoutMs) {
return {
success: false,
job,
error: 'Job polling timeout exceeded'
};
}
await sleep(pollIntervalMs);
}
}Related helpers - component lookup by name, batch execution across multiple devices, multi-job monitoring, result summarization, and a "safe run" wrapper that pre-validates device status and required variables - are in references/examples.md.
GET /api/v2/components?max=250 - list components (with their variable schemas)POST /api/v2/device/{deviceUid}/quickjob - create a quick job (componentUid + variables)GET /api/v2/job/{jobUid} - poll job status/resultsGET /api/v2/device/{deviceUid}/jobs?max=50 - job history for a deviceGET /api/v2/site/{siteUid}/jobs?max=50 - job history for a siteSee references/api.md for full request/response examples.
device.status first, or fall back to a scheduled job.variables schema and validate before submitting.status === 'completed' alone - a component can complete with a nonzero exit code.| Exit Code | Typical Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Misuse of command |
| 126 | Permission denied |
| 127 | Command not found |
| 130 | Script terminated (Ctrl+C) |
| 137 | Killed (SIGKILL) |
| 143 | Terminated (SIGTERM) |
See references/errors.md for the full job API error table.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.