> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bota.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Refresh Device Token

> Refresh a device token before it expires (4G devices only)

Refresh a device's authentication token. The old token is revoked and a new token is returned. This allows devices to rotate their credentials without requiring a rebind operation.

<Note>
  This endpoint requires a [device token](/authentication), not an API key. The device must use its current valid token to request a new one.
</Note>

<ParamField path="id" type="string" required>
  The device's unique identifier (e.g., `dev_abc123`). Must match the device associated with the token.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.bota.dev/v1/devices/dev_abc123/token/refresh \
    -H "Authorization: Bearer dtok_old_token_here..."
  ```

  ```c Arduino/ESP32 theme={null}
  #include <HTTPClient.h>
  #include <ArduinoJson.h>
  #include <Preferences.h>

  Preferences prefs;

  void refreshDeviceToken() {
    HTTPClient http;
    http.begin("https://api.bota.dev/v1/devices/dev_abc123/token/refresh");

    // Use current token
    String currentToken = prefs.getString("device_token", "");
    http.addHeader("Authorization", "Bearer " + currentToken);

    int httpCode = http.POST("");

    if (httpCode == 200) {
      String response = http.getString();
      StaticJsonDocument<256> doc;
      deserializeJson(doc, response);

      // Store new token
      String newToken = doc["device_token"].as<String>();
      prefs.putString("device_token", newToken);

      Serial.println("Token refreshed successfully");
    }

    http.end();
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "device_token": "dtok_new_token_a1b2c3d4e5f6g7h8i9j0..."
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Invalid or missing device token"
    }
  }
  ```

  ```json 403 theme={null}
  {
    "error": {
      "code": "forbidden",
      "message": "Device token does not match device ID"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "error": {
      "code": "bad_request",
      "message": "Device must be bound to refresh token"
    }
  }
  ```
</ResponseExample>

## Token Lifecycle

```
┌─────────────────┐
│   Bind Device   │ ──► Returns initial dtok_*
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Device Active  │ ◄─────────────────┐
│  (use dtok_*)   │                   │
└────────┬────────┘                   │
         │                            │
         ▼                            │
┌─────────────────┐     ┌─────────────┴───────────┐
│ Refresh Token   │ ──► │ Old token revoked       │
│                 │     │ New dtok_* returned     │
└─────────────────┘     └─────────────────────────┘
         │
         ▼
┌─────────────────┐
│ Unbind Device   │ ──► Token revoked, device unbound
└─────────────────┘
```

## When to Refresh

<Tip>
  We recommend refreshing tokens proactively rather than waiting for expiration. Consider refreshing:

  * Every 7-14 days during normal operation
  * After a firmware update
  * If you suspect the token may have been compromised
</Tip>

## Security Notes

* Only one valid token exists per device at any time
* The old token is immediately invalidated when refreshed
* If a refresh fails, the old token remains valid
* Unbinding a device revokes the token permanently

<Warning>
  The new device token is only shown once in the response. Store it securely on the device immediately. If lost, you must unbind and rebind the device to get a new token.
</Warning>
