Patching

Pending updates; patch jobs (security only, everything, chosen packages, or apps); patch policies that run on a schedule within a maintenance window; approvals for policies that need them; removing a package; OS release upgrades; and Windows Update profiles (categories, feature upgrades).

MethodPathSummary
GET/api/updatesPending updates across devices
POST/api/approvalsApprove or reject updates waiting for approval
GET/api/jobsList patch jobs
GET/api/jobs/:idGet a patch job with per-device results
POST/api/jobsStart a patch job
POST/api/patch/bulkPatch everything that needs it
POST/api/jobs/:id/cancelCancel a patch job
GET/api/policiesList patch policies
POST/api/policiesCreate a patch policy
PUT/api/policies/:idUpdate a patch policy
DELETE/api/policies/:idDelete a patch policy
POST/api/policies/:id/runRun a patch policy now
POST/api/removalsPlan removing a package
GET/api/removalsList package removals
POST/api/removals/:id/confirmConfirm a package removal
POST/api/removals/:id/cancelCancel a package removal
POST/api/os-upgradesPlan an OS release upgrade
GET/api/os-upgradesList OS upgrades
POST/api/os-upgrades/:id/confirmConfirm an OS upgrade
GET/api/os-upgrades/:id/outputWhat the device printed, plus its release upgrade logs once fetched
POST/api/os-upgrades/:id/logsFetch an upgrade's logs from the device
POST/api/os-upgrades/:id/cancelCancel an OS upgrade
GET/api/wuWindows Update profiles
POST/api/wu/profilesCreate a Windows Update profile
PUT/api/wu/profiles/:idUpdate a Windows Update profile
DELETE/api/wu/profiles/:idDelete a Windows Update profile

#Pending updates across devices

GET/api/updates
Address
https://<your-org>.brambleit.cloud/warden/api/updates
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Response 200

FieldTypeDescription
updatesarray of object
updates[].packagestring
updates[].titlestring, or null
updates[].candidate_versionstring, or null
updates[].devicesinteger
updates[].is_securityboolean
updates[].fixes_findingsnumber
updates[].severitystring, or null
updates[].originsstring
updates[].kindstring
updates[].categorystring, or null
updates[].approvalany
approvalsarray of any
Example response
JSON
{
  "updates": [
    {
      "package": "string",
      "title": "Example title",
      "candidate_version": "string",
      "devices": 1,
      "is_security": true,
      "fixes_findings": 12.5,
      "severity": "string",
      "origins": "string",
      "kind": "string",
      "category": "string",
      "approval": null
    }
  ],
  "approvals": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/updates', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Approve or reject updates waiting for approval

POST/api/approvals
Address
https://<your-org>.brambleit.cloud/warden/api/approvals
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
itemsarray of any

Response 200

FieldTypeDescription
updatedinteger
Example response
JSON
{
  "updated": 1
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/approvals', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"items":[]}),
});
const data = await res.json();

#List patch jobs

GET/api/jobs
Address
https://<your-org>.brambleit.cloud/warden/api/jobs
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Response 200

FieldTypeDescription
jobsarray of any
Example response
JSON
{
  "jobs": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/jobs', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Get a patch job with per-device results

GET/api/jobs/:id
Address
https://<your-org>.brambleit.cloud/warden/api/jobs/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

FieldTypeDescription
jobany
devicesarray of object
devices[].nameinteger
devices[].onlineboolean
devices[].packagesarray of any
devices[].resultany
devices[].result_jsonany
Example response
JSON
{
  "job": null,
  "devices": [
    {
      "…r": "…",
      "name": 1,
      "online": false,
      "packages": [],
      "result": null,
      "result_json": null
    }
  ]
}

Errors

StatusMessage
404Job not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/jobs/42', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Start a patch job

POST/api/jobs
Address
https://<your-org>.brambleit.cloud/warden/api/jobs
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
update_classstring: "security" | "all" | "selected" | "apps"security (security updates only), all, selected (just packages) or apps.
reboot_policystring: "never" | "if_required" | "always"never, if_required or always.
device_idsarray of anyDevices to patch.
packagesarray of anyPackage names, with update_class: selected.
namestringA name for the job.
include_appsbooleanAlso update applications.

Response 201

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/jobs', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"update_class":"security","reboot_policy":"never","device_ids":[],"packages":[],"name":"Example name","include_apps":false}),
});
const data = await res.json();

#Patch everything that needs it

POST/api/patch/bulk

Fixes chosen vulnerable packages and updates on every in-scope device that needs them. dry_run shows what would happen.

Address
https://<your-org>.brambleit.cloud/warden/api/patch/bulk
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
vuln_packagesarray of any
update_packagesarray of any
dry_runany
reboot_policystring: "never" | "if_required" | "always"

