Skip to content

Device tokens

A device token is a per-device credential that lets a single ESP32 authenticate directly with the OTA check endpoint, without using a project token that could auto-register new devices.

When to use a device token

Situation Recommended token
Development, CI, or first device registration Project API token
Established production fleet Device token

A project token with device scope can auto-register devices up to your plan limit. Once a device is registered and deployed to production, issuing it a dedicated device token removes the risk of a compromised project token being used to register rogue devices or pull updates on behalf of another device.

A device token:

  • authenticates at /api/v1/ota/check/ and /api/v1/ota/status/
  • cannot auto-register new devices
  • cannot access the developer API
  • is scoped to exactly one device

Token format

Device tokens carry a soto_dev_ prefix to distinguish them from project tokens (soto_proj_) and personal API tokens (soto_pat_) in logs and audit trails.

SimpleOTA stores only a SHA-256 hash of the full token and the first 16 characters as a prefix for audit and debugging purposes. The raw token is shown once at creation time and cannot be recovered; treat it like a password.

Provisioning a device token

There are two flows depending on whether the device has already registered itself.

Flow A: a device that already checked in

For devices that first booted using a project token and auto-registered, switch them to per-device authentication from the dashboard.

  1. Open the dashboard and navigate to the project.
  2. Click into the device row from the Devices list.
  3. On the device detail page, in the Authentication section, click Issue token (or Rotate token if one already exists).
  4. Copy the raw token from the yellow alert box immediately; it is shown once and cannot be retrieved again.
  5. Flash the device with the new token in place of the project token.

Flow B: factory provisioning a new device

For devices that have not yet booted, you can pre-create the device row and its token so the firmware can ship pre-flashed with credentials.

  1. Open the dashboard and navigate to the project.
  2. In the Devices card, click Add device.
  3. Enter the device's stable device_id (MAC address, chip ID, serial, or NVS UUID). Do not enter hardware metadata: the device will self-report its chip family, board, framework, hardware revision, and partition profile on its first check-in.
  4. Submit the form. A new device row is created and a token is issued immediately. Copy the raw token from the yellow alert box.
  5. Flash the device with the token. On its first OTA check-in, the metadata fields populate automatically.

Via the developer API

The same flows are available as REST endpoints under your personal API token (soto_pat_*) or a project API token with the api scope.

# Create a device and issue its token in one step (factory provisioning).
curl -X POST https://simpleota.com/api/v1/projects/<project_id>/devices/ \
     -H "Authorization: Bearer soto_pat_..." \
     -H "Content-Type: application/json" \
     -d '{"device_id": "esp32-sensor-0001"}'
# 201 → returns full device representation plus `raw_token`.

# Issue or rotate the token on an existing device.
curl -X POST https://simpleota.com/api/v1/projects/<project_id>/devices/<device_id>/token/ \
     -H "Authorization: Bearer soto_pat_..."
# 200 → returns {device_id, key_prefix, raw}.

# Revoke the token (device falls back to project-token auth).
curl -X DELETE https://simpleota.com/api/v1/projects/<project_id>/devices/<device_id>/token/ \
     -H "Authorization: Bearer soto_pat_..."
# 204 → no content.

These endpoints make it trivial to script bulk provisioning: loop over your device IDs and store each raw_token in your build pipeline's secrets manager keyed by device_id.

Using a device token in firmware

The Authorization header is identical to a project token; no other code change is required:

Authorization: Bearer soto_dev_your_random_secret_here

If a device was previously using a project token, switching to a device token is a header-only change. The request body, endpoint URL, and response format are all identical.

Arduino example

If you're using the SimpleOTAClient library, just pass the device token as the project-token argument; everything else is the same. The raw HTTPClient form looks like this:

HTTPClient http;
http.begin("https://simpleota.com/api/v1/ota/check/");
http.addHeader("Authorization", "Bearer soto_dev_your_random_secret_here");
http.addHeader("Content-Type",  "application/json");

String body = "{\"device_id\":\"" + String(DEVICE_ID) +
              "\",\"current_build_number\":" + String(currentBuild) + "}";
int code = http.POST(body);

Security properties

Property Detail
Storage SHA-256 hash only; raw token never persisted
Audit First 16 characters stored as prefix for log correlation
Scope Single device; cannot register or access other resources
Revocation Instant; no caching between request and hash check
Logging Prefix only logged, not the full token
Last-used tracking device_token_last_used_at updated on every successful auth

Rotating a device token

In the dashboard, click Rotate token on the device detail page. The new token replaces the old one immediately (hard cutover): the previous raw token stops authenticating the moment the rotation completes. Flash the new token before reboot, or the device will fall back to its project-token auth (if any).

Revoking a device token

In the dashboard, click Revoke next to the token in the Authentication section of the device detail page. Revocation is instant; the device will fall back to project-token auth (if it still holds a valid project token) or receive 401 Unauthorized on its next check-in.

  • Security modes: the token security mode requires a device token at check-in time.
  • Authentication: full token acceptance matrix and error codes.