> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/deployment/self-hosted/enterprise/deployment-manager.md).

# Deployment Manager

Manage and monitor computer vision models deployed on edge hardware.

## About

Roboflow Deployment Manager lets you easily set up, deploy, and manage computer vision models on edge devices. After training your model and building a workflow, it provides an all-in-one solution for scaling deployments.

You can use Deployment Manager to:

1. Set up new devices with the [Roboflow Inference server](/deployment/self-hosted/self-hosted.md).
2. Configure camera streams for use in a deployment.
3. Deploy [Workflows](https://docs.roboflow.com/workflows) on the edge.
4. Monitor logs, stream status, and telemetry for deployed edge devices.

{% hint style="warning" %}
Deployment Manager is available exclusively for Enterprise customers. [Contact the Roboflow sales team](https://roboflow.com/sales) to learn more about this feature and how it can be used to manage your deployments at scale.
{% endhint %}

<figure><img src="https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-96d50cdbdfa347cff727c2eddcaa8ee3d85aa550%2Fenterprise-device-overview.png?alt=media" alt="Device overview with service health, disk usage, and running Streams"><figcaption></figcaption></figure>

### Key Requirements:

Deployment Manager is built for Roboflow-supported hardware:

* Supported: Hardware purchased via Roboflow
* Unsupported (use at your own risk): NVIDIA Jetson, x86 machines running Debian-based Linux with NVIDIA GPUs
* Not yet supported: Mac or Windows-based systems

Devices need connectivity to Roboflow for setup, remote management, and monitoring. To run inference at a site without internet access, [prepare your device for offline operation](/deployment/self-hosted/enterprise/deployment-manager/setting-up/prepare-a-device-for-offline-operation.md).

### Edge Services

Alongside the inference server, a device can run additional Roboflow [Services](/deployment/self-hosted/enterprise/deployment-manager/services.md). Add and configure them from the device's Configuration tab, described in [Update Device Configuration](/deployment/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md).

* [Event Store](/deployment/self-hosted/enterprise/deployment-manager/services/event-store.md) stores inference events on the device, with automatic retention and optional cloud backup.
* [OPC UA Server](/deployment/self-hosted/enterprise/deployment-manager/services/opc-ua-server.md) publishes data as OPC UA tags for PLCs and SCADA systems.
* [PLC Relay](/deployment/self-hosted/enterprise/deployment-manager/services/plc-relay.md) reads and writes PLC tags over Allen-Bradley, Modbus TCP, or Siemens S7.
* [RTSP Simulator](/deployment/self-hosted/enterprise/deployment-manager/services/rtsp-simulator.md) streams an uploaded video file as an RTSP source for testing.

Each service serves its own HTTP API on the device's address. See [Services](/deployment/self-hosted/enterprise/deployment-manager/services.md#using-the-apis) for the base URL, authentication, and error-shape rules they share.

## Web App

Open the "Edge Devices" tab on the "Deployments" page to see your devices. Devices seen in the past seven days are listed first. "Services" and "Streams" show how many configured services are healthy and how many Streams are running. Hover over a count to see services that are still downloading or starting, or Streams waiting for a TensorRT engine to compile. Restarting the device during a compile discards it. "Last Heartbeat" shows when Roboflow last heard from the device: after 5 minutes without one, the device shows as offline.

Select an Inference or JetPack version group in the device list's navigation to find devices running that version. These groups update automatically from devices seen in the past seven days and cannot be renamed or deleted. To update an Inference group, select its devices and [set their inference version](/deployment/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md).

<figure><img src="https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-145e9c9480e2e0ceefa973249b92504a4eab2cab%2Fdevice-version-groups.png?alt=media" alt="Deployment Manager navigation with Inference and JetPack version groups beside the devices running Inference v1.7.4"><figcaption></figcaption></figure>

## Guides

### Setting Up

Follow the [Setting Up](/deployment/self-hosted/enterprise/deployment-manager/setting-up.md) guides in order to get a device online and running Workflows.

| Guide                                                                                                                      | Description                                                              |
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| [Hardware Requirements](/deployment/self-hosted/enterprise/deployment-manager/setting-up/hardware-requirements.md)         | Supported hardware, cameras, network, and outbound traffic requirements. |
| [Add a Device](/deployment/self-hosted/enterprise/deployment-manager/setting-up/add-a-device.md)                           | Provision a new edge device and register it with your account.           |
| [Add a Stream](/deployment/self-hosted/enterprise/deployment-manager/setting-up/add-a-stream.md)                           | Configure a camera stream that runs a Workflow.                          |
| [Set up Device Alerts](/deployment/self-hosted/enterprise/deployment-manager/setting-up/set-up-device-alerts.md)           | Enable email alerts for connectivity, disk, and FPS issues.              |
| [Setup Maintenance Windows](/deployment/self-hosted/enterprise/deployment-manager/setting-up/setup-maintenance-windows.md) | Schedule when deploy-affecting changes take effect.                      |

### Making Changes

The [Making Changes](/deployment/self-hosted/enterprise/deployment-manager/making-changes.md) guides cover updating, reconfiguring, and removing devices and streams after setup.

| Guide                                                                                                                                  | Description                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [Update Device Configuration](/deployment/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md)     | Manage device settings, service versions, and additional services. |
| [Configure Device Network](/deployment/self-hosted/enterprise/deployment-manager/making-changes/configure-device-network.md)           | Set IP addressing, gateway, DNS, and hostname from the cloud.      |
| [Configure AI1 Camera Settings](/deployment/self-hosted/enterprise/deployment-manager/making-changes/configure-ai1-camera-settings.md) | Tune exposure, gain, focus, and other AI1 camera settings live.    |
| [Set a Static IP for a Camera](/deployment/self-hosted/enterprise/deployment-manager/making-changes/set-camera-static-ip.md)           | Assign a persistent static IP to a GigE Basler or Lucid camera.    |
| [Restart a PoE Port](/deployment/self-hosted/enterprise/deployment-manager/making-changes/soft-reset-poe-port.md)                      | Restart a camera's PoE port to recover a stuck camera link.        |
| [Pause and Resume a Stream](/deployment/self-hosted/enterprise/deployment-manager/making-changes/stop-a-stream.md)                     | Temporarily pause a running stream and resume it later.            |
| [Trigger a Stream](/deployment/self-hosted/enterprise/deployment-manager/making-changes/trigger-a-stream.md)                           | Run a Workflow on demand against a Triggered stream.               |
| [Terminate a Stream](/deployment/self-hosted/enterprise/deployment-manager/making-changes/delete-a-stream.md)                          | Permanently remove a stream and its configuration.                 |
| [Redeploy Deployment Manager](/deployment/self-hosted/enterprise/deployment-manager/making-changes/redeploy-deployment-manager.md)     | Recover a device's configuration after a failure.                  |
| [Delete a Device](/deployment/self-hosted/enterprise/deployment-manager/making-changes/delete-a-device.md)                             | Permanently remove a device you no longer use.                     |
| [API Keys for Deployment Manager](/deployment/self-hosted/enterprise/deployment-manager/making-changes/api-keys-for-device-manager.md) | How device API keys are generated, scoped, and revoked.            |

### Monitoring

The [Monitoring](/deployment/self-hosted/enterprise/deployment-manager/monitoring.md) guides show how to check stream status, logs, resources, and Event Store health.

Use [device Activity](/deployment/self-hosted/enterprise/deployment-manager/monitoring/view-device-activity.md) to investigate errors around a deployment and restore a saved configuration.

| Guide                                                                                                                      | Description                                                   |
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| [View a Stream](/deployment/self-hosted/enterprise/deployment-manager/monitoring/view-a-stream.md)                         | View a stream's status, latest frame, and Workflow details.   |
| [View Device Logs](/deployment/self-hosted/enterprise/deployment-manager/monitoring/view-device-logs.md)                   | Search, filter, and download logs from Roboflow services.     |
| [View the Resource Monitor](/deployment/self-hosted/enterprise/deployment-manager/monitoring/view-the-resource-monitor.md) | Monitor disk, memory, CPU, GPU, and service container health. |
| [View Event Store Status](/deployment/self-hosted/enterprise/deployment-manager/monitoring/view-event-store-status.md)     | Monitor Event Store usage, backup progress, and history.      |

## HTTP API

The Deployment Manager API lets you monitor and manage your Roboflow Deployment Manager (RFDM) devices programmatically.

All endpoints are mounted under `/:workspace/devices/v2` on the public API host (`https://api.roboflow.com`). Read endpoints require a [scoped API key](https://docs.roboflow.com/reference/authentication/authentication/scoped-api-keys) with the `device:read` scope; endpoints that change a device require `device:update`. Workspace API keys with no explicit scopes list are implicitly granted all scopes (legacy behavior); keys that carry an explicit `scopes` array must include the relevant scope.

With the Deployment Manager API, you can:

* [List and Get Devices](#list-and-get-devices)
* [Create a Device](#create-a-device)
* [Device Config](#device-config)
* [Device Commands](#device-commands)
* [Device Streams](#device-streams)
* [Device Logs and Telemetry](#device-logs-and-telemetry)
* [Device Events](#device-events)
* [Device Services](#device-services)
* [Device Groups](#device-groups)
* [Device Management](#device-management)

The optional edge services (Event Store, PLC Relay, RTSP Simulator, OPC UA Server) serve their own HTTP APIs on the device's address rather than through `api.roboflow.com`. They do not accept a Roboflow API key, and their authentication and error shapes differ from everything below. See [Services](/deployment/self-hosted/enterprise/deployment-manager/services.md#using-the-apis).

### Authentication

All endpoints accept a workspace API key via either:

* Query string: `?api_key=YOUR_API_KEY`
* Header: `Authorization: Bearer YOUR_API_KEY`

#### Device-scoped API keys

API keys minted for a specific device (for example, by RFDM during install) are narrowed to that device. They may only call routes whose `:deviceId` path parameter equals the key's bound device. They will receive **403** on the workspace-wide list and create endpoints, and on any `:deviceId` path that doesn't match.

### Cross-workspace isolation

A workspace API key can only read or modify devices that belong to its workspace. Requests for a device id owned by a different workspace return **404**, even if the id is otherwise valid.

### Errors

| Status | Meaning                                                                                                                                                                                                                                                                                              |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | Invalid query parameter (unknown `time_period`, malformed cursor or date, invalid `direction`, etc.) or invalid request body.                                                                                                                                                                        |
| 401    | Missing or invalid API key.                                                                                                                                                                                                                                                                          |
| 403    | Device-scoped API key targeting a different device, the workspace-wide list/create routes, a source device from another workspace during duplication, or a feature-gated request rejected (for example, `offline_mode` without Roboflow Lite mode, or Secure Gateway not enabled for the workspace). |
| 404    | Device, stream, config, or source device not found. Read requests for device ids owned by another workspace also return 404.                                                                                                                                                                         |
| 429    | Rate limit exceeded. Log reads are limited to 120 requests per minute per workspace; telemetry reads are limited to 60 requests per minute per device with a 10-request burst over 10 seconds.                                                                                                       |

Error responses use one of two shapes:

* Handler-level errors (typically 400, 403, 404, and 429 from the handlers themselves) return `{ "error": "<message>" }`.
* Authentication and workspace-validation failures (typically 401) return a structured `error` object: `{ "error": { "message": "...", "status": 401, "type": "OAuthException", "hint": "..." } }`.

The logs rate limiter additionally returns a plain string body (not JSON) when it triggers a **429**.

### List and Get Devices

#### List Devices

List every device registered in the workspace. Device-scoped API keys cannot call this endpoint and receive **403**.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Get Device

Retrieve a single device by id.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Create a Device

Create a new device in your workspace and return the identifiers needed to install it. Device-scoped API keys cannot call this endpoint and receive **403**.

**Required scope:** `device:update`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

Use the returned `installId` to bootstrap the device with the Roboflow Deployment Manager installer.

#### Notes on AI1 and Roboflow OS devices

* `offline_mode` is only valid for AI1 devices and Roboflow OS devices (`device_type` `"edge"` with `os` `"roboflow-os"`), on workspaces with Roboflow Lite mode. Other device types return **400**, and workspaces without Roboflow Lite mode return **403**.
* When offline mode applies, the response also includes an `offlineProvisioningQrPayload` field encoding the QR payload for offline provisioning.

#### Notes on duplication

When `sourceDeviceId` is supplied, the new device is created from a copy of the source device's config. The source device must belong to the same workspace as the request, otherwise the request returns **403**. A non-existent `sourceDeviceId` returns **404**.

See [Duplicate a device](/deployment/self-hosted/enterprise/deployment-manager/setting-up/add-a-device.md#duplicate-a-device) for which settings carry over and how to install the copy.

### Device Config

#### Get Workspace Default Config

Returns the workspace-level default device configuration. This is the base default config with the workspace's config patch (if any) merged in. Use it as a template when provisioning a new device before calling `POST /:workspace/devices/v2`.

**Required scope:** `device:read`

{% hint style="info" %}
This is a workspace-wide endpoint. Device-scoped API keys will receive **403** since there is no `:deviceId` in the path.
{% endhint %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/default-config" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Update Workspace Default Config

Replace the workspace's config patch. New devices start from the merged result. Send the whole patch each time, because the new one replaces the old one.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/default-config" method="patch" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Get Config

Returns the device's stored configuration, not proof of its running state. The response shape mirrors the Roboflow Deployment Manager (RFDM) config spec.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/config" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% hint style="warning" %}
Stream credentials are removed unless a device-bound key reads its own config, which retains the encrypted credentials RFDM needs. Per-service `environment_variables` and other credentials embedded in the config are returned as stored. Treat the response body as sensitive and do not log it in plaintext.
{% endhint %}

#### Update Config

Change part of a device's configuration (ex: a stream's Workflow, a confidence threshold, a service setting). Send only the fields you want to change: nested objects merge, `null` removes a key, and an array replaces the whole array. You do not need to send the full config back.

On a production device in a Workspace with configuration approval enabled, a change can return `staged: true` and `configProposal` while it waits for approval. This does not change live config. Unapproved changes stay held through maintenance windows, and neither `forceApply` nor `immediateDelta` bypasses approval.

Once approval requirements are met, deployment changes can still wait for a [maintenance window](/deployment/self-hosted/enterprise/deployment-manager/setting-up/setup-maintenance-windows.md), with `deferred: true`. Set `forceApply=true` to request applying this change and everything queued now, or `immediateDelta=true` to request applying only this patch. Read the config again to verify the save, then check device-reported service versions, stream status, and output to verify the change is running.

**Required scope:** `device:update`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/config" method="patch" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Config History

List prior configuration revision metadata for a device, newest first.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/config/history" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Set Service Version

Set the inference or manager version on one device without sending the whole config. Read the service's current `image` from [Get Config](#get-config) and send it with the new version. If the image changed since you read it, the request fails, so you never pin a version to the wrong image. On a device with [maintenance windows](/deployment/self-hosted/enterprise/deployment-manager/setting-up/setup-maintenance-windows.md), the change waits for the next window. To update many devices, call this once per device.

Required scope: `device:update`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/config/service-version" method="patch" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Device Commands

Actions you start from the web app (ex: restart a device, pause a stream, scan for cameras) are queued as commands. The device picks them up on its next poll.

#### Queue a Command

Queue a command for a device to run on its next poll. This does from the API what the web app does when you restart a device or start a stream.

**Required scope:** `device:update`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/commands" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Device Streams

#### List Streams

List every stream configured on a device.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/streams" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Get Stream

Retrieve a single stream.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/streams/{streamId}" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Device Logs and Telemetry

#### Logs

Returns paginated device logs.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/logs" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

**Rate limit:** 120 requests per minute per workspace. Log reads and log ingest use separate rate-limit buckets, so polling for logs will not count against your ingest quota (and vice versa).

#### Telemetry

Returns aggregated hardware metrics (CPU, memory, disk, GPU) and per-stream FPS for a device, bucketed over a fixed time window.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/telemetry" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

**Rate limits**

This endpoint is rate-limited per device to **60 requests per minute** with an additional **10 requests per 10 seconds** burst limiter. Excess requests return **429**. The same per-device telemetry quota is shared with the device's telemetry ingest path, so abusive reads can affect ingest for the same device.

### Device Events

Returns device and stream lifecycle events (for example device boots, stream starts and stops, errors, config changes).

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/events" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

By default the feed collapses repeated events into state changes, which hides periodic telemetry that reuses one event name. Pass `dedupe=false` with both `entity_type` and `entity_id` to read every raw row. To chart one value over time, use the [service series endpoint](#device-services) instead: it resolves the entity ID for you.

### Device Services

Returns the [services](/deployment/self-hosted/enterprise/deployment-manager/services.md) a device runs, joined to their live status: container state, image version, and per-kind status such as PLC connection state or Event Store capacity.

**Required scope:** `device:read`

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/services" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/services/{serviceName}" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

Use these endpoints to poll a fleet: ask for `include=status` to check that a service is up and reporting, and add `include=metrics` for its CPU and memory.

{% hint style="info" %}
`include=config` returns environment variable values as they are stored, and those often hold credentials such as broker passwords and API keys. It is off by default for that reason. Treat any response that includes `config` as sensitive.
{% endhint %}

Services report telemetry under an entity ID that comes from the service kind. Two services of the same kind on one device therefore collide unless you give each its own `DEVICE_EVENT_ENTITY_ID`. When that happens, the API lists the shared IDs in `signal_conflicts` and returns `status` as `null`, because it cannot tell which container sent the reading. A custom entity ID must use only letters, digits, hyphens, and underscores. The characters `.`, `/`, `*`, `~`, `[`, and `]` break the status cache, and the service then reports no status at all.

#### Service Metric Series

Returns one metric for one service over time, for charting.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/services/{serviceName}/series" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Device Groups

Group devices to find and manage them together (ex: every camera on one line).

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups/{groupId}" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups/{groupId}" method="patch" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups/{groupId}" method="delete" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

To add or remove a few devices, use these instead of sending the full member list to Update a Device Group.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups/{groupId}/devices" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/groups/{groupId}/devices" method="delete" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

### Device Management

These endpoints do from the API what the device page in the web app does. Delete and redeploy need a workspace API key, so a device cannot delete or reinstall itself with its own key.

#### Update a Device

Rename a device or set its environment variables.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}" method="patch" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Delete a Device

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}" method="delete" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Redeploy a Device

Use the new `installId` to reinstall Deployment Manager on the device, the same way as after [Create a Device](#create-a-device).

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/redeploy" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Apply Pending Config

On a device with [maintenance windows](/deployment/self-hosted/enterprise/deployment-manager/setting-up/setup-maintenance-windows.md), approved config changes can wait for the next window. Call this to request applying them now. On a production device in a Workspace with configuration approval enabled, approval can still hold the change.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/config/apply-pending" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Capture a Frame to a Project

Capture a stream's latest frame for training. A response with `status: "screening"` means the image is held for an upload screening verdict and is not yet in the project. The returned project details identify its requested destination.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/streams/{streamId}/capture" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Sample a Live Frame

Get a recent frame from a camera as an image URL (ex: to check what a camera sees, or to pass the image to a Workflow). If the stream has a frame less than 10 seconds old, you get it at once. If not, Roboflow asks the device for a new frame and waits up to `timeout_seconds`. The URL points to a copy of the frame, so it stays valid for an hour.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/streams/{streamId}/sample" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Snooze Alerts

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/{deviceId}/alerts/snooze" method="post" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

#### Fleet-Wide Reads

These read data across all devices in the workspace, so they need a workspace API key.

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/events" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/inference-versions" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/H5x9CDQa7dPNDXC9dDQe" path="/{workspace}/devices/v2/stream-options" method="get" %}
[deployment-manager.yaml](https://1583372177-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-9b0d6be80e77f89ad8551a33aff9ac8923e427f4%2Fdeployment-manager.yaml?alt=media)
{% endopenapi %}

## MCP Server

Connect an AI agent (ex: Claude, Cursor, ChatGPT, Codex) to the [Roboflow MCP Server](https://docs.roboflow.com/agents/mcp-server) and manage your devices by asking in plain language. The agent uses the same API as the web app, with your account's permissions.

{% hint style="info" %}
[Set up the Roboflow MCP Server](https://docs.roboflow.com/agents/mcp-server#adding-mcp) in a few minutes, then ask your agent about your devices.
{% endhint %}

With the MCP Server connected, your agent can:

* Check on your fleet: find offline devices, read logs and telemetry, and explain recent errors.
* Look through a camera: grab a live frame, see the scene, and test a Workflow on it before you deploy.
* Change a device: update its config, pin an inference version, or rename it, with maintenance windows respected.
* Run streams: add, pause, resume, trigger, or remove a stream, and restart a stuck camera's PoE port.
* Organize devices: create device groups and move devices between them.

Try asking:

* "Which of my devices are offline, and why?"
* "Show me what the loading dock camera sees right now."
* "Set inference to version 1.2.3 on every device in the Line 3 group."

See every device tool in the [MCP Server tool list](https://docs.roboflow.com/agents/mcp-server#devices-and-streams).