Response 200

FieldTypeDescription
devicesarray of object
devices[].device_idinteger
devices[].nameinteger
devices[].onlineboolean
devices[].packagesarray of any
packagesarray of any
Example response
JSON
{
  "devices": [
    {
      "device_id": 7,
      "name": 1,
      "online": false,
      "packages": []
    }
  ],
  "packages": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/patch/bulk', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"vuln_packages":[],"update_packages":[],"dry_run":"…","reboot_policy":"never"}),
});
const data = await res.json();

#Cancel a patch job

POST/api/jobs/:id/cancel
Address
https://<your-org>.brambleit.cloud/warden/api/jobs/:id/cancel
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

FieldTypeDescription
messagestring
Example response
JSON
{
  "message": "Saved"
}

Errors

StatusMessage
409Job is not running

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/jobs/42/cancel', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#List patch policies

GET/api/policies
Address
https://<your-org>.brambleit.cloud/warden/api/policies
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Response 200

FieldTypeDescription
policiesarray of object
policies[].scope_idsarray of any
policies[].open_nowboolean
Example response
JSON
{
  "policies": [
    {
      "…p": "…",
      "scope_ids": [],
      "open_now": false
    }
  ]
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/policies', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Create a patch policy

POST/api/policies
Address
https://<your-org>.brambleit.cloud/warden/api/policies
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
schedule_daysarray of anyDays of the week to run.
window_startanyWhen the maintenance window opens, HH:MM.
timezoneanyThe window's time zone, e.g. Europe/London.
namestringThe policy's name.
enabledbooleanWhether it runs.
scope_typestring: "all" | "site" | "group" | "device"all, site, group or device.
scope_idsarray of anyThe sites, groups or devices (unless all).
update_classstring: "all" | "apps"all (OS updates) or apps.
include_appsarray of anyAlso update applications.
windows_categoriesarray of anyWindows Update categories to include.
approval_modestringWhether updates need approving first.
window_minutesintegerHow long the window lasts.
reboot_policystring: "never" | "if_required" | "always"never, if_required or always.
exclude_packagesarray of anyPackages never to update.
pre_script_idnumberAn RMM script to run before patching.
post_script_idnumberAn RMM script to run after patching.

Response 201

FieldTypeDescription
idinteger
Example response
JSON
{
  "id": 42
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/policies', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"schedule_days":[],"window_start":"…","timezone":"…","name":"Example name","enabled":true,"scope_type":"all","scope_ids":[],"update_class":"all","include_apps":[],"windows_categories":[],"approval_mode":"string","window_minutes":1,"reboot_policy":"never","exclude_packages":[],"pre_script_id":12.5,"post_script_id":12.5}),
});
const data = await res.json();

#Update a patch policy

PUT/api/policies/:id
Address
https://<your-org>.brambleit.cloud/warden/api/policies/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Request body JSON

NameTypeDescription
schedule_daysarray of any
window_startany
timezoneany
namestring
enabledboolean
scope_typestring: "all" | "site" | "group" | "device"
scope_idsarray of any
update_classstring: "all" | "apps"
include_appsarray of any
windows_categoriesarray of any
approval_modestring
window_minutesinteger
reboot_policystring: "never" | "if_required" | "always"
exclude_packagesarray of any
pre_script_idnumber
post_script_idnumber

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Errors

StatusMessage
404Policy not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/policies/42', {
  method: 'PUT',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"schedule_days":[],"window_start":"…","timezone":"…","name":"Example name","enabled":true,"scope_type":"all","scope_ids":[],"update_class":"all","include_apps":[],"windows_categories":[],"approval_mode":"string","window_minutes":1,"reboot_policy":"never","exclude_packages":[],"pre_script_id":12.5,"post_script_id":12.5}),
});
const data = await res.json();

#Delete a patch policy

DELETE/api/policies/:id
Address
https://<your-org>.brambleit.cloud/warden/api/policies/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Errors

StatusMessage
404Policy not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/policies/42', {
  method: 'DELETE',
  credentials: 'include',
});
const data = await res.json();

#Run a patch policy now

POST/api/policies/:id/run
Address
https://<your-org>.brambleit.cloud/warden/api/policies/:id/run
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Response 201

Errors

StatusMessage
404Policy not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/policies/42/run', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#Plan removing a package

POST/api/removals

Works out what removing a package would also remove, for you to confirm.

Address
https://<your-org>.brambleit.cloud/warden/api/removals
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
packageanyThe package.
device_idsarray of anyThe devices.
device_idinteger

Response 201

