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

  1. Authenticate to the API.
  2. Request a browse at the level you want (folders, then projects within a folder, then packages within a project).
  3. Poll for the result.
  4. 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 completedAt or errorMessage is 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.