Blue Reacher
Devices24 / 46

Devices

One read endpoint for every line in the account.

One read endpoint for every line in the account.

Every route takes Authorization: Bearer <ACCESS_TOKEN> unless the auth line says otherwise. Ids are numbers. Errors use the shape on the errors page.

RouteScopeWhat it does
GET /v1/devicesdevices.readEvery device the installer owns — across all channels — in one list.
GET /v1/devices/{id}devices.readLook up a device by id alone — the channel is resolved automatically.
GET /v1/devices/{channel}/{id}devices.readFetch one device by channel + id.
PATCH /v1/devices/{channel}/{id}devices.writeRename a device, assign/unassign it to a workspace, or set it as default.
DELETE /v1/devices/{channel}/{id}devices.writeRemove a device connection.

List devices

GET https://api.bluereacher.com/v1/devices

Auth: Bearer access token. Scope: devices.read.

Every device the installer owns — across all channels — in one list.

Each channel (iMessage) is stored separately. This single endpoint queries all four sources, normalizes each record into a common structure with a channel field, and returns them together. Requires the devices.read scope. Each channel is queried independently — if one source is briefly unavailable, the others are still returned. The response also includes a summary.by_channel count.

The channel-native values also remain flattened at the top level for backwards compatibility.

Parameters

NameInTypeRequiredDescription
channelqueryenumnoFilter to one channel: "imessage". Omit for all.

Request

curl -X GET "https://api.bluereacher.com/v1/devices" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": [
    {
      "id": 4,
      "channel": "imessage",
      "name": "MacBook Pro",
      "status": "Active-S",
      "health_status": "healthy",
      "last_seen_at": "2026-05-21T09:10:00.000Z",
      "last_ping_at": "2026-05-21T09:10:00.000Z",
      "health": {
        "battery_level": null,
        "battery_charging": null,
        "internet_connection": null,
        "battery_optimized": null,
        "service_uptime": null,
        "is_default_sms_app": null,
        "missing_permissions": null,
        "rate_limit": 100,
        "limit_exceed_action": "queue",
        "last_state": null,
        "last_probe_ok_at": null,
        "last_probe_ms": null,
        "auto_refresh": null
      },
      "channel_details": {
        "device_model": "MacBookPro18,3",
        "os_version": "14.4",
        "app_version": "1.2.0",
        "last_ping": "2026-05-21T09:10:00.000Z",
        "user_name": "Ada Lovelace",
        "rate_limit": 100,
        "limit_exceed_action": "queue"
      },
      "workspace_id": 7,
      "workspace_name": "Acme Co",
      "is_default": false,
      "device_model": "MacBookPro18,3",
      "os_version": "14.4",
      "app_version": "1.2.0",
      "last_ping": "2026-05-21T09:10:00.000Z",
      "user_name": "Ada Lovelace",
      "rate_limit": 100,
      "limit_exceed_action": "queue",
      "created_at": "2026-05-20T08:00:00.000Z",
      "updated_at": "2026-05-21T09:10:00.000Z"
    }
  ],
  "summary": {
    "total": 4,
    "by_channel": {
      "imessage": 1
    }
  }
}
StatusWhenMessage
200OK
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): devices.read.

Response fields

device: A normalized device across any channel. Fields:

FieldTypeDescription
idnumberDevice id within its channel. Example: 12
channelenumWhich channel the device belongs to: "imessage". Example: imessage
namestring, nullableDisplay name (falls back to the device model / imessage user when unnamed).
statusstring, nullable
workspace_idnumber, nullableThe workspace the device is assigned to. null if unassigned.
workspace_namestring, nullableName of the subaccount (workspace) the device is assigned to. null if unassigned.
is_defaultboolean, nullableTrue if this is the default device for its workspace/channel.
created_atstring (ISO 8601), nullableWhen the device connection was created.
updated_atstring (ISO 8601), nullableWhen the device connection was last updated.
health_statusenum
last_seen_atstring (ISO 8601), nullable
last_ping_atstring (ISO 8601), nullable
healthobjectUniform telemetry bag with the SAME keys on every channel — { battery_level, battery_charging, internet_connection, battery_optimized, service_uptime, is_default_sms_app, missing_permissions, rate_limit, limit_exceed_action, last_state, last_probe_ok_at, last_probe_ms, auto_refresh }.
channel_detailsobjectThe full channel-native field set (same values as the flattened extras below), grouped into one object so callers have a stable place to read channel-specific data. Empty object {} when the channel exposes none.
…channel extrasvaries