FieldTypeDescription
resultsarray of any
Example response
JSON
{
  "results": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/removals', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"package":"…","device_ids":[],"device_id":7}),
});
const data = await res.json();

#List package removals

GET/api/removals
Address
https://<your-org>.brambleit.cloud/warden/api/removals
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Query parameters

NameTypeDescription
idsstring
device_idstring
packagestring

Response 200

FieldTypeDescription
removalsarray of any
Example response
JSON
{
  "removals": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/removals', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Confirm a package removal

POST/api/removals/:id/confirm
Address
https://<your-org>.brambleit.cloud/warden/api/removals/:id/confirm
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Request body JSON

NameTypeDescription
accept_extraanyAlso remove the other packages that depend on it.

Response 200

FieldTypeDescription
messagestring
Example response
JSON
{
  "message": "Saved"
}

Errors

StatusMessage
404Removal not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/removals/12.5/confirm', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"accept_extra":"…"}),
});
const data = await res.json();

#Cancel a package removal

POST/api/removals/:id/cancel
Address
https://<your-org>.brambleit.cloud/warden/api/removals/:id/cancel
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Response 200

FieldTypeDescription
messagestring
Example response
JSON
{
  "message": "Saved"
}

Errors

StatusMessage
409This removal can no longer be cancelled

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/removals/12.5/cancel', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#Plan an OS release upgrade

POST/api/os-upgrades
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Request body JSON

NameTypeDescription
device_idintegerThe device.

Response 201

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"device_id":7}),
});
const data = await res.json();

#List OS upgrades

GET/api/os-upgrades
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Query parameters

NameTypeDescription
idsstring
device_idstring

Response 200

FieldTypeDescription
upgradesarray of any
Example response
JSON
{
  "upgrades": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Confirm an OS upgrade

POST/api/os-upgrades/:id/confirm
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades/:id/confirm
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Request body JSON

NameTypeDescription
confirm_namestringThe device's name, typed to confirm.
rebootanyReboot when done.

Response 200

FieldTypeDescription
messagestring
Example response
JSON
{
  "message": "Saved"
}

Errors

StatusMessage
404Upgrade not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades/12.5/confirm', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"confirm_name":"Example confirm name","reboot":"…"}),
});
const data = await res.json();

#What the device printed, plus its release upgrade logs once fetched

GET/api/os-upgrades/:id/output
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades/:id/output
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

FieldTypeDescription
outputstring
device_logstring
log_fetched_atstring (date-time)
log_statestring
Example response
JSON
{
  "output": "string",
  "device_log": "string",
  "log_fetched_at": "2026-11-12T09:30:00.000Z",
  "log_state": "string"
}

Errors

StatusMessage
404Upgrade not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades/42/output', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Fetch an upgrade's logs from the device

POST/api/os-upgrades/:id/logs
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades/:id/logs
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Response 200

Errors

StatusMessage
404Upgrade not found

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades/12.5/logs', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#Cancel an OS upgrade

POST/api/os-upgrades/:id/cancel
Address
https://<your-org>.brambleit.cloud/warden/api/os-upgrades/:id/cancel
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Response 200

FieldTypeDescription
messagestring
Example response
JSON
{
  "message": "Saved"
}

Errors

StatusMessage
409This upgrade can no longer be cancelled

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/os-upgrades/12.5/cancel', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#Windows Update profiles

GET/api/wu
Address
https://<your-org>.brambleit.cloud/warden/api/wu
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Response 200

FieldTypeDescription
profilesarray of any
devicesarray of any
targetsarray of any
Example response
JSON
{
  "profiles": [],
  "devices": [],
  "targets": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/wu', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Create a Windows Update profile

POST/api/wu/profiles
Address
https://<your-org>.brambleit.cloud/warden/api/wu/profiles
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Response 201

FieldTypeDescription
idinteger
Example response
JSON
{
  "id": 42
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/wu/profiles', {
  method: 'POST',
  credentials: 'include',
});
const data = await res.json();

#Update a Windows Update profile

PUT/api/wu/profiles/:id
Address
https://<your-org>.brambleit.cloud/warden/api/wu/profiles/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Response 200

FieldTypeDescription
idinteger
Example response
JSON
{
  "id": 42
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/wu/profiles/12.5', {
  method: 'PUT',
  credentials: 'include',
});
const data = await res.json();

#Delete a Windows Update profile

DELETE/api/wu/profiles/:id
Address
https://<your-org>.brambleit.cloud/warden/api/wu/profiles/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: Warden.

Path parameters

NameTypeDescription
idrequirednumber

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/warden/api/wu/profiles/12.5', {
  method: 'DELETE',
  credentials: 'include',
});
const data = await res.json();