-
Notifications
You must be signed in to change notification settings - Fork 4
Platform API Commands
Platform API commands operate on shared Jamf Platform services: blueprints, compliance benchmarks, DDM reports, and unified device management.
Most of them sit under jamf-cli pro and need platform gateway authentication (auth-method: platform). jamf-cli platform setup writes a gateway profile; see Setup Guide#Jamf Pro Quick Start: Platform Gateway (Recommended).
For shared CLI patterns (apply, scaffold, pagination, dry-run), see CLI Patterns.
The Platform API reached general availability on 2026-09-03. The base URL is
https://{region}.api.jamfcloud.com(no/apisegment), and the pre-GA{region}.apigw.jamf.comhost is retired: a profile still naming it is refused by name before any request is sent. Public-beta credentials stopped working at GA, so register a replacement API integration in Jamf Account. Platform API GA Migration carries the migration, the error messages verbatim and the refused-command list.
Scope: prefer
--environment-id. A Jamf Platform API integration is created at one of three levels, and a credential works with the level it was created at: organization (no ID, selected by the gateway host alone), platform environment (--environment-id/JAMF_ENVIRONMENT_ID, the level to prefer), and tenant (--tenant-id/JAMF_TENANT_ID, the legacy level: one Jamf Pro / School / Protect / Security Cloud tenant per profile). Supplying two at once is refused, in the environment as well as in a profile. The scope travels in anX-Environment-Id/X-Tenant-Idrequest header.
Three families live under
platform. Jamf AI Governance, Jamf Account (licensing, partners, SSO) and platform audit are scoped at the organization or environment level and name no Jamf Pro tenant, so they sit in a top-levelplatformnamespace. See Jamf Platform Commands.platform auditreads the platform event log;pro auditruns health checks against a Jamf Pro instance.
Platform commands are always visible in pro --help, and return an error with setup instructions when platform auth is not configured. Running one against an instance profile is refused with exit code 8, naming the profile, its resolved auth method and platform setup.
Identifiers: positional
<id>, names via--name. Unlike Protect and School (which take a positional<name>), Platform commands take the resource ID positionally and resolve names through a--nameflag. A name passed positionally goes to the API as an ID and 404s; passing both<id>and--nameis rejected. The exceptions areblueprints clone <source-name> <new-name>,compliance-benchmarks export <title>/clone <source-title> <new-title>, andplatform-device-groups add-members/remove-members <name>(all names positionally),platform-devices get/delete <id|serial>(either, auto-detected), andddm-reports device <deviceId>(ID only, no--name).applytakes no identifier on any resource: the input is the desired state and carries its own name (titleon a benchmark).
| Behaviour | Detail |
|---|---|
| Request bodies |
--from-file accepts JSON or YAML, and is optional: leave it off and the body is read from stdin, so --scaffold | edit | apply pipes end to end. An empty pipe is not a body (a CI runner hands every process one), and a named --from-file that is empty is an error. --set key=value (repeatable, dot notation for nested keys) overlays onto that body, or builds one on its own, and errors when a path segment already holds a non-object, leaving the body untouched: --set settings.banner.enabled=true over a body whose settings is a string answers cannot set nested key under non-object field "settings". Classic --set differs: it builds the whole body and cannot be combined with a file. --scaffold prints an example body and needs no auth. |
| Name lookup |
--name lists the collection and matches client-side, accumulating matches across every page before deciding. A name repeated either side of a 100-item page boundary is an ambiguity error, and a name matching an item the list returns no ID for is reported as that. |
| Output flags |
--out-file, --select, --compact, --quiet and --no-hints work on every command. --select and --compact narrow rows for every column format. |
| Enum fields |
--help lists the allowed values for every enum-constrained request field, one line per dotted path. A [] suffix on the path constrains each element of an array. --scaffold renders an enum as "", so --help is where the legal set lives. |
-n, --dry-run |
Honoured on every generated Platform write: it prints the method, the resolved path and the request body to stderr and returns. Name resolution runs first, so the preview reports the real path. The preview comes before any confirmation prompt, so -n on a destructive command works under --no-input without also pre-authorising the real thing. A hand-written platform write with no per-command preview is refused under -n: blueprints apply, compliance-benchmarks apply and platform-device-groups apply answer 412 [DRY_RUN] refused POST …: --dry-run is set and this command has no preview mode and exit 1, while blueprints delete, deploy and undeploy print a preview. |
| Empty lists | An empty collection prints [], never null, so | jq '.[]' is safe on a tenant with nothing in it: pro categories list --filter 'name=="zzz-no-such"' | jq -r '.[].name' prints nothing and exits 0. |
| Piped-body ceiling | A piped body is capped at 10MB. The generated commands and pro platform-device-groups patch / patch-members refuse one over the cap (stdin body exceeds 10MB; use --from-file for a larger payload). The hand-written readers truncate at the same ceiling without reporting it (blueprints apply, compliance-benchmarks apply, platform-device-groups apply, blueprints components configuration-profile and configuration-profile-plist), and a truncated YAML document still parses, so a long document loses its trailing fields and reports success. Verified 2026-09-11 on blueprints apply. Use --from-file for anything near the cap. |
A 403 |
Exits 5, and names the capability permission it wanted plus the section and permission name Jamf Account's Platform API integration picker shows for it, since that picker is searched by name and displays no slug. A 403 carrying OWNERSHIP_FORBIDDEN is a scope mismatch (an environment ID against a tenant-scoped credential, or the reverse) and says so, the grants being correct there. |
A missing grant looks like this, with the name Jamf Account's picker shows:
hint: grant the Jamf Platform API integration these permissions in Jamf Account:
Secure enterprise access > Content categories: Read (content-categories:read).
Names are as the permission picker shows them:
https://developer.jamf.com/platform-api/reference/jamf-pro-permissions-map
# What does this command need?
jamf-cli commands -o json \
| jq '.[] | select(.command=="pro blueprints create") | {api, privileges}'A gateway profile is optional. A JAMF_URL on the *.api.jamfcloud.com gateway host selects platform auth on its own (there is no auth-method environment variable), and the scope level is whichever ID variable you set, or none:
# platform environment (preferred)
JAMF_URL=https://eu.api.jamfcloud.com \
JAMF_ENVIRONMENT_ID=<uuid> JAMF_CLIENT_ID=<id> JAMF_CLIENT_SECRET=<secret> \
jamf-cli pro blueprints list
# tenant (legacy)
JAMF_URL=https://eu.api.jamfcloud.com \
JAMF_TENANT_ID=<uuid> JAMF_CLIENT_ID=<id> JAMF_CLIENT_SECRET=<secret> \
jamf-cli pro categories list
# organization: no ID at all, the gateway resolves it from the access token
JAMF_URL=https://us.api.jamfcloud.com \
JAMF_CLIENT_ID=<id> JAMF_CLIENT_SECRET=<secret> \
jamf-cli platform account-licenses listSupplying both IDs is a usage error (exit 2), and the message names the flags even when the pair came from the environment:
--environment-id and --tenant-id are mutually exclusive: an API integration is created at
one level, and its credential only works with that level's header
config add-profile refuses the same pair at profile-creation time, naming the three levels:
--environment-id and --tenant-id are mutually exclusive: an API integration is created at
one level (organization, platform environment, or tenant) and its credential only works
with that level's header
The CLI cannot catch the wrong level before sending, a gateway token being opaque and carrying no scope, so the gateway's answer is the only signal. Reaching an environment-only surface with an organization or tenant credential answers 400 [INVALID_REQUEST_CONTEXT_TYPE] Request context type 'tenant' is invalid. Expected any of 'environment'. and exits 1. (The gateway calls an organization credential's context 'tenant'; confusing, and that is what it prints.)
| Command | Alias |
|---|---|
blueprints |
bp |
compliance-benchmarks |
cb |
platform-devices |
pdev |
platform-device-groups |
pdg |
ddm-reports |
ddm |
Manage deployment blueprints: define configurations and deploy them to device groups.
# List all blueprints
jamf-cli pro blueprints list
jamf-cli pro blueprints list --sort name:asc --search "staging"
# Get a blueprint by UUID, or by name with --name
jamf-cli pro blueprints get 0f0e6b0c-1f2a-4c3d-9e8f-7a6b5c4d3e2f
jamf-cli pro blueprints get --name "macOS Standard"
# Create or update a blueprint
jamf-cli pro blueprints apply --from-file blueprint.json --yes
# Print a JSON scaffold template
jamf-cli pro blueprints apply --scaffold
# Export a blueprint (round-trippable to apply)
jamf-cli pro blueprints export --name "macOS Standard" -o yaml > blueprint.yaml
# Clone a blueprint (the one command that takes names positionally)
jamf-cli pro blueprints clone "macOS Standard" "macOS Standard - Test"
# Deploy / undeploy
jamf-cli pro blueprints deploy --name "macOS Standard"
jamf-cli pro blueprints undeploy --name "macOS Standard"
# Get deployment status report
jamf-cli pro blueprints report --name "macOS Standard"
# Delete a blueprint
jamf-cli pro blueprints delete --name "macOS Standard" --yesOnly a v1.31.1 YAML export round-trips. Earlier releases rendered each component's
configurationas a sequence of integer bytes and lower-cased its keys, whichapplycannot read back.-o jsonwas correct throughout.applyrefuses the older file rather than sending it:component com.jamf.ddm.passcode-settings: configuration is not an object A YAML export written by jamf-cli 1.31.0 or earlier rendered it as a byte sequence. Re-export the blueprint with this version and apply that fileRe-export any YAML blueprint you have kept. A stored JSON export is unaffected.
blueprints scope is a Platform API command and shares nothing with the Classic scope subcommands on policies and configuration profiles: it scopes a blueprint to device groups only, and it was not changed by v1.30.0. The Classic ones moved to a positional <id> with --name as the alternative in that release. See Jamf Pro Commands.
# List device groups in a blueprint's scope (positional UUID, or --name)
jamf-cli pro blueprints scope list 0f0e6b0c-1f2a-4c3d-9e8f-7a6b5c4d3e2f
jamf-cli pro blueprints scope list --name "macOS Standard"
# Add device groups to scope (--computer-group / --mobile-device-group by name, or --group-id by UUID; all repeatable)
jamf-cli pro blueprints scope add --name "macOS Standard" --computer-group "All Macs"
# Remove device groups from scope
jamf-cli pro blueprints scope remove --name "macOS Standard" --computer-group "Test Devices"Blueprint components are the DDM declarations that make up a blueprint step. Each component has a unique identifier (e.g. com.jamf.ddm.passcode-settings).
# List all available components
jamf-cli pro blueprints components list
# Get a component's current API definition by identifier
jamf-cli pro blueprints components get "com.jamf.ddm.passcode-settings"
# Print a ready-to-use JSON scaffold for a component (no auth required)
# Accepts full identifiers or short names
jamf-cli pro blueprints components scaffold passcode-settings
jamf-cli pro blueprints components scaffold com.jamf.ddm.software-update-settings
# Convert a .mobileconfig file to a configuration-profile component
jamf-cli pro blueprints components configuration-profile --from-file profile.mobileconfig
# Download an existing profile from Jamf Pro and convert it, by Classic ID or by name
jamf-cli pro blueprints components configuration-profile --id 42
jamf-cli pro blueprints components configuration-profile --name "My Restrictions"
jamf-cli pro blueprints components configuration-profile --name "Managed Restrictions" --type mobile
# Strip Apple default values before converting (reduces noise from UI-generated profiles)
jamf-cli pro blueprints components configuration-profile --from-file profile.mobileconfig --strip-defaults
# Convert a raw preference domain plist to a configuration-profile component
jamf-cli pro blueprints components configuration-profile-plist \
--from-file com.apple.dock.plist --payload-type com.apple.dockimport-profile downloads a Classic API configuration profile from Jamf Pro, converts compatible payloads to native DDM components, and creates a blueprint. Conversion is the default; --legacy skips it.
# Import a macOS config profile (DDM conversion happens without a flag)
jamf-cli pro blueprints import-profile "Passcode Policy"
# Import a mobile device config profile
jamf-cli pro blueprints import-profile "Managed Restrictions" --type mobile
# Override the blueprint name
jamf-cli pro blueprints import-profile "FileVault Settings" --blueprint-name "FV Blueprint"
# Strip Apple defaults from payloads (useful for profiles with many UI-set keys)
jamf-cli pro blueprints import-profile "My Restrictions" --strip-defaults
# Skip DDM conversion: wrap everything in a single configuration-profile component
jamf-cli pro blueprints import-profile "My Restrictions" --legacy
# Set (or override) the blueprint scope. Blueprints require at least one device group (repeatable)
jamf-cli pro blueprints import-profile "Software Update" --computer-group "All Managed Macs"
jamf-cli pro blueprints import-profile "Managed Restrictions" --type mobile --mobile-device-group "Student iPads"
# Send payloads that blueprints hard-disables anyway (the API will reject them)
jamf-cli pro blueprints import-profile "My Restrictions" --include-unsupported
# Identify the profile by its Classic API ID instead of its display name
jamf-cli pro blueprints import-profile 42
jamf-cli pro blueprints import-profile --name "Passcode Policy"Identifying the profile. Jamf Pro allows duplicate profile display names, so
import-profilealso takes a Classic API ID. It reads the positional argument as an ID when every character is a digit and as a display name otherwise, so a profile whose display name is all digits (e.g."2024") must be looked up with--name. A name matching more than one profile prompts you to pick; under--no-inputthe command errors and lists the matching IDs.components configuration-profiletakes an--idflag for the same job.
Scope override and the empty-scope guard.
--computer-group/--mobile-device-group(both repeatable) set the blueprint scope, overriding the profile's own. Blueprints require at least one device group, so a profile whose scope resolves to no groups (all computers, individual devices, buildings, or departments) fails with an error naming the problem, and one of these flags fixes it.
Disabled payload types are skipped. Blueprints hard-disables a fixed set (certificates, VPN, SSO, web clips, fonts, and others), and those are dropped with a warning.
--include-unsupportedsends them anyway, and the API rejects them.
Supported DDM conversions (applied whenever import-profile finds the payload):
| Legacy Payload | DDM Component |
|---|---|
com.apple.mobiledevice.passwordpolicy |
com.jamf.ddm.passcode-settings |
com.apple.applicationaccess (safari keys) |
com.jamf.ddm.safari-settings |
com.apple.applicationaccess (deferral keys) |
com.jamf.ddm.software-update-settings |
com.apple.applicationaccess (RSR keys) |
com.jamf.ddm.software-update-settings |
com.apple.SoftwareUpdate |
com.jamf.ddm.software-update-settings |
Payloads with no DDM mapping are wrapped in a com.jamf.ddm-configuration-profile component. Some of these "Legacy payload" components can only be managed through the blueprints API and appear read-only in the Jamf Pro UI. import-profile carries the scope over, target device groups only: individual computers, buildings, departments, limitations and exclusions cannot be imported to blueprints.
The com.jamf.ddm-configuration-profile component takes a fixed registry of payloadType values standalone, and the API reference overstates it. A type outside that registry earns a message naming the whole component, with no payload, key or reason:
{"httpStatus":400,"errors":[{"code":"VALIDATION_FAILURE",
"field":"steps[0].components[2].configuration",
"description":"Failed to validate configuration."}]}Wire-probing every payload type Apple publishes, plus Jamf Pro's own spellings, found 74 accepted standalone, 22 disabled, and 40 unknown to the registry, well-documented ones included: com.apple.MCX, com.apple.Safari, com.apple.SoftwareUpdate, com.apple.Terminal, com.apple.TimeMachine, com.apple.systemuiserver, com.apple.mail.managed, .GlobalPreferences. Apple publishing a schema says nothing about what the registry knows.
import-profile and components configuration-profile model that:
-
An out-of-registry type is wrapped.
import-profiledelivers a payload whose type the registry does not know ascom.apple.ManagedClient.preferences(Application & Custom Settings), which the API accepts for every domain probed, third-party ones likecom.microsoft.Wordincluded, and which is the correct legacy delivery for those domains. No settings are lost. -
Jamf Pro's non-canonical spelling is rewritten. Jamf Pro writes its User Preferences payload as
com.apple.preferences.users(Apple's filename), and the registry knowscom.apple.preference.users. One character fails a whole profile. -
MCX unwrapping is offline and narrow.
import-profileunwraps an Application & Custom Settings payload to a standalone payload when a DDM converter will consume its inner domain, or the registry accepts that domain. Classification needs no network call.--legacykeeps MCX intact.
Note: A type missing from the registry is benign:
import-profileMCX-wraps it and delivers it. Guessing one in is not, so the CLI's list stays conservative.
Manage mSCP (macOS Security Compliance Project) compliance benchmarks. compliance-benchmarks handles benchmark CRUD (create/apply, get, list, clone, delete, export). Baseline and rule reference data live under baselines/rules; compliance monitoring lives under benchmark-reports.
# List available mSCP baselines (the starting point for new benchmarks)
jamf-cli pro baselines list
# List all benchmarks
jamf-cli pro compliance-benchmarks list
# Get a benchmark by ID, or by title with --name
jamf-cli pro compliance-benchmarks get <benchmark-id>
jamf-cli pro compliance-benchmarks get --name "CIS macOS 15"
# Create a benchmark from a portable JSON/YAML file (group names, not IDs)
jamf-cli pro compliance-benchmarks apply --from-file benchmark.json
jamf-cli pro compliance-benchmarks apply --from-file benchmark.yaml
# Print a JSON scaffold template for the input format
jamf-cli pro compliance-benchmarks apply --scaffold
# Generate a scaffold pre-populated with all rules from a specific baseline
# (pass the baseline ID from 'baselines' list)
jamf-cli pro compliance-benchmarks apply --scaffold-from-baseline "<baseline-id>"
# Export a benchmark as portable JSON/YAML (group IDs replaced with names).
# export and clone take titles positionally
jamf-cli pro compliance-benchmarks export "CIS macOS 15"
jamf-cli pro compliance-benchmarks export "CIS macOS 15" -o yaml > benchmark.yaml
# Clone a benchmark with a new title
jamf-cli pro compliance-benchmarks clone "CIS macOS 15" "CIS macOS 15 - Staging"
# Clone and override target device groups
jamf-cli pro compliance-benchmarks clone "CIS macOS 15" "CIS macOS 15 - Test" \
--computer-group "Test Devices"
# Delete a benchmark (positional ID, or --name for the title)
jamf-cli pro compliance-benchmarks delete --name "CIS macOS 15" --yesNote: Benchmarks cannot be updated after creation, so
applyis create-only. To modify one, export it, delete the old one, edit the exported file, and re-apply. Usecloneto copy an existing benchmark under a new title.exportproduces a portable format with names in place of device group IDs, so its output is safe to apply to a different instance.
A benchmark definition can pin the OS versions it applies to with a selectedOsVersions list. Each entry has an osType and osVersion. It appears in apply --scaffold output, and export/clone preserve it:
{
"title": "My Benchmark",
"sourceBaselineId": "<baseline-id>",
"rules": [ { "enabled": true, "id": "<rule-id>" } ],
"selectedOsVersions": [
{ "osType": "MAC_OS", "osVersion": 26 }
],
"target": {
"deviceGroups": [
{ "name": "<device-group-name>", "deviceType": "COMPUTER", "groupType": "SMART" }
]
},
"enforcementMode": "MONITOR"
}The mSCP baselines and their rules are read-only reference data, exposed as their own resources and not as subcommands of compliance-benchmarks. Use a baseline ID when scaffolding a benchmark with compliance-benchmarks apply --scaffold-from-baseline.
# List available mSCP baselines
jamf-cli pro baselines list
# List all mSCP rules
jamf-cli pro rules list
# List the rules provided by a specific baseline
jamf-cli pro rules list --baseline-id <baseline-id>Baseline IDs are slugs (cis_lvl1), so --baseline-id 1 is a 404.
Compliance reporting for existing benchmarks. Each subcommand takes a benchmark ID (from compliance-benchmarks list) positionally, or a benchmark title via --name, resolved against compliance-benchmarks.
# Per-rule compliance stats for a benchmark (passed / failed / unknown counts)
jamf-cli pro benchmark-reports rules <benchmark-id>
jamf-cli pro benchmark-reports rules --name "CIS macOS 15"
jamf-cli pro benchmark-reports rules <benchmark-id> --rule-search "firewall" --sort passed:desc
# Devices for a benchmark, optionally filtered to a single rule
jamf-cli pro benchmark-reports devices <benchmark-id>
jamf-cli pro benchmark-reports devices --name "CIS macOS 15" --rule-id <rule-id> --sort deviceName:asc
# Overall compliance percentage for a benchmark
jamf-cli pro benchmark-reports compliance-percentage <benchmark-id>
jamf-cli pro benchmark-reports compliance-percentage --name "CIS macOS 15"Unified device inventory and management through the Platform API. Identify a device by UUID or serial number; the CLI works out which you passed (UUIDs contain hyphens, serials do not).
# List all devices
jamf-cli pro platform-devices list
jamf-cli pro platform-devices list --sort name:asc --filter "osType==MACOS"
# Get a device by serial number or UUID
jamf-cli pro platform-devices get C02X1234
jamf-cli pro platform-devices get "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Update device attributes
jamf-cli pro platform-devices update C02X1234 --from-file device-update.json
# Delete a device (destructive)
jamf-cli pro platform-devices delete C02X1234 --yes
# List installed applications
jamf-cli pro platform-devices applications C02X1234
# List group memberships
jamf-cli pro platform-devices groups C02X1234
# List devices for a user
jamf-cli pro platform-devices user user-id-here
# Request a device check-in (non-destructive)
jamf-cli pro platform-devices check-in C02X1234
# Device actions (destructive, require --yes)
jamf-cli pro platform-devices erase C02X1234 --yes
jamf-cli pro platform-devices restart C02X1234 --yes
jamf-cli pro platform-devices shutdown C02X1234 --yes
jamf-cli pro platform-devices unmanage C02X1234 --yesManage device groups through the Platform API. Static groups support member management; filter criteria define smart groups.
# List all device groups
jamf-cli pro platform-device-groups list
jamf-cli pro platform-device-groups list --sort name:asc
# Get a device group by ID, or by name with --name
jamf-cli pro platform-device-groups get <group-id>
jamf-cli pro platform-device-groups get --name "All macOS Devices"
# Create or update a device group
jamf-cli pro platform-device-groups apply --from-file group.json --yes
# Print a JSON scaffold template
jamf-cli pro platform-device-groups apply --scaffold
# Export a group as YAML (round-trippable to apply)
jamf-cli pro platform-device-groups get --name "All macOS Devices" -o yaml
# Delete a device group
jamf-cli pro platform-device-groups delete --name "Test Group" --yes
# List group members (positional <id>, or --name)
jamf-cli pro platform-device-groups members --name "All macOS Devices"
# Add/remove members from a static group. These two take the group NAME
# positionally; --id is the repeatable device ID
jamf-cli pro platform-device-groups add-members "Manual Group" --id <device-id-1> --id <device-id-2>
jamf-cli pro platform-device-groups remove-members "Manual Group" --id <device-id-1>
# Disambiguate by device type when a computer group and a mobile device group share a name
jamf-cli pro platform-device-groups get --name "Engineering" --device-type COMPUTER
jamf-cli pro platform-device-groups get --name "Engineering" --device-type MOBILE
--device-type: a computer group and a mobile device group can carry the same name, which makes a bare name lookup ambiguous. Pass--device-type COMPUTERor--device-type MOBILEto narrow it. The flag is on the subcommands that resolve a group by name:get,delete,members,add-members,remove-members,patch, andpatch-members.Identifier shapes differ within this group:
get,delete,members,patch, andpatch-memberstake a positional<id>with--namefor lookup;add-membersandremove-memberstake the group<name>positionally.
Declarative Device Management reporting: check declaration deployment status across your fleet.
# The declaration report for one device (by device ID). --filter is required
jamf-cli pro ddm-reports device declarations <device-id> --filter 'active==true'
# Devices reporting a specific declaration. --filter is required
jamf-cli pro ddm-reports declaration devices "com.apple.configuration.passcode" --filter 'active==true' --sort declarationType,asc
# Everything, with the tautology that stands in for an unfiltered read
jamf-cli pro ddm-reports declaration devices "com.apple.configuration.passcode" \
--filter 'active=in=(true,false)'
# Page through a large report (--page is 0-based; --size sets the page size)
jamf-cli pro ddm-reports device declarations <device-id> \
--filter 'active=in=(true,false)' --page 1 --size 200
# Devices with failed/invalid declarations, and their error reasons
jamf-cli pro ddm-reports errors "com.apple.configuration.passcode"Removed:
ddm-reports declaration getandddm-reports device get. The declaration-reporting API deprecated both endpoints in favour of a sibling on the same resource. Rewrite:
Was Now pro ddm-reports declaration get <id>pro ddm-reports declaration devices <id> --filter …pro ddm-reports device get <id>pro ddm-reports device declarations <id> --filter …The successors declare
filterrequired where the removed pair did not, so use--filter 'active=in=(true,false)'where you want everything. Both successors also take--page. The same two removals apply toschool ddm-reports. The old names are gone from cobra:pro ddm-reports declaration get Xexits 2 as a usage error, so a script still calling one fails with a usage error.
Paging and sorting differ from the platform lists.
--pageis zero-based and--sizesets the page size (not--page-size), and--sorttakes the comma formproperty,asc/property,desc, while every other Platform list usesproperty:asc.
--filteris required ondevice declarationsanddeclaration devices: the API has no "return everything" mode for these reports, so cobra refuses the call before anything is sent, withrequired flag(s) "filter" not setand exit code 2. Filters use RSQL and apply to declarations already on the device (the report excludes PENDING declarations). Allowed fields:
device declarations:declarationIdentifier,active,validityState,declarationType,dateUpdated,channeldeclaration devices:deviceId,channel,lastReportTime,active,validityState,declarationType,dateUpdatedFor example,
--filter 'validityState=="INVALID"'returns the failing declarations. Theerrorssubcommand takes no--filter, since it already scopes to failed and invalid declarations.
Report commands that aggregate Platform API data. These nest under pro report alongside the existing Pro reports.
# Blueprint deployment status across all blueprints
jamf-cli pro report blueprint-status
# Per-rule compliance stats for a benchmark
jamf-cli pro report compliance-rules "CIS macOS 15"
# Non-compliant devices for a benchmark
jamf-cli pro report compliance-devices "CIS macOS 15"
# DDM declaration health across all devices
jamf-cli pro report ddm-statusPrint a valid Jamf Platform Gateway access token. The CLI refreshes the token when it has expired.
# Print token as JSON (includes expiry)
jamf-cli platform auth token
# Extract the token string for scripting
jamf-cli platform auth token --field token
# Force a fresh token exchange (ignores cache)
jamf-cli platform auth token --refreshOutput:
{
"token": "eyJhbGciOi...",
"expires_at": "2026-04-15T15:30:00Z"
}| Flag | Description |
|---|---|
--refresh |
Force a new token exchange, ignoring any cached token |
With platform gateway auth active, pro audit includes platform-specific checks:
# Run all audit checks (platform included when configured)
jamf-cli pro audit
# Run only platform checks
jamf-cli pro audit --checks platformPlatform checks cover: undeployed blueprints, deployment failures, stale blueprints, benchmark updates needed, monitor-only benchmarks, empty platform scope, and failed DDM declarations.
Repository · Issues · Releases
jamf-cli Wiki
- Home
- Community
- Getting Started
- CLI Reference
- Product Commands
- Workflows
- Configuration
- Reference
Products
- Jamf Pro:
jamf-cli pro - Jamf Platform API:
jamf-cli pro(blueprints, benchmarks, DDM reports) - Jamf Platform:
jamf-cli platform(AI Governance, Jamf Account, audit) - Jamf Protect:
jamf-cli protect - Jamf School:
jamf-cli school - Jamf Security Cloud:
jamf-cli security