Get device by id (channel-less)

GET https://api.bluereacher.com/v1/devices/{id}

Auth: Bearer access token. Scope: devices.read.

Look up a device by id alone — the channel is resolved automatically.

Convenience endpoint for callers that already know the device id but not its channel. The API resolves the device across all channels and returns the device when exactly one channel matches.

When the same id exists on multiple channels (rare — device ids are only unique within a channel), the response is 409 Conflict with a channels array, and the caller should re-issue the request against /devices/{channel}/{id} to disambiguate. Use the channel-qualified endpoint directly when you already know the channel — it skips the cross-channel scan.

Parameters

NameInTypeRequiredDescription
idpathnumberyesDevice id within any channel.

Request

curl -X GET "https://api.bluereacher.com/v1/devices/7022" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK — exactly one channel matched):

{
  "success": true,
  "data": {
    "id": 7022,
    "channel": "imessage",
    "name": null,
    "status": "active",
    "health_status": "healthy",
    "last_seen_at": "2026-06-09T11:08:43.000Z",
    "last_ping_at": "2026-06-09T11:08:43.000Z",
    "health": {
      "battery_level": 100,
      "battery_charging": true,
      "internet_connection": "wifi",
      "battery_optimized": false,
      "service_uptime": 172800,
      "is_default_sms_app": true,
      "missing_permissions": [],
      "rate_limit": null,
      "limit_exceed_action": null,
      "last_state": null,
      "last_probe_ok_at": null,
      "last_probe_ms": null,
      "auto_refresh": null
    },
    "channel_details": {
      "device_model": "SM-A065F",
      "app_version": "10.9.5",
      "battery_level": 100,
      "battery_charging": true,
      "internet_connection": "wifi",
      "is_default_sms_app": true,
      "service_uptime": 172800,
      "battery_optimized": false,
      "missing_permissions": [],
      "mms_config": "auto",
      "last_ping": "2026-06-09T11:08:43.000Z",
      "sims": [
        {
          "slot": 1,
          "carrier": "Example Mobile",
          "number": "+15551234567",
          "name": "Example Mobile",
          "country": "US",
          "enabled": true
        },
        {
          "slot": 2,
          "carrier": "Example Mobile",
          "number": "+15557654321",
          "name": "Example Mobile",
          "country": "US",
          "enabled": true
        }
      ]
    },
    "workspace_id": 7,
    "workspace_name": "Acme Co",
    "is_default": null,
    "device_model": "SM-A065F",
    "app_version": "10.9.5",
    "battery_level": 100,
    "battery_charging": true,
    "internet_connection": "wifi",
    "is_default_sms_app": true,
    "service_uptime": 172800,
    "battery_optimized": false,
    "missing_permissions": [],
    "mms_config": "auto",
    "last_ping": "2026-06-09T11:08:43.000Z",
    "sims": [
      {
        "slot": 1,
        "carrier": "Example Mobile",
        "number": "+15551234567",
        "name": "Example Mobile",
        "country": "US",
        "enabled": true
      },
      {
        "slot": 2,
        "carrier": "Example Mobile",
        "number": "+15557654321",
        "name": "Example Mobile",
        "country": "US",
        "enabled": true
      }
    ],
    "created_at": null,
    "updated_at": "2026-06-09T11:08:43.000Z"
  }
}
StatusWhenMessage
200OK — exactly one channel matched
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): devices.read.
404No channel has a device with this idDevice not found

Response fields

device: The matched device. Fields:

FieldTypeDescription
idnumberDevice id within its channel. Example: 12
channelenumWhich channel the device belongs to: "imessage". Example: imessage
namestring, nullableDisplay name (falls back to the device model / imessage user when unnamed).
statusstring, nullable
workspace_idnumber, nullableThe workspace the device is assigned to. null if unassigned.
workspace_namestring, nullableName of the subaccount (workspace) the device is assigned to. null if unassigned.
is_defaultboolean, nullableTrue if this is the default device for its workspace/channel.
created_atstring (ISO 8601), nullableWhen the device connection was created.
updated_atstring (ISO 8601), nullableWhen the device connection was last updated.
health_statusenum
last_seen_atstring (ISO 8601), nullable
last_ping_atstring (ISO 8601), nullable
healthobjectUniform telemetry bag with the SAME keys on every channel — { battery_level, battery_charging, internet_connection, battery_optimized, service_uptime, is_default_sms_app, missing_permissions, rate_limit, limit_exceed_action, last_state, last_probe_ok_at, last_probe_ms, auto_refresh }.
channel_detailsobjectThe full channel-native field set (same values as the flattened extras below), grouped into one object so callers have a stable place to read channel-specific data. Empty object {} when the channel exposes none.
…channel extrasvaries

