A sync group is a named set of sync peers that a job can opt into (see Get / Set a Job's Sync Config). This is configuration only -- as of today, nothing in the API actually pushes a job's definition to a peer. There's no "sync now" or "push to peers" call anywhere; registering peers, grouping them, and opting a job in just records the intent. Treat this feature as fleet topology setup, not a working replication pipeline yet.

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. Get the id of every peer to include (from Manage Sync Peers).
  3. Create the group.

The calls

GET    /api/job-sync-groups
POST   /api/job-sync-groups
DELETE /api/job-sync-groups/{jobSyncGroupId}

Permission needed: Security.Manage for all three.

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 peer ids to include (from Manage Sync Peers).
var peerIds = new[] { 3, 5 };

// Step 3: Create the group.
var newGroup = new CreateJobSyncGroupRequest(GroupName: "Prod + DR", MemberSyncPeerIds: peerIds);
var response = await client.PostAsJsonAsync("/api/job-sync-groups", newGroup, jsonOptions);
response.EnsureSuccessStatusCode();
var created = await response.Content.ReadFromJsonAsync<CreatedGroupId>(jsonOptions);
Console.WriteLine($"Created sync group id: {created!.JobSyncGroupID}");

// List every group and its members.
var groups = await client.GetFromJsonAsync<JobSyncGroupSummary[]>("/api/job-sync-groups", jsonOptions);
foreach (var group in groups!)
    Console.WriteLine($"{group.JobSyncGroupId}: {group.GroupName} ({string.Join(", ", group.Members.Select(m => m.PeerName))})");

record CreateJobSyncGroupRequest(string GroupName, int[] MemberSyncPeerIds);
record CreatedGroupId(Guid JobSyncGroupID);
record SyncPeerRef(int SyncPeerId, string PeerName);
record JobSyncGroupSummary(Guid JobSyncGroupId, string GroupName, SyncPeerRef[] Members);

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 peer ids to include (from Manage Sync Peers).
$peerIds = @(3, 5)

# Step 3: Create the group. (-AllowUnencryptedAuthentication: PowerShell requires this for Windows auth over plain http to anything but localhost -- see "Network Access & Authentication Security".)
$newGroup = @{ GroupName = "Prod + DR"; MemberSyncPeerIds = $peerIds } | ConvertTo-Json
$created = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-sync-groups" `
    -Method Post -Body $newGroup -ContentType "application/json" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
"Created sync group id: $($created.jobSyncGroupID)"

# List every group and its members.
$groups = Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-sync-groups" -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers
$groups | ForEach-Object { "$($_.jobSyncGroupId): $($_.groupName) ($(($_.members | ForEach-Object { $_.peerName }) -join ', '))" }

# Delete it later.
Invoke-RestMethod -Uri "http://your-minion-agent-server:5443/api/job-sync-groups/$($created.jobSyncGroupID)" -Method Delete -UseDefaultCredentials -AllowUnencryptedAuthentication -Headers $headers

What you get back

POST -- 201 Created:

{ "jobSyncGroupID": "8f1b2c3d-4e5f-6789-a0b1-c2d3e4f56789" }

GET -- 200 OK, an array. Note it lists member peers, not member jobs -- which jobs use a group lives on the job side, see Get / Set a Job's Sync Config:

[
    { "jobSyncGroupId": "8f1b2c3d-4e5f-6789-a0b1-c2d3e4f56789", "groupName": "Prod + DR", "members": [ { "syncPeerId": 3, "peerName": "DR-SITE" } ] }
]

DELETE -- 204 No Content -- no body.

Codes this call can return

See API Response Codes for what each one means in general. For these calls:

  • 201 -- created.
  • 200 -- the list.
  • 204 -- deleted.
  • 403 -- you don't have Security.Manage.
  • 409 -- (delete) one or more jobs still use this group; move them to a different group first.

Deleting a group id that doesn't exist returns 204 rather than 404 -- it's a no-op delete, not an error.

What gets audited

Create is recorded as JobSyncGroup / Create Job Sync Group; delete as JobSyncGroup / Delete Job Sync Group. The list GET isn't audited. Add/remove a single member is a separate call -- see Manage Job Sync Group Membership.

See also: Manage Sync Peers, Manage Job Sync Group Membership, Get / Set a Job's Sync Config.