Device Lifecycle API

Introduction

The Device Lifecycle API provides you with an Application Program Interface (API) to request permanent device deletion of your enrolled managed devices. Main purpose of this API is to allow automation of device lifecycle management and provide an alternative to manual device lifecycle management in Radar portal UI.

The API is RESTful and HTTP-based. This means that the communication is made through normal HTTP requests.

If at any point you require any further assistance, please reach out to your Jamf support representative.

Getting Started

  1. From RADAR portal generate an API key and get your Application ID and Secret. Get your customer ID from RADAR URL address parameter customerId.
  2. Authenticate with the following terminal command replacing <Application ID> and <Application Secret> with the ones retrieved on the previous step:
    curl -X POST -u '<Application ID>:<Application Secret>' <https://api.wandera.com/v1/login>
    
  3. Copy the JWT value from the token field in the response without double quotations.
  4. Request permanent device deletion by running a command in terminal replacing <JWT> placeholder by value obtained in previous step. Replace <CUSTOMER_ID> with customer ID obtained in step 1 and finally, replace <EXTERNAL_ID> with externalId identifier (or comma-separated double-quoted identifiers) of a device or devices you wish to delete.
    curl -X POST -H 'Content-Type: application/json; charset=utf-8' \
    -H 'Authorization: Bearer <JWT>' \
    -d '{"externalIds": ["<EXTERNAL_ID>"]}' \
    https://api.wandera.com/device-lifecycle/v1/<CUSTOMER_ID>/devices/purge/async/external
    

Authentication

Authentication is needed in order to use the Device Lifecycle API

The authentication used is in the form of a JSON Web Token (JWT). Each request to the API needs to contain a Bearer type Authorization header containing a valid JWT. A JWT can be obtained by calling the /v1/login endpoint via POST request using a valid Application ID and Application secret as HTTP Basic Authorization credentials. These credentials can be created in the Security Integrations part of RADAR Settings. Each JWT has a limited validity of 15 minutes, during which it can be used.

You can find out more about JWT and decode a token on https://jwt.io/.

Examples

Using curl

Once you have your Application ID and secret from RADAR you can add them into the following in a terminal or console:

$ curl \
-X POST \
-u '<Application ID>:<Application secret>' \
https://api.wandera.com/v1/login

This returns the encoded JWT, which has the following format:

{"token":"<JWT header (base 64)>.<JWT payload (base 64)>.<JWT signature>"}

Using jwt.io link above you can decode the payload of this particular JWT:

{
  "customer_id": "4744defa-1042-4a85-9fff-763ae00c7584",
  "iat": 1734456531,
  "exp": 1734457431,
  "aud": "DEVICE_LIFECYCLE_API",
  "client_id": "df3e7a9a-585e-475a-87d5-aa1e83c0cbf1"
}

Note the iat and exp fields in the decoded token where you can check when a JWT was issued and when it expires.

Rate Limiting

The Device Lifecycle API has rate limits to avoid applications degrading the user experience. There are individual limits for requests obtaining JWTs and for permanent device deletion requests.

The current values of the limits are the same for both types – 5 per second and 10,000 per day. Requests are counted for each application integration individually so one application won't block other applications integrated into the same account.

When a request is blocked, the body is empty and time (in milliseconds) until the next possible non-limited request is returned via X-Rate-Limit-Retry-After-Milliseconds response header field. Blocked requests count up to the limits too.

Example of headers of a blocked request:

$ curl \
-D - \
-X POST \
-H 'Authorization: Bearer <JWT token>' \
-H 'Content-Type: application/json; charset=utf-8' \
-d '{"externalIds": ["010fc047-df30-4851-bff8-a26390cf01a6", "020fc047-df30-4851-bff8-a26390cf01a6", "030fc047-df30-4851-bff8-a26390cf01a6"]}' \
https://api.wandera.com/device-lifecycle/v1/4744defa-1042-4a85-9fff-763ae00c7584/devices/purge/async/external

HTTP/2 429
referrer-policy: no-referrer
strict-transport-security: max-age=315360000
vary: Accept-Encoding
x-rate-limit-retry-after-milliseconds: 40298409
content-length: 0
date: Mon, 06 Jan 2020 13:48:21 GMT

Error Messages

When an error occurs during an API call, the user is notified about it with a well-defined error response.

Error codes

Error responses contain machine-parseable error codes. While the error messages may change in the future, the error codes stay the same all the time.

ErrorStatusCodeMessage
UNKNOWN_URI_PATH404The requested URI does not exist.
Forbidden403Access Denied
TOO_MANY_REQUESTS429Too Many Requests.

The error response is structured in the following format.

{
    "timestamp":"2024-11-17T17:20:15.471+00:00",
    "path":"/device-lifecycle/v1/4744defa-1042-4a85-9fff-763ae00c7584/devices/purge/async/external",
    "status":403,
    "error":"Forbidden"
}

Field nameData typeDescription
logrefStringLogging reference
messageStringHuman-readable error description
errorStringFixed error code
statusCodeIntegerHTTP status code

Unauthorized Errors

An unauthorized error might occur during using the API, which could be like the following:

{
  "timestamp": "2020-01-06T15:11:17.882+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Access Denied",
  "path": "/v1/tokens"
}

Where the timestamp and path fields may differ for this error.