Get device

GET https://api.bluereacher.com/v1/devices/{channel}/{id}

Auth: Bearer access token. Scope: devices.read.

Fetch one device by channel + id.

A device is addressed by both its channel and its id, since device ids are only unique within a channel. A URL like /v1/devices/{id} without a channel segment will return 404. The response is the same normalized data structure as the list endpoint.

Parameters

NameInTypeRequiredDescription
channelpathenumyes
idpathnumberyesDevice id within that channel.

Request

curl -X GET "https://api.bluereacher.com/v1/devices/imessage/12" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": {
    "id": 12,
    "channel": "imessage",
    "name": "Sales iMessage",
    "status": "ready",
    "health_status": "healthy",
    "last_seen_at": "2026-05-21T09:12:00.000Z",
    "last_ping_at": "2026-05-21T09:13:00.000Z",
    "health": {
      "battery_level": null,
      "battery_charging": null,
      "internet_connection": null,
      "battery_optimized": null,
      "service_uptime": null,
      "is_default_sms_app": null,
      "missing_permissions": null,
      "rate_limit": null,
      "limit_exceed_action": null,
      "last_state": "CONNECTED",
      "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
      "last_probe_ms": 5,
      "auto_refresh": true
    },
    "channel_details": {
      "number": "+15551234567",
      "client_id": "wa_8f21",
      "user_name": "Ada Lovelace",
      "last_state": "CONNECTED",
      "last_activity_at": "2026-05-21T09:12:00.000Z",
      "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
      "last_probe_ms": 5,
      "auto_refresh": true
    },
    "workspace_id": 7,
    "workspace_name": "Acme Co",
    "is_default": true,
    "number": "+15551234567",
    "client_id": "wa_8f21",
    "user_name": "Ada Lovelace",
    "last_state": "CONNECTED",
    "last_activity_at": "2026-05-21T09:12:00.000Z",
    "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
    "last_probe_ms": 5,
    "auto_refresh": true,
    "created_at": "2026-05-21T09:14:22.000Z",
    "updated_at": "2026-05-21T09:14:22.000Z"
  }
}
StatusWhenMessage
200OK
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): devices.read.
404Device does not exist or is not owned by the installerDevice not found

Response fields

device: The device requested. Fields:

FieldTypeDescription
idnumberDevice id within its channel. Example: 12
channelenumWhich channel the device belongs to: "imessage". Example: imessage
namestring, nullableDisplay name (falls back to the device model / imessage user when unnamed).
statusstring, nullable
workspace_idnumber, nullableThe workspace the device is assigned to. null if unassigned.
workspace_namestring, nullableName of the subaccount (workspace) the device is assigned to. null if unassigned.
is_defaultboolean, nullableTrue if this is the default device for its workspace/channel.
created_atstring (ISO 8601), nullableWhen the device connection was created.
updated_atstring (ISO 8601), nullableWhen the device connection was last updated.
health_statusenum
last_seen_atstring (ISO 8601), nullable
last_ping_atstring (ISO 8601), nullable
healthobjectUniform telemetry bag with the SAME keys on every channel — { battery_level, battery_charging, internet_connection, battery_optimized, service_uptime, is_default_sms_app, missing_permissions, rate_limit, limit_exceed_action, last_state, last_probe_ok_at, last_probe_ms, auto_refresh }.
channel_detailsobjectThe full channel-native field set (same values as the flattened extras below), grouped into one object so callers have a stable place to read channel-specific data. Empty object {} when the channel exposes none.
…channel extrasvaries

Update device

PATCH https://api.bluereacher.com/v1/devices/{channel}/{id}

Auth: Bearer access token. Scope: devices.write.

Rename a device, assign/unassign it to a workspace, or set it as default.

Editable fields: name, workspace_id (send null to unassign), and is_default.

Parameters

