> 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/ko/self-hosted/enterprise/deployment-manager.md).

# 배포 관리자

## 소개

Roboflow Deployment Manager를 사용하면 엣지 디바이스에서 컴퓨터 비전 모델을 쉽게 설정, 배포 및 관리할 수 있습니다. 모델을 학습하고 워크플로를 구축한 후에는 배포를 확장하기 위한 올인원 솔루션을 제공합니다.

Deployment Manager를 다음과 같이 사용할 수 있습니다:

1. 다음으로 새 디바이스를 설정할 수 있습니다: [Roboflow Inference 서버](/deployment/ko/self-hosted/self-hosted.md).
2. 배포에서 사용할 카메라 스트림을 구성합니다.
3. 배포 [워크플로](https://docs.roboflow.com/workflows) 엣지에서.
4. 배포된 엣지 디바이스의 로그, 스트림 상태, 텔레메트리를 모니터링합니다.

{% hint style="warning" %}
Deployment Manager는 Enterprise 고객에게만 제공됩니다. [Roboflow 영업팀에 문의하세요](https://roboflow.com/sales) 이 기능과 이를 사용해 대규모로 배포를 관리하는 방법에 대해 자세히 알아보세요.
{% endhint %}

<figure><img src="/files/bdd4b674e52ef8691d56754acee014a19e2d033d" alt=""><figcaption></figcaption></figure>

### 주요 요구 사항:

Deployment Manager는 Roboflow에서 지원하는 하드웨어용으로 만들어졌습니다:

* 지원됨: Roboflow를 통해 구매한 하드웨어
* 지원되지 않음(자체 책임 하에 사용): NVIDIA GPU가 있는 Debian 계열 Linux를 실행하는 NVIDIA Jetson, x86 머신
* 아직 지원되지 않음: Mac 또는 Windows 기반 시스템

디바이스는 설정 및 지속적인 운영을 위해 인터넷에 연결되어 있어야 하며, 원격 관리 및 모니터링을 위해 Roboflow에 지속적으로 액세스할 수 있어야 합니다.

### 엣지 서비스

Inference 서버와 함께 디바이스는 추가 Roboflow [서비스](/deployment/ko/self-hosted/enterprise/deployment-manager/services.md). 디바이스의 Configuration 탭에서 추가하고 구성할 수 있으며, 이에 대한 설명은 [디바이스 구성 업데이트](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md).

* [Event Store](/deployment/ko/self-hosted/enterprise/deployment-manager/services/event-store.md) 추론 이벤트를 디바이스에 저장하며, 자동 보관 및 선택적 클라우드 백업을 제공합니다.
* [OPC UA Server](/deployment/ko/self-hosted/enterprise/deployment-manager/services/opc-ua-server.md) PLCS 및 SCADA 시스템용 OPC UA 태그로 데이터를 게시합니다.
* [PLC Relay](/deployment/ko/self-hosted/enterprise/deployment-manager/services/plc-relay.md) Allen-Bradley, Modbus TCP 또는 Siemens S7을 통해 PLC 태그를 읽고 씁니다.
* [RTSP Simulator](/deployment/ko/self-hosted/enterprise/deployment-manager/services/rtsp-simulator.md) 업로드한 비디오 파일을 테스트용 RTSP 소스로 스트리밍합니다.

각 서비스는 디바이스 주소에서 자체 HTTP API를 제공합니다. 다음을 참조하세요. [서비스](/deployment/ko/self-hosted/enterprise/deployment-manager/services.md#using-the-apis) 공유하는 기본 URL, 인증 및 오류 형식 규칙은

## 가이드

### 설정하기

다음을 따르세요: [설정하기](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up.md) 디바이스를 온라인 상태로 만들고 Workflows를 실행하기 위해 가이드를 순서대로 따르세요.

| 가이드                                                                                                           | 설명                                      |
| ------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| [하드웨어 요구 사항](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/hardware-requirements.md)    | 지원되는 하드웨어, 카메라, 네트워크 및 아웃바운드 트래픽 요구 사항. |
| [디바이스 추가](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/add-a-device.md)                | 새 엣지 디바이스를 프로비저닝하고 계정에 등록합니다.           |
| [스트림 추가](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/add-a-stream.md)                 | Workflow를 실행하는 카메라 스트림을 구성합니다.          |
| [디바이스 알림 설정](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/set-up-device-alerts.md)     | 연결, 디스크 및 FPS 문제에 대한 이메일 알림을 활성화합니다.    |
| [유지보수 창 설정](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/setup-maintenance-windows.md) | 배포에 영향을 주는 변경 사항이 적용될 시간을 예약합니다.        |

### 변경하기

해당 [변경하기](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes.md) 가이드는 설정 후 디바이스와 스트림을 업데이트, 재구성 및 제거하는 방법을 다룹니다.

| 가이드                                                                                                                                 | 설명                                           |
| ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| [디바이스 구성 업데이트](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md)              | 디바이스 설정, 서비스 버전 및 추가 서비스를 관리합니다.             |
| [디바이스 네트워크 구성](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/configure-device-network.md)                 | 클라우드에서 IP 주소 지정, 게이트웨이, DNS 및 호스트명을 설정합니다.   |
| [AI1 카메라 설정 구성](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/configure-ai1-camera-settings.md)           | 노출, 게인, 초점 및 기타 AI1 카메라 설정을 실시간으로 조정합니다.     |
| [카메라에 고정 IP 설정](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/set-camera-static-ip.md)                    | GigE Basler 또는 Lucid 카메라에 영구적인 고정 IP를 할당합니다. |
| [PoE 포트 소프트 재설정](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/soft-reset-poe-port.md)                    | 멈춘 카메라 링크를 복구하기 위해 PoE 포트를 전원 재순환합니다.        |
| [스트림 일시 중지 및 재개](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/stop-a-stream.md)                          | 실행 중인 스트림을 일시적으로 중지했다가 나중에 재개합니다.            |
| [스트림 트리거](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/trigger-a-stream.md)                              | 트리거된 스트림에 대해 필요할 때 Workflow를 실행합니다.          |
| [스트림 종료](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/delete-a-stream.md)                                | 스트림과 해당 구성을 영구적으로 제거합니다.                     |
| [Deployment Manager 재배포](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/redeploy-deployment-manager.md)    | 장애 후 디바이스 구성을 복구합니다.                         |
| [디바이스 삭제](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/delete-a-device.md)                               | 더 이상 사용하지 않는 디바이스를 영구적으로 제거합니다.              |
| [Deployment Manager용 API 키](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/api-keys-for-device-manager.md) | 디바이스 API 키가 생성, 범위 지정 및 폐기되는 방식.             |

### 모니터링

해당 [모니터링](/deployment/ko/self-hosted/enterprise/deployment-manager/monitoring.md) 가이드는 스트림 상태, 로그, 리소스 및 Event Store 상태를 확인하는 방법을 보여줍니다.

| 가이드                                                                                                                 | 설명                                         |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| [스트림 보기](/deployment/ko/self-hosted/enterprise/deployment-manager/monitoring/view-a-stream.md)                      | 스트림의 상태, 최신 프레임 및 Workflow 세부 정보를 확인합니다.   |
| [디바이스 로그 보기](/deployment/ko/self-hosted/enterprise/deployment-manager/monitoring/view-device-logs.md)               | Roboflow 서비스의 로그를 검색, 필터링 및 다운로드합니다.       |
| [리소스 모니터 보기](/deployment/ko/self-hosted/enterprise/deployment-manager/monitoring/view-the-resource-monitor.md)      | 디스크, 메모리, CPU, GPU 및 서비스 컨테이너 상태를 모니터링합니다. |
| [Event Store 상태 보기](/deployment/ko/self-hosted/enterprise/deployment-manager/monitoring/view-event-store-status.md) | Event Store 사용량, 백업 진행 상황 및 기록을 모니터링합니다.   |

## HTTP API

Deployment Manager API를 사용하면 Roboflow Deployment Manager(RFDM) 디바이스를 프로그래밍 방식으로 모니터링하고 관리할 수 있습니다.

모든 엔드포인트는 다음 아래에 마운트됩니다: `/:workspace/devices/v2` 공개 API 호스트(`https://api.roboflow.com`). 읽기 엔드포인트에는 [범위가 지정된 API 키](https://docs.roboflow.com/reference/authentication/authentication/scoped-api-keys) 와 `device:read` 스코프가 필요합니다. 디바이스를 변경하는 엔드포인트에는 `device:update`. 명시적 스코프 목록이 없는 워크스페이스 API 키에는 모든 스코프가 암묵적으로 부여됩니다(레거시 동작). 명시적 `scopes` 배열에는 관련 스코프가 포함되어야 합니다.

Deployment Manager API를 사용하면 다음을 수행할 수 있습니다:

* [디바이스 목록 조회 및 가져오기](#list-and-get-devices)
* [디바이스 생성](#create-a-device)
* [디바이스 구성](#device-config)
* [디바이스 명령](#device-commands)
* [디바이스 스트림](#device-streams)
* [디바이스 로그 및 텔레메트리](#device-logs-and-telemetry)
* [디바이스 이벤트](#device-events)
* [디바이스 서비스](#device-services)

선택적 엣지 서비스(Event Store, PLC Relay, RTSP Simulator, OPC UA Server)는 다음을 통해서가 아니라 디바이스 주소에서 자체 HTTP API를 제공합니다: `api.roboflow.com`. 이들은 Roboflow API 키를 받지 않으며, 인증 및 오류 형식도 아래의 다른 항목들과 다릅니다. 다음을 참조하세요: [서비스](/deployment/ko/self-hosted/enterprise/deployment-manager/services.md#using-the-apis).

### 인증

모든 엔드포인트는 다음 중 하나를 통해 워크스페이스 API 키를 받습니다:

* 쿼리 문자열: `?api_key=YOUR_API_KEY`
* 헤더: `Authorization: Bearer YOUR_API_KEY`

#### 디바이스 범위 API 키

특정 디바이스용으로 발급된 API 키(예: 설치 중 RFDM에 의해)는 해당 디바이스로 범위가 좁혀집니다. 이 키는 `:deviceId` 경로 매개변수가 키에 바인딩된 디바이스와 일치하는 라우트만 호출할 수 있습니다. 이들은 **403** 워크스페이스 전체 목록 및 생성 엔드포인트와, 일치하지 않는 `:deviceId` 모든 경로에서 이를 받습니다.

### 워크스페이스 간 격리

워크스페이스 API 키는 자신의 워크스페이스에 속한 디바이스만 읽거나 수정할 수 있습니다. 다른 워크스페이스가 소유한 디바이스 ID에 대한 요청은 **404**ID가 다른 면에서 유효하더라도 반환됩니다.

### 오류

| 상태  | 의미                                                                                                                                                       |
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400 | 잘못된 쿼리 매개변수(알 수 없는 `time_period`, 잘못된 커서 또는 날짜, 잘못된 `direction` 등) 또는 잘못된 요청 본문.                                                                         |
| 401 | API 키가 없거나 유효하지 않습니다.                                                                                                                                    |
| 403 | 다른 디바이스를 대상으로 하는 디바이스 범위 API 키, 워크스페이스 전체 목록/생성 라우트, 복제 중 다른 워크스페이스의 소스 디바이스, 또는 기능 제한으로 거부된 요청(예: AI1 생성 또는 `offline_mode` 오프라인 모드가 워크스페이스에서 활성화되지 않음). |
| 404 | 디바이스, 스트림, 구성 또는 소스 디바이스를 찾을 수 없습니다. 다른 워크스페이스가 소유한 디바이스 ID에 대한 읽기 요청도 404를 반환합니다.                                                                       |
| 429 | 요청 한도를 초과했습니다. 로그는 IP당 분당 5개 요청, 전체적으로는 분당 50개 요청으로 제한됩니다. 텔레메트리 읽기는 디바이스당 분당 60개 요청으로 제한되며, 10초 동안 10개 요청의 버스트가 허용됩니다.                                  |

오류 응답은 다음 두 가지 형식 중 하나를 사용합니다:

* 핸들러 수준 오류(보통 핸들러 자체에서 발생하는 400, 403, 404, 429)는 다음을 반환합니다: `{ "error": "<message>" }`.
* 인증 및 워크스페이스 검증 실패(보통 401)는 구조화된 `error` 객체: `{ "error": { "message": "...", "status": 401, "type": "OAuthException", "hint": "..." } }`.

로그 속도 제한기는 트리거될 때 추가로 일반 문자열 본문(JSON 아님)을 반환합니다: **429**.

### 디바이스 목록 조회 및 가져오기

#### 디바이스 목록 조회

워크스페이스에 등록된 모든 디바이스를 나열합니다. 디바이스 범위 API 키는 이 엔드포인트를 호출할 수 없으며 **403**.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2?api_key=$ROBOFLOW_API_KEY"
```

**예시 응답**

```json
{
  "data": [
    {
      "id": "abc123",
      "name": "factory-floor-cam-1",
      "status": "online",
      "last_heartbeat": "2026-04-28T12:00:00.000Z",
      "platform": "Linux",
      "platform_release": "5.10.104-tegra",
      "platform_version": "#1 SMP PREEMPT ...",
      "architecture": "aarch64",
      "hostname": "jetson-01",
      "rfdm_version": "1.2.3",
      "type": "jetson",
      "hardware": {
        "processor": "aarch64",
        "gpu": null,
        "total_memory_mb": null,
        "total_disk_space_mb": 124426534912
      },
      "tags": ["production", "line-3"],
      "created_at": "2026-01-15T08:30:00.000Z"
    }
  ]
}
```

해당 `status` 필드는 `온라인` 최근 5분 이내에 하트비트가 수신되었다면, `오프라인` 더 오래되었다면, 또는 `알 수 없음` 하트비트가 한 번도 기록되지 않았다면. 새로 프로비저닝된 디바이스는 첫 하트비트 전에 목록에 나타나며, 그 전까지는 `status` 는 `알 수 없음` 그리고 모니터링에서 파생된 대부분의 필드는 `null`.

{% hint style="warning" %}
`hardware.total_disk_space_mb` 은 디바이스가 보고한 원시 값입니다. 그런데도 `_mb` 접미사에도 불구하고, RFDM에서 보고된 디바이스는 현재 이 값을 바이트 단위로 반환합니다(예: `124426534912` 약 124GB 디스크의 경우). 단위는 디바이스 정의로 취급하세요.
{% endhint %}

#### 디바이스 가져오기

ID로 단일 디바이스를 가져옵니다. 다음을 반환합니다 **404** 디바이스가 존재하지 않거나 다른 워크스페이스에 속한 경우.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}?api_key=$ROBOFLOW_API_KEY"
```

응답 본문은 목록 엔드포인트의 단일 항목과 일치합니다( `data` 배열로 감싸지 않습니다).

### 디바이스 생성

워크스페이스에 새 디바이스를 만들고 설치에 필요한 식별자를 반환합니다. 디바이스 범위 API 키는 이 엔드포인트를 호출할 수 없으며 **403**.

**필수 스코프:** `device:update`

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

**예시 요청**

```bash
curl -X POST "https://api.roboflow.com/{workspace}/devices/v2?api_key=$ROBOFLOW_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{"device_name": "factory-floor-cam-2", "device_type": "edge"}'
```

**예시 응답**

```json
{
  "deviceId": "abc456",
  "installId": "inst_xyz789"
}
```

반환된 `installId` 를 사용해 Roboflow Deployment Manager 설치 프로그램으로 디바이스를 부트스트랩하세요.

#### AI1 디바이스에 대한 참고 사항

* 설정 `device_type` 을 `"ai1"` 로 설정하려면 워크스페이스에 `deviceAio` 기능이 활성화되어 있어야 하며, 그렇지 않으면 요청은 **403**.
* `offline_mode` 은 다음이 있는 워크스페이스의 AI1 디바이스에만 유효합니다: `roboflowLiteMode`. 다른 조합은 다음을 반환합니다: **400** 또는 **403**.
* 기존 디바이스를 복제하지 않고 `workflow_id`, 슬러그화된 `device_name` 에는 영숫자 문자가 하나 이상 포함되어야 하며, 그렇지 않으면 요청은 **400**.
* AI1 + 오프라인 모드가 적용되면 응답에는 또한 `offlineProvisioningQrPayload` 오프라인 프로비저닝용 QR 페이로드를 인코딩하는 필드가 포함됩니다.

#### 복제에 대한 참고 사항

다음이 제공되면 `sourceDeviceId` 가 제공되면 새 디바이스는 소스 디바이스 구성의 복사본에서 생성됩니다. 소스 디바이스는 요청과 동일한 워크스페이스에 속해야 하며, 그렇지 않으면 요청은 **403**. 존재하지 않는 `sourceDeviceId` 은 다음을 반환합니다: **404**.

### 디바이스 구성

#### 워크스페이스 기본 구성 가져오기

워크스페이스 수준의 기본 디바이스 구성을 반환합니다. 이는 워크스페이스의 구성 패치(있는 경우)가 병합된 기본 구성입니다. 새 디바이스를 프로비저닝할 때 다음을 호출하기 전에 템플릿으로 사용하세요: `POST /:workspace/devices/v2`.

**필수 스코프:** `device:read`

{% hint style="info" %}
이것은 워크스페이스 전체 엔드포인트입니다. 디바이스 범위 API 키는 **403** 를 받게 됩니다. 경로에 `:deviceId` 가 없기 때문입니다.
{% endhint %}

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/default-config?api_key=$ROBOFLOW_API_KEY"
```

**예시 응답**

```json
{
  "config": {
    "version": "1.0.0",
    "config": {
      "inference": { "confidence": 0.7, "threshold": 0.3 },
      "device_type": "edge"
    },
    "services": {}
  },
  "patch": {
    "config": {
      "inference": { "confidence": 0.7 }
    }
  }
}
```

* `config` -- 병합된 결과(기본값 + 워크스페이스 패치).
* `patch` -- 워크스페이스에 저장된 패치입니다. 빈 객체 `{}` 는 워크스페이스에 사용자 지정 패치가 없으면.

#### 구성 가져오기

디바이스의 현재 런타임 구성을 반환합니다. 응답 형식은 Roboflow Deployment Manager(RFDM) 구성 사양을 따릅니다.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/config?api_key=$ROBOFLOW_API_KEY"
```

응답은 전체 구성 문서이며 다음 최상위 필드를 포함합니다(이에 국한되지 않음):

* `device_id`, `device_name`
* `workspace_id`
* `version`, `last_updated`, `last_updated_at`, `created_at`
* `config` (디바이스의 런타임 구성 트리로, 다음을 포함합니다: `device_type`, `stream`, 그리고 `offline_mode`)
* `services` (서비스별 컨테이너 정의로, 다음을 포함합니다: `image`, `volumes`, 그리고 `environment_variables`)
* `environment_variables` (서비스별 변수 외에 최상위 환경 변수도 포함됩니다: `services`)
* `production_mode`, `last_automatic_update`, `updated`, `updated_by`, `$schema`, `id`

RFDM이 작성한 추가 필드가 나타날 수도 있습니다. 응답 형식은 확장 가능한 것으로 간주하고 필요한 필드에만 의존하세요.

다음을 반환합니다 **404** 디바이스가 존재하지 않거나 워크스페이스에 속하지 않거나, 해당 디바이스에 저장된 구성이 없으면.

{% hint style="warning" %}
응답에는 작성된 전체 구성이 포함됩니다. 서비스별 `environment_variables` 및 구성에 포함된 모든 통합 자격 증명은 마스킹되지 않은 상태로 반환됩니다. 응답 본문은 민감한 정보로 취급하고 평문으로 로그에 남기지 마세요.
{% endhint %}

#### 구성 기록

디바이스의 이전 구성 개정을 최신순으로 나열합니다.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/config/history?api_key=$ROBOFLOW_API_KEY&limit=10"
```

**예시 응답**

```json
{
  "data": [
    {
      "revision_id": "rev_abc",
      "created_at": "2026-04-20T14:30:00.000Z",
      "created_by": "user_123"
    }
  ],
  "pagination": {
    "next_cursor": "...",
    "has_more": true,
    "limit": 10
  }
}
```

잘못된 `커서` 은 다음을 반환합니다: **400** 과 함께 `{"error": "Invalid cursor format"}`.

### 디바이스 명령

웹 앱에서 시작한 작업(예: 디바이스 다시 시작, 스트림 일시 중지, 카메라 검색)은 명령으로 대기열에 추가됩니다. 디바이스는 다음 폴링 시 이를 가져갑니다.

#### 대기 중인 명령 가져오기

디바이스를 기다리는 명령을 가장 오래된 것부터 반환합니다. 읽는다고 해서 제거되지는 않습니다. 명령은 디바이스가 실행했다고 보고할 때까지 대기열에 남아 있으므로, 명령 실행 도중 재시작된 디바이스는 이를 다시 보게 됩니다. 5분 이상 전에 대기열에 추가된 명령은 만료되어 전달되지 않습니다. 나중에 실행하면 요청한 내용과 일치하지 않기 때문입니다.

**필수 스코프:** `device:read`

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

#### 명령 대기열에 추가

디바이스가 다음 폴링에서 실행할 명령을 대기열에 추가합니다. 이는 웹 앱에서 디바이스를 다시 시작하거나 스트림을 시작할 때 하는 작업을 API로 수행하는 것입니다.

**필수 스코프:** `device:update`

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

### 디바이스 스트림

#### 스트림 목록 조회

장치에 구성된 모든 스트림을 나열합니다.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/streams?api_key=$ROBOFLOW_API_KEY"
```

**예시 응답**

```json
{
  "data": [
    {
      "id": "stream_abc",
      "name": "entrance-cam",
      "status": "running",
      "pipeline_id": "pipe_123",
      "workflow_id": "wf_456",
      "source": "rtsp://192.168.1.100:554/live",
      "started_at": "2026-04-28T10:00:00.000Z",
      "last_event_at": "2026-04-28T12:30:00.000Z",
      "camera_fps": 29.97,
      "inference_fps": 12.4,
      "sharpness": 82,
      "error": null,
      "error_code": null,
      "error_message": null,
      "error_retryable": null
    }
  ]
}
```

**스트림 오류**

스트림이 실패하면, `error_code`, `error_message`, 그리고 `error_retryable` 실패를 설명합니다. 이 값들은 가장 최근의 스트림 상태 이벤트에서 오므로, 스트림이 복구되면 지워집니다. `error_code` 자신의 코드에서 분기 처리하는 데 사용하고, `error_retryable` 장치가 스트림을 자체적으로 재시도하는지 확인하는 데 사용합니다. 이전의 `error` 필드는 호환성을 위해 유지됩니다.

**소스 정리**

해당 `source` 필드는 반환되기 전에 항상 정리 과정을 거칩니다:

* 소스가 URL이면, 다음의 모든 항목은 `userinfo` (`scheme://user:pass@host/...`)은 제거됩니다. 예를 들어, `rtsp://admin:password@192.168.1.100:554/live` 다음과 같이 됩니다 `rtsp://192.168.1.100:554/live`.
* 소스가 객체인 경우, 소문자 이름이 다음인 키는 `password`, `passwd`, `secret`, `api_key`, `apikey`, `auth`, `authorization`, `token`또는 `access_token` 은 응답에서 제외됩니다. 나머지 모든 키는 유지됩니다.
* 배열과 중첩 객체는 재귀적으로 정리됩니다.

#### 스트림 가져오기

단일 스트림을 가져옵니다. 다음을 반환합니다 **404** 스트림이 장치에 존재하지 않거나, 장치가 존재하지 않거나, 해당 장치가 작업공간에 속하지 않으면

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/streams/{streamId}?api_key=$ROBOFLOW_API_KEY"
```

응답 본문은 목록 엔드포인트의 단일 항목과 일치합니다( `data` 배열로 감싸지 않습니다).

#### 파이프라인 상태 보고

장치가 실행 중인 추론 파이프라인을 보고합니다. 보고된 각 파이프라인은 FPS 및 선명도 메트릭과 함께 일치하는 스트림을 업데이트합니다. 장치 구성에 선언된 스트림은 스트림 키로 매칭되므로, 장치가 이를 보고하면 프로비저닝 중으로 표시되지 않게 됩니다.

RFDM은 device-manager 컨테이너 없이 실행되는 장치에 이것을 게시합니다. 해당 컨테이너를 실행하는 장치는 healthcheck에서 동일한 데이터를 보고하므로 이 엔드포인트가 필요하지 않습니다.

**필수 스코프:** `device:update`

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

추론 서버의 다음도 게시할 수 있습니다 `/inference_pipelines/list` 응답을 그대로 다음처럼 전달할 수 있습니다: `{"success": true, "data": {"pipelines": [...]}}`. 해당 본문에 `"success": false`가 포함되어 있으면, 장치가 파이프라인 목록을 가져오지 못한 것이므로, 요청은 아무 작업도 하지 않으며 기존 스트림은 그대로 둡니다.

### 디바이스 로그 및 텔레메트리

#### 로그

페이지로 나뉜 장치 로그를 반환합니다.

**필수 스코프:** `device:read`

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

**예시 요청**

**요청 제한:** 작업공간당 분당 120회 요청. 로그 읽기와 로그 수집은 별도의 속도 제한 버킷을 사용하므로, 로그 폴링은 수집 할당량에 영향을 주지 않습니다(반대도 마찬가지입니다).

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/logs?api_key=$ROBOFLOW_API_KEY&limit=50"
```

**예시 응답**

```json
{
  "data": [
    {
      "timestamp": "2026-04-28T12:01:00.000Z",
      "service": "inference",
      "severity": "INFO",
      "message": "Model loaded successfully"
    }
  ],
  "pagination": {
    "next_cursor": "2026-04-28T12:01:00.000Z",
    "has_more": true,
    "limit": 50
  }
}
```

**속도 제한**

이 엔드포인트의 요청 제한은 **IP 주소당 분당 5회 요청** 및 **전역적으로 분당 50회 요청**. 초과 요청은 **429**.

#### 원격 측정

고정된 시간 구간에 걸쳐 버킷화된 장치의 집계 하드웨어 메트릭(CPU, 메모리, 디스크, GPU)과 스트림별 FPS를 반환합니다.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/telemetry?api_key=$ROBOFLOW_API_KEY&time_period=24h"
```

버킷 크기는 시간 기간마다 고정됩니다:

| `time_period` | `bucket_interval` | `fill_interval_seconds` |
| ------------- | ----------------- | ----------------------- |
| `1h`          | `2 MINUTE`        | 120                     |
| `24h`         | `30 MINUTE`       | 1800                    |
| `7d`          | `4 HOUR`          | 14400                   |
| `14d`         | `8 HOUR`          | 28800                   |

**예시 응답**

```json
{
  "time_period": "24h",
  "bucket_interval": "30 MINUTE",
  "fill_interval_seconds": 1800,
  "buckets": [
    {
      "bucket_start": "2026-04-28T00:00:00.000Z",
      "cpu_pct": 42.5,
      "used_memory_mb": 3200,
      "total_memory_mb": 7860,
      "used_disk_space_mb": 15000,
      "total_disk_space_mb": 29000,
      "gpu_pct": 78.2
    }
  ]
}
```

요청된 시간 창에서 텔레메트리가 수신되지 않은 버킷도 각 메트릭 필드가 `null`.

**속도 제한**

이 엔드포인트는 장치당 다음의 요청 제한이 적용됩니다 **분당 60회 요청** 에 더해 **10초당 10회 요청** 의 버스트 제한이 있습니다. 초과 요청은 **429**을 반환합니다. 동일한 장치별 원격 측정 할당량은 장치의 원격 측정 수집 경로와 공유되므로, 악의적인 읽기가 같은 장치의 수집에 영향을 줄 수 있습니다.

### 디바이스 이벤트

장치와 스트림의 라이프사이클 이벤트(예: 장치 부팅, 스트림 시작 및 중지, 오류, 구성 변경)를 반환합니다.

**필수 스코프:** `device:read`

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

**예시 요청**

```bash
curl "https://api.roboflow.com/{workspace}/devices/v2/{deviceId}/events?api_key=$ROBOFLOW_API_KEY&limit=50"
```

**예시 응답**

```json
{
  "data": [
    {
      "id": "evt_abc123",
      "event": "device.boot",
      "entity_type": "device",
      "entity_id": "abc123",
      "event_description": "장치가 시작되었습니다",
      "error_code": null,
      "metadata": { "source": "boot-loop" },
      "device_timestamp": "2026-04-28 10:00:00",
      "server_timestamp": "2026-04-28 10:00:01",
      "event_end_timestamp": null
    }
  ],
  "pagination": {
    "next_cursor": "...",
    "prev_cursor": "...",
    "has_more": true,
    "limit": 50
  }
}
```

해당 `device_timestamp`, `server_timestamp`, 그리고 `event_end_timestamp` 필드는 다음 형식으로 포맷됩니다 `YYYY-MM-DD HH:MM:SS[.SSS]` UTC 기준입니다. 이 API의 다른 타임스탬프처럼 ISO-8601으로 정규화되지는 않습니다.

`event_end_timestamp` 이벤트에 기록된 종료 타임스탬프가 없을 때는 epoch-zero 문자열로도 반환될 수 있습니다 `"1970-01-01 00:00:00.000"` (대신 `null`)이 반환됩니다.

기본적으로 피드는 반복 이벤트를 상태 변경으로 합쳐서, 하나의 이벤트 이름을 재사용하는 주기적 텔레메트리를 숨깁니다. `dedupe=false` 와 함께 `entity_type` 및 `entity_id` 의 모든 원시 행을 읽을 수 있습니다. 시간에 따른 하나의 값을 차트로 그리려면 [서비스 시리즈 엔드포인트](#device-services) 를 대신 사용하세요. 엔티티 ID를 대신 확인해 줍니다.

### 디바이스 서비스

다음을 반환합니다 [services](/deployment/ko/self-hosted/enterprise/deployment-manager/services.md) 장치가 실행 중인 서비스는 라이브 상태와 결합되어 반환됩니다: 컨테이너 상태, 이미지 버전, 그리고 PLC 연결 상태나 Event Store 용량 같은 종류별 상태.

**필수 스코프:** `device:read`

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

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

이 엔드포인트들을 사용해 여러 장치를 폴링하세요: 다음을 요청하고 `include=status` 서비스가 올라와 있고 보고 중인지 확인한 뒤, 다음을 추가합니다 `include=metrics` 로 CPU와 메모리를 확인합니다.

{% hint style="info" %}
`include=config` 는 저장된 그대로 환경 변수 값을 반환하며, 여기에는 브로커 비밀번호와 API 키 같은 자격 증명이 들어 있는 경우가 많습니다. 이런 이유로 기본적으로 꺼져 있습니다. 다음을 포함하는 응답은 모두 민감한 정보로 취급하세요 `config` 를 민감한 정보로 취급하세요.
{% endhint %}

서비스는 서비스 종류에서 비롯된 엔티티 ID 아래에 텔레메트리를 보고합니다. 따라서 하나의 장치에서 같은 종류의 서비스 두 개는 각각 고유한 `DEVICE_EVENT_ENTITY_ID`가 없으면 충돌합니다. 이런 경우 API는 공유 ID를 다음에 나열합니다 `signal_conflicts` 를 반환하고 `status` 다음처럼 `null`, 읽기를 보낸 컨테이너를 구분할 수 없기 때문입니다. 사용자 지정 엔티티 ID에는 문자, 숫자, 하이픈, 밑줄만 사용할 수 있습니다. 다음 문자는 `.`, `/`, `*`, `~`, `[`, 그리고 `]` 상태 캐시를 깨뜨리며, 그러면 서비스는 상태를 전혀 보고하지 않습니다.

#### 서비스 메트릭 시리즈

차트 작성을 위해 하나의 서비스에 대한 하나의 메트릭을 시간 경과에 따라 반환합니다.

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

메트릭 이름은 서비스 종류에 따라 다릅니다. 알 수 없는 `메트릭` 으로 호출하면 400 응답이 유효한 이름을 다음에 나열합니다 `valid_values`.

<table data-search="false"><thead><tr><th width="220">서비스 종류</th><th>메트릭</th></tr></thead><tbody><tr><td><code>event_store</code></td><td><code>records</code>, <code>records_percent</code>, <code>images</code>, <code>bytes_used</code>, <code>bytes_percent</code>, <code>backed_up_records</code>, <code>backed_up_bytes_percent</code>, <code>pending_records</code>, <code>pending_bytes</code>, <code>draft_records</code>, <code>oldest_draft_age_seconds</code>, <code>disk_percent_used</code></td></tr><tr><td><code>plc_relay</code></td><td><code>connected</code></td></tr><tr><td><code>opcua_server</code></td><td><code>session_count</code>, <code>refused_total</code></td></tr><tr><td><code>rtsp_simulator</code>, <code>device_hmi</code>, <code>custom</code></td><td>없음. 이것들은 컨테이너 상태와 메트릭만 보고합니다.</td></tr></tbody></table>

## MCP 서버

AI 에이전트를 다음에 연결하면 [MCP 서버](https://docs.roboflow.com/agents/mcp-server) 다음 도구로 엣지 장치를 확인할 수 있습니다:

<table data-search="false"><thead><tr><th width="290">도구</th><th>설명</th></tr></thead><tbody><tr><td><code>devices_list</code></td><td>작업공간에 등록된 장치를 나열합니다.</td></tr><tr><td><code>devices_get_snapshot</code></td><td>한 번의 호출로 장치의 현재 전체 상태를 가져옵니다.</td></tr><tr><td><code>devices_get_config</code></td><td>장치의 현재 실행 시점 구성을 가져옵니다.</td></tr><tr><td><code>devices_update_config</code></td><td>장치의 실행 시점 구성을 업데이트합니다.</td></tr><tr><td><code>devices_streams_list</code></td><td>장치에 구성된 스트림을 나열합니다.</td></tr><tr><td><code>devices_get_logs</code></td><td>장치 로그를 가져옵니다.</td></tr><tr><td><code>devices_get_telemetry</code></td><td>집계된 하드웨어 메트릭과 장치 상태를 가져옵니다.</td></tr></tbody></table>
