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

  1. Authenticate to the API.
  2. Request the scan against a target server.
  3. Poll for its result.
  4. 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 completedAt or errorMessage is 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.