NameInTypeRequiredDescription
channelpathenumyes
idpathnumberyesDevice id.
namebodystringnoNew display name. Max 255.
workspace_idbodynumbernoAssign to a workspace (must belong to the installer). Send null to unassign.
is_defaultbodybooleannoMark/unmark as the default device for its channel.

Request

curl -X PATCH "https://api.bluereacher.com/v1/devices/imessage/12" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Sales iMessage (renamed)",
  "workspace_id": 7,
  "is_default": true
}'

Responses

A 200 reply (Updated):

{
  "success": true,
  "data": {
    "id": 12,
    "channel": "imessage",
    "name": "Sales iMessage (renamed)",
    "status": "ready",
    "health_status": "healthy",
    "last_seen_at": "2026-05-21T09:12:00.000Z",
    "last_ping_at": "2026-05-21T09:13:00.000Z",
    "health": {
      "battery_level": null,
      "battery_charging": null,
      "internet_connection": null,
      "battery_optimized": null,
      "service_uptime": null,
      "is_default_sms_app": null,
      "missing_permissions": null,
      "rate_limit": null,
      "limit_exceed_action": null,
      "last_state": "CONNECTED",
      "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
      "last_probe_ms": 5,
      "auto_refresh": true
    },
    "channel_details": {
      "number": "+15551234567",
      "client_id": "wa_8f21",
      "user_name": "Ada Lovelace",
      "last_state": "CONNECTED",
      "last_activity_at": "2026-05-21T09:12:00.000Z",
      "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
      "last_probe_ms": 5,
      "auto_refresh": true
    },
    "workspace_id": 7,
    "workspace_name": "Acme Co",
    "is_default": true,
    "number": "+15551234567",
    "client_id": "wa_8f21",
    "user_name": "Ada Lovelace",
    "last_state": "CONNECTED",
    "last_activity_at": "2026-05-21T09:12:00.000Z",
    "last_probe_ok_at": "2026-05-21T09:13:00.000Z",
    "last_probe_ms": 5,
    "auto_refresh": true
  }
}
StatusWhenMessage
200Updated
400Empty body — no editable fields providedNo editable fields provided. Editable: name, workspace_id, is_default.
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): devices.write.
404Device does not exist or is not owned by the installerDevice not found

Response fields

device: The updated device. Fields:

FieldTypeDescription
idnumberDevice id within its channel. Example: 12
channelenumWhich channel the device belongs to: "imessage". Example: imessage
namestring, nullableDisplay name (falls back to the device model / imessage user when unnamed).
statusstring, nullable
workspace_idnumber, nullableThe workspace the device is assigned to. null if unassigned.
workspace_namestring, nullableName of the subaccount (workspace) the device is assigned to. null if unassigned.
is_defaultboolean, nullableTrue if this is the default device for its workspace/channel.
created_atstring (ISO 8601), nullableWhen the device connection was created.
updated_atstring (ISO 8601), nullableWhen the device connection was last updated.
health_statusenum
last_seen_atstring (ISO 8601), nullable
last_ping_atstring (ISO 8601), nullable
healthobjectUniform telemetry bag with the SAME keys on every channel — { battery_level, battery_charging, internet_connection, battery_optimized, service_uptime, is_default_sms_app, missing_permissions, rate_limit, limit_exceed_action, last_state, last_probe_ok_at, last_probe_ms, auto_refresh }.
channel_detailsobjectThe full channel-native field set (same values as the flattened extras below), grouped into one object so callers have a stable place to read channel-specific data. Empty object {} when the channel exposes none.
…channel extrasvaries

Delete device

DELETE https://api.bluereacher.com/v1/devices/{channel}/{id}

Auth: Bearer access token. Scope: devices.write.

Remove a device connection.

Parameters

NameInTypeRequiredDescription
channelpathenumyes
idpathnumberyesDevice id.

Request

curl -X DELETE "https://api.bluereacher.com/v1/devices/imessage/12" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (Deleted):

{
  "success": true,
  "message": "Device deleted.",
  "data": {
    "channel": "imessage",
    "id": 12,
    "deleted": true
  }
}
StatusWhenMessage
200Deleted
400Device still assigned to a workspace/subaccount — unassign firstThis device is assigned to a workspace. Unassign it (set workspace_id to null) before deleting.
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): devices.write.
404Device does not exist or is not owned by the installerDevice not found

On this page