---
title: "RegisterPublicKeys"
method: POST
path: "/devices/public-keys"
tags: ["IP Devices"]
---

# RegisterPublicKeys

`POST /devices/public-keys`

Register one or more public keys so that the signatures for [JSON Web Tokens (JWTs)](https://docs.nordicsemi.com/bundle/nrf-cloud/page/Devices/Security/JWT.html) sent by the device can be verified.

This endpoint supports the following use case:
- Devices that <strong>are [onboarded](https://docs.nordicsemi.com/bundle/nrf-cloud/page/Devices/Associations/Onboarding.html)</strong> on nRF Cloud and want to use a dedicated private key for signing JWTs instead of the key associated
with the device's cloud-onboarding certificate (e.g., onboarded with the <a href="#operation/OnboardDevices">OnboardDevices endpoint</a>,
which automatically extracts and stores a public key during the onboarding process for use in subsequent JWT signature verifications).

Only one public key may be registered for each device. Uploading CSV data with a different key for the same device will overwrite the existing key.

Public keys must be [ES256](https://ldapwiki.com/wiki/Wiki.jsp?page=ES256). For more information, see the [nRF Cloud REST Authentication documentation](https://docs.nordicsemi.com/bundle/nrf-cloud/page/APIs/REST/RESTOverview.html#authentication).

This endpoint supports [asynchronous bulk operations](#tag/Bulk-Ops-Requests). Your data will be validated, and if valid, you
will receive an HTTP 202 response with a `bulkOpsRequestId`. You can use this id with the bulk ops endpoints
to track the request's processing status. If the bulk ops request indicates FAILED status, check the JSON errors file (URL in the bulk
ops request details), fix the offending rows, then re-submit the CSV with only those rows.

Each CSV row must in the format `deviceId,"keyPem"`, where:

|Field|Required|Description|Validation Pattern|
|---|:---:|---|---|
|`deviceId`<div style="width:90px"></div>|Yes|A globally unique device id (UUIDs are highly recommended)|`/^[a-z0-9:_-]{1,128}$/i`|
|`keyPem`|Yes|A unique [ES256](https://ldapwiki.com/wiki/Wiki.jsp?page=ES256) public key in PEM format, wrapped in double quotes (to allow for line breaks in CSV)|`/^-{5}BEGIN PUBLIC KEY-{5}(\r\n\|\r\|\n)([^-]+)(\r\n\|\r\|\n)-{5}END PUBLIC KEY-{5}(\r\n\|\r\|\n)$/`|

Example of a CSV row:
   #### All values set
<span style="font-family:Courier">f69c0e45-7f04-4949-8def-bb2215b4223e,"-----BEGIN PUBLIC KEY-----<br/>MIIB7DCCAZMCFD...Av3CVgjzn5BLS03X7lyf4w==<br/>
-----END PUBLIC KEY-----<br/>"</span>

Also note:
   * Max number of rows is 1000.
   * Do not use a header.
   * Do not leave any blank lines.

Example of uploading CSV data as a binary file:

```sh
curl -X POST $API_HOST/v1/devices/public-keys \
--data-binary @$PATH_TO_CSV_FILE \
-H "Content-Type: application/octet-stream" \
-H "Authorization: Bearer $API_KEY"
```
Note that for some unknown reason, curl will strip the final line break in each ES256 public key when sending the CSV file using a non-binary content-type, e.g., using syntax such as `-d @$PATH_TO_CSV_FILE -H "Content-Type: text/csv"`. Therefore, with curl use `--data-binary` only. If you want to send the CSV as text, use a REST client like Postman or Insomnia.

## Headers

- `content-type` 'text/plain;charset=UTF8' | 'text/plain;charset=ASCII' | 'text/plain' | 'application/octet-stream' | 'text/csv', required

## Request body

- string

## Response `202`

- object
  - `bulkOpsRequestId` string, required — Universally Unique Lexicographically Sortable Identifier (using Crockford's alphabet).

## Other responses

- `422` — Validation Failed

---

[API](https://skmtc.dev/nrfcloud/apis/nrf-cloud-rest-api.md) · [All operations](https://skmtc.dev/nrfcloud/apis/nrf-cloud-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/nrfcloud/nrf-cloud-rest-api/revisions/c4e56e458ebf/schema)
