Parses SQL Server Agent job script (the exact T-SQL SSMS's "Script Job as -> CREATE To" produces) and returns a preview of what it found -- jobs, steps, schedules, flagged problems, and a proposed credential match per step -- without persisting anything. Nothing is created until you follow up with Commit a Job Import.
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.
- Get the script text (paste it directly, or get it from Request a Job Import Scan instead of typing it by hand).
- Parse it.
- Resolve any flagged step/schedule before committing.
The call
POST /api/job-imports/parse
Permission needed: Job.Edit.
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: You already have the script text (pasted, or from a scan's ResultScriptText).
var scriptText = File.ReadAllText(@"C:\temp\NightlyETL.sql");
// Step 3: Parse it.
var response = await client.PostAsJsonAsync("/api/job-imports/parse", new ImportParseRequest(scriptText), jsonOptions);
response.EnsureSuccessStatusCode();
var parsed = await response.Content.ReadFromJsonAsync<ImportParseResponse>(jsonOptions);
// Step 4: Check for flags before committing.
foreach (var job in parsed!.Jobs)
{
Console.WriteLine($"{job.JobName}: duplicate = {job.IsDuplicate}, can commit = {job.CanCommit}");
foreach (var step in job.Steps)
foreach (var flag in step.Flags)
Console.WriteLine($" step '{step.StepName}': [{flag.Severity}] {flag.Message}");
}
record ImportParseRequest(string ScriptText);
record ImportFlagDto(string Severity, string Message);
record ImportStepDto(int StepId, string StepName, string Subsystem, string CommandText, string? DatabaseName,
byte? StepTypeCode, int? MatchedCredentialId, string? MatchedCredentialName, ImportFlagDto[] Flags, bool CanCommit);
record ImportScheduleDto(string Name, string? Day, int? Ordinal, TimeSpan? StartTime, TimeSpan? EndTime,
int? MaxForTimeframe, int? FrequencyMinutes, bool RunOnStartup, ImportFlagDto[] Flags, bool CanCommit);
record ImportJobDto(string JobName, string? Description, bool Enabled, ImportStepDto[] Steps, ImportScheduleDto[] Schedules,
bool CanCommit, bool IsDuplicate = false, int? ExistingJobId = null);
record ImportParseResponse(ImportJobDto[] Jobs);
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: You already have the script text.
$scriptText = Get-Content -Raw -Path "C:\temp\NightlyETL.sql"
# Step 3: Parse it. (-AllowUnencryptedAuthentication: PowerShell requires this for Windows auth over plain http to anything but localhost -- see "Network Access & Authentication Security".)
$body = @{ ScriptText = $scriptText } | ConvertTo-Json
$parsed = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-imports/parse" `
-Method Post -Body $body -ContentType "application/json" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
# Step 4: Check for flags before committing.
foreach ($job in $parsed.jobs) {
"$($job.jobName): duplicate = $($job.isDuplicate), can commit = $($job.canCommit)"
foreach ($step in $job.steps) {
foreach ($flag in $step.flags) { " step '$($step.stepName)': [$($flag.severity)] $($flag.message)" }
}
}
What you get back
200 OK:
{
"jobs": [
{
"jobName": "Nightly ETL",
"description": "Imported nightly load",
"enabled": true,
"steps": [
{
"stepId": 1, "stepName": "Load Staging", "subsystem": "TSQL", "commandText": "EXEC dbo.LoadStaging",
"databaseName": "Warehouse", "stepTypeCode": 0, "matchedCredentialId": null, "matchedCredentialName": null,
"flags": [ { "severity": "Warning", "message": "No credential matched by name -- pick one before committing." } ],
"canCommit": false
}
],
"schedules": [
{ "name": "Nightly", "day": "Daily", "ordinal": null, "startTime": "02:00:00", "endTime": null, "maxForTimeframe": null, "frequencyMinutes": null, "runOnStartup": false, "flags": [], "canCommit": true }
],
"canCommit": false,
"isDuplicate": false,
"existingJobId": null
}
]
}
matchedCredentialId/matchedCredentialName is a name-match proposal against your existing credentials (List Credentials) -- it's a suggestion only, never pre-selected for you; you must supply a real CredentialId per step when you commit. isDuplicate/existingJobId is set when a job of the same name already exists and is active -- Parse's check is a convenience preview; Commit re-checks this itself as the authoritative decision.
Codes this call can return
See API Response Codes for what each one means in general. For this specific call:
- 200 -- parsed (even if every job/step ends up flagged
canCommit: false). - 400 -- the script text isn't parseable T-SQL in the expected SQL Agent script shape.
- 403 -- you don't have
Job.Edit.
Not audited -- nothing is persisted by this call.
See also: Commit a Job Import, Request a Job Import Scan.