Asks the Worker to connect to a live SQL Server's msdb and pull its SQL Server Agent jobs as script text -- an alternative to pasting the script yourself into Parse a Job Import Script. This is another "enqueue a request, check on it later" flow, the same shape as Request an Elevated Role Scan: the API only records the request, the Worker does the actual connecting.
Having trouble reaching the API, or logging in from another machine? See Network Access & Authentication Security -- by default the Api only answers
localhost, and PowerShell needs an extra flag once it does answer elsewhere.
Order of Operations
- Authenticate to the API.
- Request the scan against a target server.
- Poll for its result.
- Feed the result into Parse (and later Commit's
HistoryJson, if you want run history backfilled too).
The calls
POST /api/job-import-scans
GET /api/job-import-scans/{jobImportScanRequestId}
Permission needed: Job.Edit for both.
C# example
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
// Step 1: Authenticate to the API.
using var handler = new HttpClientHandler { UseDefaultCredentials = true };
using var client = new HttpClient(handler) { BaseAddress = new Uri("http://your-minion-agent-server:5443") };
client.DefaultRequestHeaders.Add("X-App-Name", "MyIntegration");
// Step 2: Request the scan. CredentialId null uses the Worker's own service-account identity.
var scanRequest = new RequestJobImportScanRequest(TargetServerId: 7, CredentialId: null, HistoryDaysBack: 30, IncludeAllHistory: false);
var response = await client.PostAsJsonAsync("/api/job-import-scans", scanRequest, jsonOptions);
response.EnsureSuccessStatusCode();
var created = await response.Content.ReadFromJsonAsync<CreatedScanId>(jsonOptions);
Console.WriteLine($"Requested scan id: {created!.JobImportScanRequestID}");
// Step 3: Poll for the result.
JobImportScanStatusResponse? status;
do
{
await Task.Delay(TimeSpan.FromSeconds(5));
status = await client.GetFromJsonAsync<JobImportScanStatusResponse>($"/api/job-import-scans/{created.JobImportScanRequestID}", jsonOptions);
} while (status!.CompletedAt is null && status.ErrorMessage is null);
if (status.ErrorMessage is not null)
{
Console.WriteLine($"Scan failed: {status.ErrorMessage}");
}
else
{
// Step 4: Feed the result into Parse.
Console.WriteLine("Scan complete -- ready to parse ResultScriptText.");
}
record RequestJobImportScanRequest(int TargetServerId, int? CredentialId, int? HistoryDaysBack = null, bool IncludeAllHistory = false);
record CreatedScanId(long JobImportScanRequestID);
record JobImportScanStatusResponse(DateTime? CompletedAt, string? ResultScriptText, string? ResultHistoryJson, string? ErrorMessage);
Not on a domain machine? Swap in the app-account login from Calling the API From Your Own Code.
PowerShell example
# Step 1: Authenticate to the API.
$headers = @{ "X-App-Name" = "MyIntegration" }
# Step 2: Request the scan. CredentialId null uses the Worker's own service-account identity. (-AllowUnencryptedAuthentication: PowerShell requires this for Windows auth over plain http to anything but localhost -- see "Network Access & Authentication Security".)
$scanRequest = @{ TargetServerId = 7; CredentialId = $null; HistoryDaysBack = 30; IncludeAllHistory = $false } | ConvertTo-Json
$created = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-import-scans" `
-Method Post -Body $scanRequest -ContentType "application/json" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
"Requested scan id: $($created.jobImportScanRequestID)"
# Step 3: Poll for the result.
do {
Start-Sleep -Seconds 5
$status = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-import-scans/$($created.jobImportScanRequestID)" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
} while (-not $status.completedAt -and -not $status.errorMessage)
if ($status.errorMessage) {
"Scan failed: $($status.errorMessage)"
} else {
"Scan complete -- ready to parse ResultScriptText."
}
What you get back
POST -- 201 Created:
{ "jobImportScanRequestID": 88 }
GET -- 200 OK, before completion:
{ "completedAt": null, "resultScriptText": null, "resultHistoryJson": null, "errorMessage": null }
...and once the Worker finishes:
{ "completedAt": "2026-09-16T03:11:00Z", "resultScriptText": "EXEC msdb.dbo.sp_add_job ...", "resultHistoryJson": "[{...}]", "errorMessage": null }
resultScriptText is exactly what you'd hand to Parse a Job Import Script; resultHistoryJson is what you'd hand to Commit a Job Import's optional HistoryJson.
Codes this call can return
See API Response Codes for what each one means in general. For these calls:
- 201 -- scan requested.
- 200 -- status returned (poll until
completedAtorerrorMessageis set). - 403 -- you don't have
Job.Edit. - 404 -- (
GET) no scan request exists with that id.
There's no endpoint to list past scans -- keep the id from the 201 response; it's the only way to check on that scan again.
What gets audited
The POST is recorded as JobImportScanRequest / Request Job Import Scan, with the target server and credential choice in the after-state. The GET status check isn't audited.
See also: Parse a Job Import Script, Commit a Job Import, List Target Servers.