Transitioning the REST API
This guide walks through how to migrate scripts from the legacy nRF Cloud REST API to the new nRF Cloud API to take advantage of improved authentication and extended API support.
The legacy REST API continues to work during the transition, so you can migrate one endpoint at a time.
This guide covers only endpoints that are available in the new nRF Cloud API today. Deprecated endpoints with no planned replacement are listed in Deprecated endpoints without a replacement.
Please reach out in our DevZone community forum if you have any questions.
Moving from API keys to Organization Auth Tokens
The legacy nRF Cloud API keys are deprecated in favor of nRF Cloud Organization Auth Tokens (OATs). OATs add a number of new capabilities that API keys don't support:
| Capability | OAT | Legacy API key |
|---|---|---|
| Onboard a device: with an attestation token, onboarding token, or certificate | ✅ | ✅ |
| Centrally managed: organization admins own the tokens, not individual users | ✅ | ❌ |
| Rich access control: read-only, read/write, or individual permissions | ✅ | ❌ |
| Audit logged: who did what, when, and from where | ✅ | ❌ |
| Isolated revocation: one token per integration, revoked without affecting others | ✅ | ❌ |
| Project scoping: limit a token to specific projects within an organization | ✅ | ❌ |
| Works across the whole platform: one token for all nRF Cloud APIs | ✅ | ❌ |
See Organization Auth Tokens for more details about OATs.
What is changing
Both APIs continue to use https://api.nrfcloud.com, but authentication and the
way you scope requests have changed:
| Aspect | Legacy nRF Cloud REST API | nRF Cloud API |
|---|---|---|
| Authentication | Legacy API key | Organization auth token (OAT) |
| Scope | The team that owns the API key | An organization and a project, both specified in the URL |
| URL prefix | /v1/ | /v1/organizations/<ORG>/projects/<PROJECT>/ |
| Permissions | The API key owner's role in the team | OAT permissions, such as device:read and device:write |
Before you begin the migration
You need:
- An Organization Auth Token. Organization admins can create one under Admin → Organization Auth Tokens → Create Token.
- Your Organization Slug and Project Slug, both of which appear under Project Settings → General.
The following examples assume your OAT, Organization Slug, and Project Slug are
available as the environment variables NRFCLOUD_OAT, NRFCLOUD_ORG, and
NRFCLOUD_PROJECT, respectively. For requests that target a single device, set
DEVICE_ID to its nRF Cloud device ID.
Set BASE to the project-scoped URL prefix:
BASE="https://api.nrfcloud.com/v1/organizations/$NRFCLOUD_ORG/projects/$NRFCLOUD_PROJECT"
Send the OAT in the Authorization header using the Bearer scheme, as you did
with the API key:
-H "Authorization: Bearer $NRFCLOUD_OAT"
Endpoint mapping
Paths in the nRF Cloud API column are relative to
/v1/organizations/<ORG>/projects/<PROJECT>.
| Task | Legacy nRF Cloud REST API | nRF Cloud API |
|---|---|---|
| Retrieve a device | GET /v1/devices/{deviceId} | GET /devices/{deviceId} |
| List devices | GET /v1/devices | GET /devices |
| Onboard a device | POST /v1/devices/{deviceId} | nrfcloud device create |
| Onboard devices in bulk | POST /v1/devices | nrfcloud device create |
| Track a bulk operation | GET /v1/bulk-ops-requests, GET /v1/bulk-ops-requests/{id}, GET /v1/bulk-ops-assets/{id}/{id} | Not needed: nrfcloud device create waits for the result |
| Delete a device | DELETE /v1/devices/{deviceId} | DELETE /long-range/devices/{deviceId} |
| Retrieve the device state | GET /v1/devices/{deviceId} | GET /long-range/devices/{deviceId}/state |
| Update the device state | PATCH /v1/devices/{deviceId}/state | PATCH /long-range/devices/{deviceId}/state |
| Publish a device message | POST /v1/devices/{deviceId}/messages | POST /long-range/devices/{deviceId}/mqtt-message |
| List stored device messages | GET /v1/messages | GET /messages |
| List location history | GET /v1/location/history | GET /location/history |
The sections below describe the differences for each task.
Devices
Retrieve, list, and rename devices
Use the Devices API in the new nRF Cloud experience to retrieve, list, and rename devices. This API covers all devices in the project.
In this API, the nRF Cloud device ID is the device serial (device_serial).
To retrieve a device:
curl "$BASE/devices/$DEVICE_ID" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
The response uses the Devices API's device format. For example, the device ID is
returned as device_serial, and the device belongs to a cohort instead of
having tags. See
Retrieve a Device.
The legacy endpoint also returned the device state. To retrieve it, use the
device state endpoint. The transform query
parameter is also available at that endpoint.
To list devices:
curl "$BASE/devices" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
The legacy filters, such as tags, subTypes, firmwareSupport, and
deviceNameFuzzy, and the transform parameter are not available. See
List Devices for the supported
parameters and the response format.
To rename a device, set its nickname instead of sending the new name to the
legacy /name endpoint:
curl -X PATCH "$BASE/devices/$DEVICE_ID" \
-H "Authorization: Bearer $NRFCLOUD_OAT" \
-H "Content-Type: application/json" \
-d '{"nickname": "warehouse-east-01"}'
See Update a Device.
Onboard devices
Onboard devices with your OAT and the nrfcloud device create CLI command. It
uploads a CSV of devices, waits for nRF Cloud to process it, and reports the
result for each device:
nrfcloud --org-token $NRFCLOUD_OAT \
--org $NRFCLOUD_ORG --project $NRFCLOUD_PROJECT \
device create --csv devices.csv
For more details, see the Onboarding Devices with the CLI best practices guide.
Tracking Bulk Device Onboarding
When you onboard with nrfcloud device create, you do not need to track the
upload: the command waits for it to complete and reports the result for each
device.
Delete a device
curl -X DELETE "$BASE/long-range/devices/$DEVICE_ID" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
Deleting a device also releases its claim, so another project can onboard it.
Deletion is idempotent: deleting a device that does not exist also returns
202 Accepted.
Device state
Retrieve the device state
The legacy API returned the state as part of the device response. In the new API, the state has a dedicated endpoint:
curl "$BASE/long-range/devices/$DEVICE_ID/state" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
The response contains reported, desired, delta, metadata, and version.
The transform query parameter accepts a JSONata expression, as before, but it
is evaluated against this state object rather than the whole device.
See Retrieve the State of an nRF9x Device.
Update the device state
The request body is unchanged: a patch with desired, reported, or both.
curl -X PATCH "$BASE/long-range/devices/$DEVICE_ID/state" \
-H "Authorization: Bearer $NRFCLOUD_OAT" \
-H "Content-Type: application/json" \
-d '{"desired": {"control": {"logLvl": 3}}}'
Differences:
- The patch is validated before it is applied. Paths owned by the platform, such
as
pairing,connection, anddesired.device, are rejected unless you addforce=trueto the query string, and some paths have a required value type. All violations are reported in a single422 Unprocessable Entityresponse, and the state remains unchanged. - The
If-Matchheader is ignored. The patch is always merged into the current state.
See Update the State of an nRF9x Device for the full list of constrained paths.
Messages
Publish a device message
Like the legacy endpoint, the new endpoint publishes an MQTT message on behalf
of a device. The legacy topic was relative to <mqttTopicPrefix>/m/, so it
could name any topic. The new endpoint publishes only to the device's own
topics, <mqttTopicPrefix>/m/d/<deviceId>/<subtopic>, and rejects devices that
connect over CoAP.
The request body has changed:
| Legacy field | nRF Cloud API |
|---|---|
topic | subtopic: the part after d/<deviceId>/, for example d2c instead of d/<deviceId>/d2c |
message | payload for a JSON object or array, or payloadBase64 for binary data |
| — | contentType (optional): the MQTT content type of the published message |
curl -X POST "$BASE/long-range/devices/$DEVICE_ID/mqtt-message" \
-H "Authorization: Bearer $NRFCLOUD_OAT" \
-H "Content-Type: application/json" \
-d '{"subtopic": "d2c", "payload": {"appId": "TEMP", "messageType": "DATA", "data": "23.5"}}'
This example publishes to the device-to-cloud topic, as if the device had sent
the message. To deliver a message to a device that uses the nRF Cloud library,
publish to its receive topic, c2d/r, instead.
The device ID comes from the URL. A subtopic that starts with the device ID or
with d/<deviceId> is rejected. The subtopic must have one to three levels, and
the full topic must not exceed 256 bytes. The 202 Accepted response contains
the full MQTT topic to which the message was published.
See Publish an MQTT Message for an nRF9x Device.
List stored device messages
curl "$BASE/messages?deviceId=$DEVICE_ID" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
The following filter and pagination parameters are unchanged: deviceId,
appId, topic, start, end, pageLimit, pageSort, and pageNextToken.
The same filter combinations are supported: topic requires deviceId and
cannot be combined with appId.
Differences from the legacy endpoint:
- The deprecated
inclusiveStartandexclusiveEndparameters are removed. Usestartandend. - Messages in the response no longer include
tenantId.
See List nRF9x Device Messages.
Location history
curl "$BASE/location/history?deviceId=$DEVICE_ID" \
-H "Authorization: Bearer $NRFCLOUD_OAT"
The OAT requires the device:read permission. Omit deviceId to list the
history of all devices in the project.
For the other Location Services endpoints, see Location Services.
Deprecated endpoints without a replacement
The following legacy endpoints are deprecated and have no planned replacement in the nRF Cloud API. Where an alternative workflow is available in the new nRF Cloud experience, it is listed below.
| Legacy endpoint | What to use instead |
|---|---|
PUT /v1/devices/{deviceId}/name | The device name is now returned as nickname. See Retrieve, list, and rename devices. |
GET /v1/devices/tags, PUT /v1/devices/{deviceId}/tags | Tags are replaced by cohorts. |
PUT /v1/association/{deviceId} | Replaced by device attributes. |
/v1/devices/certificates, /v1/devices/{deviceId}/certificates, /v1/devices/{deviceId}/image, /v1/devices/public-keys | Onboard the device with nrfcloud device create, as described in Onboard devices. |
/v1/devices/mqtt-team, /v1/devices/mqtt-team/{id} | Use the Message Routing Service. If you still rely on these endpoints, contact support. |
/v1/alerts | Use Alerts in the new nRF Cloud experience. |
/v1/firmwares, /v1/fota-jobs, /v1/fota-job-executions, /v1/fota-job-execution-statuses, and subpaths | OTA updates in the new nRF Cloud experience. See New FOTA Experience. |
/v1/account, /v1/account/usage, /v1/account/service-token, /v1/status | No replacement. These endpoints are needed only with legacy API keys. |