Looks up the folders, projects, or packages deployed to a target server's SSIS catalog (SSISDB) -- so you can populate an SSIS Package step (see Create a Job Step) with real names instead of typing them by hand. Like Request an Elevated Role Scan and Request a Job Import Scan, this is an enqueue-and-poll flow: 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 a browse at the level you want (folders, then projects within a folder, then packages within a project).
- Poll for the result.
- Use the returned names in Create a Job Step / Update a Step.
The calls
POST /api/ssis/catalog-browse
GET /api/ssis/catalog-browse/{id}
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 a browse. Leave FolderName/ProjectName null to list folders; set FolderName to list its projects;
// set both to list a project's packages. CredentialId null uses the Worker's own Windows identity.
var browseRequest = new RequestSsisCatalogBrowseRequest(TargetServerId: 7, CredentialId: null, FolderName: "ETL", ProjectName: null);
var response = await client.PostAsJsonAsync("/api/ssis/catalog-browse", browseRequest, jsonOptions);
response.EnsureSuccessStatusCode();
var created = await response.Content.ReadFromJsonAsync<CreatedBrowseId>(jsonOptions);
Console.WriteLine($"Requested browse id: {created!.SsisCatalogBrowseRequestID}");
// Step 3: Poll for the result.
SsisCatalogBrowseStatusResponse? status;
do
{
await Task.Delay(TimeSpan.FromSeconds(3));
status = await client.GetFromJsonAsync<SsisCatalogBrowseStatusResponse>($"/api/ssis/catalog-browse/{created.SsisCatalogBrowseRequestID}", jsonOptions);
} while (status!.CompletedAt is null && status.ErrorMessage is null);
if (status.ErrorMessage is not null)
{
Console.WriteLine($"Browse failed: {status.ErrorMessage}");
}
else
{
// Step 4: Use the returned names. ResultJson is a flat JSON array of strings at the level you asked for.
var names = JsonSerializer.Deserialize<string[]>(status.ResultJson!, jsonOptions);
foreach (var name in names!)
Console.WriteLine(name);
}
record RequestSsisCatalogBrowseRequest(int TargetServerId, int? CredentialId, string? FolderName = null, string? ProjectName = null);
record CreatedBrowseId(long SsisCatalogBrowseRequestID);
record SsisCatalogBrowseStatusResponse(DateTime? CompletedAt, string? ResultJson, 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 a browse. Leave FolderName/ProjectName null to list folders; set FolderName to list its projects;
# set both to list a project's packages. (-AllowUnencryptedAuthentication: PowerShell requires this for Windows auth over plain http to anything but localhost -- see "Network Access & Authentication Security".)
$browseRequest = @{ TargetServerId = 7; CredentialId = $null; FolderName = "ETL"; ProjectName = $null } | ConvertTo-Json
$created = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/ssis/catalog-browse" `
-Method Post -Body $browseRequest -ContentType "application/json" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
"Requested browse id: $($created.ssisCatalogBrowseRequestID)"
# Step 3: Poll for the result.
do {
Start-Sleep -Seconds 3
$status = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/ssis/catalog-browse/$($created.ssisCatalogBrowseRequestID)" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
} while (-not $status.completedAt -and -not $status.errorMessage)
if ($status.errorMessage) {
"Browse failed: $($status.errorMessage)"
} else {
# Step 4: Use the returned names. ResultJson is a flat JSON array of strings at the level you asked for.
$names = $status.resultJson | ConvertFrom-Json
$names
}
Picking a level
FolderName: null, ProjectName: null-- lists every folder in the catalog.FolderName: "ETL", ProjectName: null-- lists every project in that folder.FolderName: "ETL", ProjectName: "LoadWarehouse"-- lists every package in that project.
You can't set ProjectName without FolderName -- there's no cross-folder project lookup.
What you get back
POST -- 201 Created:
{ "ssisCatalogBrowseRequestID": 19 }
GET -- 200 OK, once complete:
{ "completedAt": "2026-09-16T04:02:11Z", "resultJson": "[\"LoadWarehouse\", \"LoadStaging\"]", "errorMessage": null }
resultJson is always a flat JSON array of names at whichever level you asked for -- never a nested folder/project/package tree.
Codes this call can return
See API Response Codes for what each one means in general. For these calls:
- 201 -- browse requested.
- 200 -- status returned (poll until
completedAtorerrorMessageis set). - 403 -- you don't have
Job.Edit. - 404 -- (
GET) no browse request exists with that id.
There's no endpoint to list past browse requests -- keep the id from the 201 response.
What gets audited
The POST is recorded as SsisCatalogBrowseRequest / Request SSIS Catalog Browse, with the target server, credential choice, and requested folder/project in the after-state. The GET status check isn't audited.
See also: Create a Job Step, Update a Step, List Target Servers.