Skip to main content
Deno 2 is finally here šŸŽ‰ļø
Learn more

Jamf School API for Deno

An unofficial, idiomatic API wrapper for Jamf School. Itā€™s designed to feel natural for anyone with basic web development experience to pick it up, and to be safe enough to trust in production.

If something doesnā€™t work as expected or you just want some help, please raise an issue on GitHub so we can improve the library and documentation for everyone!

Currently, only a limited (mostly read-only) subset of API features are supported.

Hereā€™s the documentation for the latest release.

Features

  • Designed for modern JavaScript
  • A low-level API wrapper and a higher-level object-oriented interface
  • Data validation means you always get the data youā€™re promised
  • Comprehensive documentation and easy-to-follow example
  • Only requires --allow-net=YOUR_SCHOOL.jamfcloud.com

Usage

Hereā€™s how to get your API credentials. Youā€™ll have to replace the token, ID, and URL in the examples.

This example will print the name of each registered device.

device_names.ts
import * as jamf from "https://deno.land/x/jamf_school@0.3.2/mod.ts";

const client = jamf.createClient({
  id: "YOUR_NETWORK_ID",
  token: "YOUR_API_TOKEN",
  url: "https://YOUR_SCHOOL.jamfcloud.com/api",
});

// See the docs for everything clients can do.
const devices = await client.getDevices();

for (const device of devices) {
  console.log(device.udid, device.name);
}

Now run that script.

deno run --allow-net=YOUR_SCHOOL.jamfcloud.com device_names.ts
Show a more complex example

Restart all devices owned by anyone named ā€œRobertā€.

import * as jamf from "https://deno.land/x/jamf_school@0.3.2/mod.ts";

// The client can be instantiated with an API instead of credentials.
const api = jamf.createAPI({
  id: "YOUR_NETWORK_ID",
  token: "YOUR_API_TOKEN",
  url: "https://YOUR_SCHOOL.jamfcloud.com/api",
});

const client = jamf.createClient({ api });

// Using the API directly gives you control over exactly what requests
// are made. All the data returned is validated, of course.
const deviceData = await api.getDevices({ ownerName: "Robert" });

// If you have a client, objects can be created from API data directly.
const devices = deviceData.map((data) => client.createDevice(data));

// Everything is promise-based, so you can do things concurrently.
// Methods that perform actions (like restart) will reject on failure.
await Promise.allSettled(devices.map((device) => device.restart()));

Changelog

Each entry explains what changed and links to a pull request that has more details.

Version 0.3.2

  • Improve implementation of Device.enrollment ([#56])
    This should be marginally faster. The ā€œmanualā€ type now also includes a pending property (currently always false).
Older versions

Version 0.3.1

  • Add Device.enrollment (#53)
    Itā€™s an object instead of a string. See the docs for more information.

  • Add Client.getUserByName (#53)
    Returns null if there are no users with the name, fails if multiple users have it.

Version 0.3.0

  • Add support for apps (#15)
    This includes Client.getApps, Client.getAppsById, and Device.getApps. See the documentation for more information (the App interface).

  • Add support for locations (#40)
    Locations can get the data that belongs to them, and all objects can now get their location.

  • Specify the behaviour of toString and toJSON methods (#49)
    These methods can now be used reliably now that their behaviour is consistent and obvious.

Version 0.2.1

  • Suggest identifiers for APIGetDevicesOptions.modelIdentifier (#34)
    This uses the list curated in SeparateRecords/apple_device_identifiers to suggest strings, and still allows any string to be assigned to the property.

Version 0.2.0

  • Breaking: Changed how clients are instantiated with an API (#8)
    The API object must now be passed in as an api property on an object.

  • Added methods to set device ownership (#10, #16)
    API.assignDeviceOwner and Device.setOwner. The documentation contains examples.

  • Various schema improvements and corrections (#10, #20)
    More data is now included. To the best of my knowledge, the current schemas are complete.

  • Schemas donā€™t fail when additional properties are returned (#19)
    Release builds of schemas are now resilient against additional properties being added, but will still fail if any required properties are omitted.

  • Handle authentication errors with a better message (#24)
    Previously, authentication errors were lumped in with other errors, which made them confusing to read.

  • Changed how data is validated (#7)
    Technical change, but a good increase in real-world performance.

Version 0.1.0

  • Initial release
    Includes basic API support for devices, device groups, users, and user groups, as well as an object-oriented layer to simplify using the API.

License and Disclaimer

JAMF is a trademark beloning to JAMF Software, LLC. This projectā€™s development is not affiliated with JAMF Software, LLC.

There is a copy of the projectā€™s license (MIT) located in the root of the repository and in the module entrypoint (mod.ts).