{
  "openapi": "3.1.0",
  "info": {
    "title": "MQcentral API",
    "version": "v2",
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    },
    "description": "Provides endpoints to access and manage MachineQ *Resources* and *Devices*. Version 2 delivers performative APIs designed for scale and flexibility.\n"
  },
  "servers": [
    {
      "url": "https://api.machineq.net",
      "description": "Production MachineQ API Server"
    },
    {
      "url": "https://api.preview.machineq.net",
      "description": "Preview MachineQ API Server"
    },
    {
      "url": "https://api.dev.machineq.net",
      "description": "Development MachineQ API Server"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Devices",
      "description": "Select endpoints for the _Devices_ API are available in the V2 release. All other APIs continue to use the v1 designation until updated to v2. The V1 _Devices_ API remains available for backwards compatibility.\n\nResults from these endpoints are streamed. After calculating the `meta` section, the server begins streaming results per _Device_ as the query completes. Streaming enables faster response times for customers with large fleets.\n\nStatistics fields are included at the top-level of each record for easier querying.\n\n_Groups_ are included in each record to support fleet management and filtering.\n"
    },
    {
      "name": "Overview",
      "description": "The MachineQ output system connects MQcentral to client applications by delivering IoT device data and platform operation information. Output is primarily delivered via push mechanisms to configured *Destinations*.\n\n*Destinations* include:\n  - Webhooks\n  - MQTT\n  - Popular cloud solutions including AWS (IoTCore) and Azure (IoTHub)\n\nPlatform operation information is delivered via *Output Alert Events*. When a *Gateway* or *Device* configured with an *Output Alert* meets the alert condition (such as \"gateway online/offline\"), an *Output Alert Event* is delivered to all configured *Destinations*.\n",
      "x-traitTag": true
    },
    {
      "name": "Output Credentials",
      "description": "*Output Credentials* specify the access criteria used when delivering data to *Output Destinations*."
    },
    {
      "name": "Output Destinations",
      "description": "*Output Destinations* define the client-side collector of data emitted from the MQcentral platform.\n\nMost *Output Destinations* require credentials so that the MachineQ output system can establish an authenticated connection.\nAn *Output Credentials* association varies depending on the type of *Output Destination*:\n\n- `webhook` *Output Destinations* typically use `basic_auth` or `client_credentials` credentials. \n- `mqtt` *Output Destinations* typically use `basic_auth` credentials.\n- `aws_iot_core` *Output Destinations* use `x509_certificate` credentials.\n- `azure_iot_hub` *Output Destinations* use `azure_shared_access_policy` credentials.\n"
    },
    {
      "name": "Output Alerts",
      "description": "*Output Alerts* define the relationship between data produced by physical IoT infrastructure and the rules that govern an alert condition."
    },
    {
      "name": "Output Events",
      "description": "*Output Events* are produced by the MachineQ output system when an *Output Alert* rule triggers\nbased on the current state of a specified device or gateway.\n"
    },
    {
      "name": "Device Configuration",
      "description": "Provides endpoints to read and manage device configurations.\n\n## Codec support\n\nNot all devices support remote configuration — support depends on the device's codec.\nIf the device's codec does not support config encoding, `PUT` will return `400`. Use\n`GET` to check whether a device has ever had a desired config applied.\n\n## Rollout lifecycle\n\nWhen a desired config is submitted via PUT, a **rollout** is created and the first\nfragment is dispatched asynchronously as a LoRaWAN downlink — typically within\nseconds, but callers should not assume immediate delivery. Subsequent fragments are\nsent one at a time after each preceding fragment is confirmed. The rollout moves\nthrough the following statuses:\n\n| Status        | Description |\n|---------------|-------------|\n| `pending`     | Briefly transitional — rollout accepted but first fragment not yet scheduled for transmission. Rarely visible in practice. |\n| `in_progress` | First fragment scheduled for transmission; delivery underway |\n| `applied`     | All fragments confirmed |\n| `failed`      | A fragment failed after exhausting retries |\n| `cancelled`   | Cancelled via DELETE before completion |\n\n## Fragment lifecycle\n\nEach fragment within a rollout transitions independently:\n\n| Status      | Description |\n|-------------|-------------|\n| `pending`             | Not yet scheduled for transmission — either the rollout was just accepted or a prior fragment is still being confirmed |\n| `ready`               | Scheduled for the next transmission attempt |\n| `queued`              | Submitted to the network server |\n| `sent`                | Network server confirmed gateway transmission |\n| `confirmed`           | Device acknowledged (strategy-dependent) |\n| `gateway_unavailable` | No connected gateway can reach the device; fragment is suspended and will resume automatically when device activity is observed |\n| `failed`              | Delivery failed after retry exhaustion |\n| `cancelled`           | Cancelled before confirmation |\n\n## Confirmation strategies\n\nThe codec determines which strategy is used:\n\n- **`downlink-sent`** — fragment confirmed when the network server reports successful\n  gateway transmission.\n- **`uplink-ack`** — fragment confirmed when the device sends a LoRaWAN acknowledged\n  uplink in response to the downlink. Some device types additionally require the device\n  to echo the configuration back in a specific response message before the fragment is\n  considered confirmed.\n- **`reported-config`** — rollout applied when every parameter in the desired\n  configuration is present in the device's reported configuration with the same value.\n  The device may report additional parameters beyond those being set. Used for devices\n  that report their configuration across multiple successive uplinks rather than in a\n  single response. Only single-fragment rollouts are supported."
    },
    {
      "name": "Device Labels",
      "description": "*Device Labels* are arbitrary `key`/`value` metadata attached to a device. A label selector matches against them to address a whole fleet of devices at once instead of one device at a time.\n\n## Key and value rules\n\nKeys and values are both strings. Keys are the canonical selector dimension: 1 to 63 characters drawn from `[a-z0-9._-]`, starting and ending with a letter or digit, and lowercased on write. Values carry display-quality text: 1 to 128 characters, spaces and mixed case allowed, stored as supplied. Both are trimmed of surrounding whitespace. A device holds at most one value per key.\n\n## Selectors\n\nA selector is a list of requirements that a device must satisfy in full. Each requirement names one label key and the value or values that key may hold: `eq` matches a single exact value, and `in` matches any one of several. Requirements combine with AND, so a device matches only when every requirement holds, and a key may appear in only one requirement.\n\nThis selector matches production devices running either of two firmware versions. Post it to `/v2/devices/labels:search` to see the devices it matches:\n\n```json\n{\n  \"selector\": [\n    {\n      \"key\": \"env\",\n      \"operator\": \"eq\",\n      \"values\": [\"prod\"]\n    },\n    {\n      \"key\": \"firmware\",\n      \"operator\": \"in\",\n      \"values\": [\"1.2.0\", \"1.2.1\"]\n    }\n  ]\n}\n```\n\n## Managing labels\n\nThe label map is addressed as a whole: read it, replace it (`PUT`), merge keys into it (`PATCH`), or clear it (`DELETE`). A single key is removed through `DELETE /v2/devices/{dev_eui}/labels/{key}`. Every operation returns the device's resulting label map, so no follow-up read is needed.\n"
    },
    {
      "name": "Labels",
      "description": "*Labels* are the shared vocabulary of `key`/`value` metadata in use across labeled entities. These endpoints report the distinct keys, and the distinct values for a given key, so selector builders and type-ahead pickers can offer what already exists.\n\nThe vocabulary is shared across entity types rather than partitioned by one, so a key first attached to a device is offered when labeling any other entity. Managing the labels themselves lives under the entity that carries them (see *Device Labels*).\n"
    },
    {
      "name": "Device Configuration Policies",
      "description": "*Device Configuration Policies* apply one device configuration to every device a label selector matches, so a fleet is configured by intent rather than device by device. A policy pairs a selector with a codec and the configuration to apply, and the devices it reaches change as labels change. \n\n### Matching\n\nA device must meet two conditions to match a policy: satisfy all requirements in the policy’s selector and use the matching codec_id. Devices with the correct labels but a different codec are excluded, as configurations only work with their specific codec. To preview which devices a selector will reach before creating a policy, use the POST /v2/devices/labels:search endpoint. \n\n### Priority\n\nWhen multiple policies match a single device, the priority integer (defaulting to 0) determines which one takes effect. The highest priority wins, while lower-priority policies stand down. A policy that stands down still reports the device, with a status of superseded and the winning policy in superseded_by_policy_id, so you can see which policy took it. Giving two matching policies the same priority is a misconfiguration rather than an error. One policy is still selected as the winner and continues to apply to the device on each evaluation. The selection is deterministic but is not based on a configurable policy attribute, so do not rely on it. Set distinct priorities whenever two policies can match the same device. \n\n### Lifecycle\n\nNew policies are created disabled by default to allow for safe review of the selector, configuration, and priority. Use POST /v2/device_config_policies/{policy_id}:enable to activate a policy and :disable to turn it off. Status is read-only on the entity itself; while a PUT request can echo the current status to support standard read-edit-write workflows, attempting to change it will fail. Disabling or deleting a policy prevents it from updating any new devices, but any configuration already deployed to a device remains intact."
    }
  ],
  "paths": {
    "/v2/devices": {
      "get": {
        "tags": [
          "Devices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/fieldMaskParam"
          },
          {
            "$ref": "#/components/parameters/limitParam"
          },
          {
            "$ref": "#/components/parameters/pageParam"
          },
          {
            "$ref": "#/components/parameters/orderParam"
          },
          {
            "$ref": "#/components/parameters/qParam"
          }
        ],
        "summary": "Retrieves a list of devices",
        "description": "Returns all *Devices* for the authenticated account. Supports filtering, pagination, field selection, and sorting via query parameters.",
        "operationId": "GetDevices",
        "responses": {
          "200": {
            "description": "Successful response containing the device list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetDevicesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter supplied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "code": 3,
                  "message": "invalid field mask parameter: id"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}": {
      "get": {
        "tags": [
          "Devices"
        ],
        "summary": "Retrieves a device by DevEUI",
        "description": "Returns the *Device* identified by the given device EUI.",
        "operationId": "GetDevice",
        "parameters": [
          {
            "name": "dev_eui",
            "in": "path",
            "description": "Extended Unique Identifier of the device.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing the device",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Device"
                }
              }
            }
          },
          "400": {
            "description": "Invalid DevEUI format",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "code": 3,
                  "message": "invalid field DevEui: value 'INVALID' must be a string conforming to regex ^[A-Fa-f0-9]{16}$"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/config": {
      "get": {
        "operationId": "getDeviceConfig",
        "summary": "Retrieves device configuration",
        "description": "Returns the control mode, reported configuration and desired configuration for a device. The `control` section says who may set the device's configuration, either a person under manual control or a device configuration policy that matches the device. The `reported` section reflects the last configuration observed from a device uplink. Null if the device has never sent a config uplink. The `desired` section reflects the most recent config rollout, including terminal rollouts (applied, failed, cancelled). Null if no rollout has ever been created for the device.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "Device configuration retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                },
                "examples": {
                  "reported_and_in_progress": {
                    "summary": "Reported config with an in-progress rollout",
                    "value": {
                      "dev_eui": "AABB1122CCDD3344",
                      "owner_id": "iXeowDYO",
                      "control": {
                        "mode": "manual",
                        "updated_at": "2026-04-20T08:55:00Z",
                        "updated_by": "Job3ZjzC"
                      },
                      "reported": {
                        "config": {
                          "report_interval_seconds": 300,
                          "threshold_celsius": 25
                        },
                        "last_uplink_at": "2026-04-18T10:00:00Z"
                      },
                      "desired": {
                        "config": {
                          "report_interval_seconds": 60,
                          "threshold_celsius": 30
                        },
                        "source_type": "manual",
                        "status": "in_progress",
                        "created_by": "Job3ZjzC",
                        "updated_by": "Job3ZjzC",
                        "created_at": "2026-04-20T09:00:00Z",
                        "updated_at": "2026-04-20T09:00:05Z",
                        "started_at": "2026-04-20T09:00:05Z",
                        "progress": {
                          "total_fragments": 2,
                          "fragments_confirmed": 1,
                          "fragments": [
                            {
                              "sequence": 1,
                              "status": "confirmed",
                              "attempt_count": 1,
                              "queued_at": "2026-04-20T09:00:05Z",
                              "sent_at": "2026-04-20T09:00:06Z",
                              "confirmed_at": "2026-04-20T09:00:08Z"
                            },
                            {
                              "sequence": 2,
                              "status": "sent",
                              "attempt_count": 1,
                              "queued_at": "2026-04-20T09:00:09Z",
                              "sent_at": "2026-04-20T09:00:10Z"
                            }
                          ]
                        }
                      }
                    }
                  },
                  "reported_only": {
                    "summary": "Reported config, no rollout ever created",
                    "value": {
                      "dev_eui": "AABB1122CCDD3344",
                      "owner_id": "iXeowDYO",
                      "control": {
                        "mode": "policy"
                      },
                      "reported": {
                        "config": {
                          "report_interval_seconds": 300
                        },
                        "last_uplink_at": "2026-04-18T10:00:00Z"
                      },
                      "desired": null
                    }
                  },
                  "applied": {
                    "summary": "Rollout successfully applied",
                    "value": {
                      "dev_eui": "AABB1122CCDD3344",
                      "owner_id": "iXeowDYO",
                      "control": {
                        "mode": "manual",
                        "updated_at": "2026-04-20T08:55:00Z",
                        "updated_by": "Job3ZjzC"
                      },
                      "reported": {
                        "config": {
                          "report_interval_seconds": 60,
                          "threshold_celsius": 30
                        },
                        "last_uplink_at": "2026-04-20T09:01:00Z"
                      },
                      "desired": {
                        "config": {
                          "report_interval_seconds": 60,
                          "threshold_celsius": 30
                        },
                        "source_type": "manual",
                        "status": "applied",
                        "created_by": "Job3ZjzC",
                        "updated_by": "Job3ZjzC",
                        "created_at": "2026-04-20T09:00:00Z",
                        "updated_at": "2026-04-20T09:01:00Z",
                        "started_at": "2026-04-20T09:00:05Z",
                        "completed_at": "2026-04-20T09:01:00Z",
                        "progress": {
                          "total_fragments": 1,
                          "fragments_confirmed": 1,
                          "fragments": [
                            {
                              "sequence": 1,
                              "status": "confirmed",
                              "attempt_count": 1,
                              "queued_at": "2026-04-20T09:00:05Z",
                              "sent_at": "2026-04-20T09:00:06Z",
                              "confirmed_at": "2026-04-20T09:01:00Z"
                            }
                          ]
                        }
                      }
                    }
                  },
                  "failed": {
                    "summary": "Rollout failed after retries",
                    "value": {
                      "dev_eui": "AABB1122CCDD3344",
                      "owner_id": "iXeowDYO",
                      "control": {
                        "mode": "manual",
                        "updated_at": "2026-04-20T08:55:00Z",
                        "updated_by": "Job3ZjzC"
                      },
                      "reported": {
                        "config": {
                          "report_interval_seconds": 300
                        },
                        "last_uplink_at": "2026-04-18T10:00:00Z"
                      },
                      "desired": {
                        "config": {
                          "report_interval_seconds": 60
                        },
                        "source_type": "manual",
                        "status": "failed",
                        "failure_reason": "downlink delivery failed: tx error",
                        "created_by": "Job3ZjzC",
                        "updated_by": "admin",
                        "created_at": "2026-04-20T09:00:00Z",
                        "updated_at": "2026-04-20T09:05:00Z",
                        "started_at": "2026-04-20T09:00:05Z",
                        "completed_at": "2026-04-20T09:05:00Z",
                        "progress": {
                          "total_fragments": 1,
                          "fragments_confirmed": 0,
                          "fragments": [
                            {
                              "sequence": 1,
                              "status": "failed",
                              "attempt_count": 3,
                              "queued_at": "2026-04-20T09:00:05Z",
                              "sent_at": "2026-04-20T09:00:06Z"
                            }
                          ]
                        }
                      }
                    }
                  },
                  "no_config": {
                    "summary": "Device exists but has never reported config or received a desired config",
                    "value": {
                      "dev_eui": "AABB1122CCDD3344",
                      "owner_id": "iXeowDYO",
                      "control": {
                        "mode": "policy"
                      },
                      "reported": null,
                      "desired": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/config:enable_manual_control": {
      "post": {
        "operationId": "enableDeviceConfigManualControl",
        "summary": "Enables manual control of a device's configuration",
        "description": "Puts the device under manual configuration control, causing matching device configuration policies to stand aside. Takes no request body. Enabling manual control on a device that is already under manual control succeeds as a no-op. Returns `400` if the device's codec does not support device configuration encoding. Returns the device configuration.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "Control mode applied, returning the device configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalid_dev_eui": {
                    "summary": "Invalid dev_eui format",
                    "value": {
                      "message": "Invalid request parameter: 'dev_eui' must be a valid device EUI (16 hexadecimal characters)"
                    }
                  },
                  "codec_unsupported": {
                    "summary": "Codec does not support config encoding",
                    "value": {
                      "message": "codec \"my-sensor-v1\" does not support device config encoding"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/config:disable_manual_control": {
      "post": {
        "operationId": "disableDeviceConfigManualControl",
        "summary": "Disables manual control of a device's configuration",
        "description": "Returns the device to policy control, allowing the highest-priority matching device configuration policy to manage it. Takes no request body. Disabling manual control on a device that is already under policy control succeeds as a no-op. Returns the device configuration.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "Control mode applied, returning the device configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalid_dev_eui": {
                    "summary": "Invalid dev_eui format",
                    "value": {
                      "message": "Invalid request parameter: 'dev_eui' must be a valid device EUI (16 hexadecimal characters)"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/config/desired": {
      "put": {
        "operationId": "putDesiredConfig",
        "summary": "Updates desired device configuration",
        "description": "Submits a desired configuration for the device. The device must be under manual configuration control; a device under policy control returns `409`, and `POST /v2/devices/{dev_eui}/config:enable_manual_control` enables manual control. If an active rollout exists, it is cancelled and replaced with the new one. The first fragment is dispatched asynchronously; subsequent fragments follow as each is confirmed. The `config` object must be valid for the device's codec type. The codec determines how the configuration is encoded into downlink fragments and which confirmation strategy is used. Returns `400` if the codec does not support device configuration encoding or if the configuration fails validation. Returns `204 No Content` when the desired configuration is already fully reflected in the device's reported configuration; no rollout is created in this case. Returns `202 Accepted` when a rollout is created. Fragment delivery is asynchronous; poll `GET /devices/{dev_eui}/config` to track progress.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PutDesiredConfigRequest"
              },
              "examples": {
                "single_fragment": {
                  "summary": "Config that encodes into a single downlink",
                  "value": {
                    "config": {
                      "report_interval_seconds": 60,
                      "threshold_celsius": 30
                    }
                  }
                },
                "multi_fragment": {
                  "summary": "Config that encodes into multiple downlinks",
                  "value": {
                    "config": {
                      "report_interval_seconds": 60,
                      "threshold_celsius": 30,
                      "channels": [
                        {
                          "id": 1,
                          "enabled": true,
                          "multiplier": 1.5
                        },
                        {
                          "id": 2,
                          "enabled": false,
                          "multiplier": 1
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Desired config accepted and a rollout created with the first fragment ready for dispatch",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DesiredConfigSection"
                },
                "examples": {
                  "pending": {
                    "summary": "Rollout created (first fragment ready for dispatch, second pending)",
                    "value": {
                      "config": {
                        "report_interval_seconds": 60,
                        "threshold_celsius": 30
                      },
                      "source_type": "manual",
                      "status": "in_progress",
                      "created_by": "Job3ZjzC",
                      "updated_by": "Job3ZjzC",
                      "created_at": "2026-04-20T09:00:00Z",
                      "updated_at": "2026-04-20T09:00:00Z",
                      "started_at": "2026-04-20T09:00:00Z",
                      "progress": {
                        "total_fragments": 2,
                        "fragments_confirmed": 0,
                        "fragments": [
                          {
                            "sequence": 1,
                            "status": "ready",
                            "attempt_count": 1
                          },
                          {
                            "sequence": 2,
                            "status": "pending",
                            "attempt_count": 0
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "Desired config is already reflected in the device's reported config, no rollout created"
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalid_dev_eui": {
                    "summary": "Invalid dev_eui format",
                    "value": {
                      "message": "Invalid request parameter: 'dev_eui' must be a valid device EUI (16 hexadecimal characters)"
                    }
                  },
                  "codec_unsupported": {
                    "summary": "Codec does not support config encoding",
                    "value": {
                      "message": "codec \"my-sensor-v1\" does not support device config encoding"
                    }
                  },
                  "invalid_config": {
                    "summary": "Config fails codec validation",
                    "value": {
                      "message": "problem encoding device config: report_interval_seconds must be between 10 and 3600"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The device is under policy control, so its configuration cannot be set by hand",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "message": "device AABB1122CCDD3344 is under policy control; enable manual control before setting its configuration"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "delete": {
        "operationId": "deleteDesiredConfig",
        "summary": "Cancels desired device configuration",
        "description": "Cancels the active rollout for the device. Any in-flight fragment is also cancelled. If no active rollout exists the response is `204 No Content`. Cancellation only affects the rollout state — any fragments already delivered to the device are not reversed.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "Active rollout found and cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DesiredConfigSection"
                },
                "examples": {
                  "cancelled": {
                    "summary": "Rollout cancelled mid-delivery",
                    "value": {
                      "config": {
                        "report_interval_seconds": 60,
                        "threshold_celsius": 30
                      },
                      "source_type": "manual",
                      "status": "cancelled",
                      "created_by": "Job3ZjzC",
                      "updated_by": "Job3ZjzC",
                      "created_at": "2026-04-20T09:00:00Z",
                      "updated_at": "2026-04-20T09:02:00Z",
                      "started_at": "2026-04-20T09:00:05Z",
                      "progress": {
                        "total_fragments": 2,
                        "fragments_confirmed": 1,
                        "fragments": [
                          {
                            "sequence": 1,
                            "status": "confirmed",
                            "attempt_count": 1,
                            "queued_at": "2026-04-20T09:00:05Z",
                            "sent_at": "2026-04-20T09:00:06Z",
                            "confirmed_at": "2026-04-20T09:01:00Z"
                          },
                          {
                            "sequence": 2,
                            "status": "cancelled",
                            "attempt_count": 1,
                            "queued_at": "2026-04-20T09:01:01Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "No active rollout for this device, nothing to cancel"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/config/history": {
      "get": {
        "operationId": "getDeviceConfigHistory",
        "summary": "Retrieves device reported configuration history",
        "description": "Returns a paginated log of reported configuration changes for a device, ordered most-recent first. Each record represents a moment when the device's reported config changed to a new value, as detected from an uplink. The log is capped per device. Use `page_token` to paginate through older records. `limit` defaults to 20; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "tags": [
          "Device Configuration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Config history retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigHistoryResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page — more results exist",
                    "value": {
                      "records": [
                        {
                          "config": {
                            "report_interval_seconds": 60,
                            "threshold_celsius": 30
                          },
                          "observed_at": "2026-05-20T14:32:00.123456Z"
                        },
                        {
                          "config": {
                            "report_interval_seconds": 300,
                            "threshold_celsius": 25
                          },
                          "observed_at": "2026-05-19T08:00:00.000000Z"
                        }
                      ],
                      "meta": {
                        "next_page_token": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa",
                        "more": true
                      }
                    }
                  },
                  "last_page": {
                    "summary": "Last page — no further results",
                    "value": {
                      "records": [
                        {
                          "config": {
                            "report_interval_seconds": 300,
                            "threshold_celsius": 25
                          },
                          "observed_at": "2026-04-01T12:00:00.000000Z"
                        }
                      ],
                      "meta": {
                        "more": false
                      }
                    }
                  },
                  "empty": {
                    "summary": "No history recorded yet",
                    "value": {
                      "records": [],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "array",
                  "description": "NDJSON stream represented as an array for documentation purposes. In the actual\nresponse each element is a newline-delimited JSON object. Data records come first;\nthe final element is always a metadata object with a `meta` key. Absence of the\nfinal metadata element indicates a mid-stream error — the client should treat an\nunexpected EOF as a failure.\n",
                  "items": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/HistoricalReportedConfig"
                      },
                      {
                        "type": "object",
                        "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
                        "required": [
                          "meta"
                        ],
                        "properties": {
                          "meta": {
                            "$ref": "#/components/schemas/ListMeta"
                          }
                        }
                      }
                    ]
                  }
                },
                "examples": {
                  "ndjson_first_page": {
                    "summary": "NDJSON — first page with more results",
                    "value": [
                      {
                        "config": {
                          "report_interval_seconds": 60,
                          "threshold_celsius": 30
                        },
                        "observed_at": "2026-05-20T14:32:00.123456Z"
                      },
                      {
                        "config": {
                          "report_interval_seconds": 300,
                          "threshold_celsius": 25
                        },
                        "observed_at": "2026-05-19T08:00:00.000000Z"
                      },
                      {
                        "meta": {
                          "next_page_token": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa",
                          "more": true
                        }
                      }
                    ]
                  }
                }
              },
              "application/jsonl": {
                "schema": {
                  "type": "array",
                  "description": "Identical to application/x-ndjson. Send `Accept: application/jsonl` to receive\n`Content-Type: application/jsonl` in the response — the server echoes the media\ntype the client requested. One JSON object per line; the final line is always a\nmetadata object with a `meta` key.\n",
                  "items": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/HistoricalReportedConfig"
                      },
                      {
                        "type": "object",
                        "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
                        "required": [
                          "meta"
                        ],
                        "properties": {
                          "meta": {
                            "$ref": "#/components/schemas/ListMeta"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v2/devices/{dev_eui}/labels": {
      "get": {
        "operationId": "getDeviceLabels",
        "summary": "Retrieves device labels",
        "description": "Returns the device's labels as a map of `key`/`value` pairs. Returns an empty object when the device carries no labels.",
        "tags": [
          "Device Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "Device labels retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLabels"
                },
                "examples": {
                  "labels": {
                    "summary": "Device with labels",
                    "value": {
                      "env": "prod",
                      "region": "us-east"
                    }
                  },
                  "none": {
                    "summary": "Device with no labels",
                    "value": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "put": {
        "operationId": "replaceDeviceLabels",
        "summary": "Updates device labels",
        "description": "Replaces the device's entire label set with the supplied map. Keys present on the device but absent from the request are removed, and an empty object clears every label. Keys are lowercased and both keys and values are trimmed before storage. Returns the resulting labels.",
        "tags": [
          "Device Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLabels"
              },
              "examples": {
                "set": {
                  "summary": "Set two labels",
                  "value": {
                    "env": "prod",
                    "region": "us-east"
                  }
                },
                "clear": {
                  "summary": "Clear all labels",
                  "value": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Labels replaced successfully, returning the resulting labels",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLabels"
                },
                "example": {
                  "env": "prod",
                  "region": "us-east"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidLabel"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "patch": {
        "operationId": "mergeDeviceLabels",
        "summary": "Merges device labels",
        "description": "Adds or updates the supplied keys and leaves keys not named in the request untouched. Keys are lowercased and both keys and values are trimmed before storage. Unlike `PUT`, keys absent from the request are preserved; a key is removed only by `DELETE`. Returns the resulting labels.",
        "tags": [
          "Device Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLabels"
              },
              "example": {
                "env": "staging"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Labels merged successfully, returning the resulting labels",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLabels"
                },
                "example": {
                  "env": "staging",
                  "region": "us-east"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidLabel"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "delete": {
        "operationId": "deleteAllDeviceLabels",
        "summary": "Deletes all device labels",
        "description": "Removes every label from the device, equivalent to `PUT` with an empty object. Returns the resulting empty label map. To remove a single label instead, use `DELETE /v2/devices/{dev_eui}/labels/{key}`.",
        "tags": [
          "Device Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          }
        ],
        "responses": {
          "200": {
            "description": "All labels removed successfully, returning an empty object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLabels"
                },
                "example": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/devices/{dev_eui}/labels/{key}": {
      "delete": {
        "operationId": "deleteDeviceLabel",
        "summary": "Deletes a device label",
        "description": "Removes a single label key from the device. The operation is idempotent: removing a key the device does not carry succeeds and changes nothing. The key is canonicalized to lowercase to match stored keys. Returns the device's remaining labels.",
        "tags": [
          "Device Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DevEUI"
          },
          {
            "$ref": "#/components/parameters/LabelKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Key removed or already absent, returning the remaining labels",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLabels"
                },
                "example": {
                  "region": "us-east"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/devices/labels:search": {
      "post": {
        "operationId": "searchDevicesByLabels",
        "summary": "Searches devices by label selector",
        "description": "Returns a paginated list of devices whose labels satisfy the selector. A device matches only when it satisfies every requirement in the selector. Results are ordered by `dev_eui`. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists. Set `include_count` to also return the total number of matching devices in `meta.total_count`. That total covers every match rather than just the returned page, so requesting it slows the response; ask for it only when the total is needed.",
        "tags": [
          "Device Labels"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchDevicesByLabelsRequest"
              },
              "examples": {
                "eq_and_in": {
                  "summary": "Devices where env is prod and firmware is 1.2.0 or 1.2.1",
                  "value": {
                    "selector": [
                      {
                        "key": "env",
                        "operator": "eq",
                        "values": [
                          "prod"
                        ]
                      },
                      {
                        "key": "firmware",
                        "operator": "in",
                        "values": [
                          "1.2.0",
                          "1.2.1"
                        ]
                      }
                    ],
                    "limit": 50,
                    "include_count": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Matching devices retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceSearchResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page with more results and the count included",
                    "value": {
                      "records": [
                        {
                          "dev_eui": "2CC407FFFE517038",
                          "owner_id": "iXeowDYO"
                        },
                        {
                          "dev_eui": "4883C7DF30021C70",
                          "owner_id": "iXeowDYO"
                        }
                      ],
                      "meta": {
                        "next_page_token": "WyJpWGVvd0RZTyIsIjQ4ODNDN0RGMzAwMjFDNzAiXQ",
                        "more": true,
                        "total_count": 42
                      }
                    }
                  },
                  "empty": {
                    "summary": "No devices match the selector",
                    "value": {
                      "records": [],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceSearchNDJSONStream"
                }
              },
              "application/jsonl": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceSearchNDJSONStream"
                }
              }
            }
          },
          "400": {
            "description": "Invalid selector supplied, with the specific problem in the message field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "empty_selector": {
                    "summary": "The selector has no requirements",
                    "value": {
                      "message": "selector must contain at least one requirement"
                    }
                  },
                  "missing_operator": {
                    "summary": "A requirement omits the operator",
                    "value": {
                      "message": "selector requirement for key \"env\" must specify an operator"
                    }
                  },
                  "eq_requires_one_value": {
                    "summary": "An eq requirement supplied more than one value",
                    "value": {
                      "message": "selector operator \"eq\" requires exactly one value, got 2"
                    }
                  },
                  "duplicate_value": {
                    "summary": "An in requirement lists a value more than once",
                    "value": {
                      "message": "selector operator \"in\" has duplicate value \"1.2.0\""
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/labels/keys": {
      "get": {
        "operationId": "getLabelKeys",
        "summary": "Retrieves a list of label keys in use",
        "description": "Returns a paginated list of the distinct label keys in use for the authenticated account, for building selectors and type-ahead pickers. Results are ordered by `key`. Supply `prefix` to filter to keys starting with it. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "tags": [
          "Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          },
          {
            "$ref": "#/components/parameters/Prefix"
          }
        ],
        "responses": {
          "200": {
            "description": "Label keys retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LabelKeysResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page with more results",
                    "value": {
                      "records": [
                        {
                          "owner_id": "iXeowDYO",
                          "key": "env"
                        },
                        {
                          "owner_id": "iXeowDYO",
                          "key": "region"
                        }
                      ],
                      "meta": {
                        "next_page_token": "WyJpWGVvd0RZTyIsInJlZ2lvbiJd",
                        "more": true
                      }
                    }
                  },
                  "empty": {
                    "summary": "No labels in use",
                    "value": {
                      "records": [],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "$ref": "#/components/schemas/LabelKeysNDJSONStream"
                }
              },
              "application/jsonl": {
                "schema": {
                  "$ref": "#/components/schemas/LabelKeysNDJSONStream"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/labels/{key}/values": {
      "get": {
        "operationId": "getLabelValues",
        "summary": "Retrieves a list of values in use for a label key",
        "description": "Returns a paginated list of the distinct values in use for the given label key, for building selectors and type-ahead pickers. The key is canonicalized to lowercase. Results are ordered by `value`, and accept the same `prefix` filter as the keys endpoint. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists. A key that is not in use yields an empty result rather than a `404`.",
        "tags": [
          "Labels"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LabelKey"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          },
          {
            "$ref": "#/components/parameters/Prefix"
          }
        ],
        "responses": {
          "200": {
            "description": "Label values retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LabelValuesResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page with more results",
                    "value": {
                      "records": [
                        {
                          "owner_id": "iXeowDYO",
                          "value": "prod"
                        },
                        {
                          "owner_id": "iXeowDYO",
                          "value": "staging"
                        }
                      ],
                      "meta": {
                        "next_page_token": "WyJpWGVvd0RZTyIsInByb2QiXQ",
                        "more": true
                      }
                    }
                  },
                  "empty": {
                    "summary": "No values in use for this key",
                    "value": {
                      "records": [],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "$ref": "#/components/schemas/LabelValuesNDJSONStream"
                }
              },
              "application/jsonl": {
                "schema": {
                  "$ref": "#/components/schemas/LabelValuesNDJSONStream"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/device_config_policies": {
      "get": {
        "operationId": "listDeviceConfigPolicies",
        "summary": "Retrieves a list of device configuration policies",
        "description": "Returns a paginated list of *Device Configuration Policies* for the authenticated account. Results are ordered by `id`. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Device config policies retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListDeviceConfigPoliciesResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page with more results",
                    "value": {
                      "records": [
                        {
                          "id": "kR3mQ7xa",
                          "owner_id": "iXeowDYO",
                          "name": "Production sensors",
                          "codec_id": "my-sensor-v1",
                          "config": {
                            "report_interval_seconds": 60,
                            "threshold_celsius": 30
                          },
                          "priority": 10,
                          "status": "enabled",
                          "selector": [
                            {
                              "key": "env",
                              "operator": "eq",
                              "values": [
                                "prod"
                              ]
                            }
                          ],
                          "created_at": "2026-08-14T10:15:00Z",
                          "created_by": "Job3ZjzC",
                          "updated_at": "2026-08-20T16:42:00Z",
                          "updated_by": "Job3ZjzC"
                        },
                        {
                          "id": "b7TnW2pL",
                          "owner_id": "iXeowDYO",
                          "name": "Staging sensors",
                          "codec_id": "my-sensor-v1",
                          "config": {
                            "report_interval_seconds": 300
                          },
                          "priority": 0,
                          "status": "disabled",
                          "selector": [
                            {
                              "key": "env",
                              "operator": "eq",
                              "values": [
                                "staging"
                              ]
                            }
                          ],
                          "created_at": "2026-08-21T09:00:00Z",
                          "created_by": "Job3ZjzC",
                          "updated_at": "2026-08-21T09:00:00Z",
                          "updated_by": "Job3ZjzC"
                        }
                      ],
                      "meta": {
                        "next_page_token": "WyJpWGVvd0RZTyIsImI3VG5XMnBMIl0",
                        "more": true
                      }
                    }
                  },
                  "empty": {
                    "summary": "No policies defined",
                    "value": {
                      "records": [],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceConfigPoliciesNDJSONStream"
                }
              },
              "application/jsonl": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceConfigPoliciesNDJSONStream"
                }
              }
            }
          },
          "400": {
            "description": "Invalid pagination parameter supplied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "message": "invalid page_token: illegal base64 data at input byte 4"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "post": {
        "operationId": "createDeviceConfigPolicy",
        "summary": "Creates a new device configuration policy",
        "description": "Creates a *Device Configuration Policy* from the given name, codec, configuration, label selector, and priority. The `config` object is validated against `codec_id` and rejected when it is not a valid configuration for that codec. Names are unique per account. The policy is always created `disabled`, whatever its selector matches, so enable it with `POST /v2/device_config_policies/{policy_id}:enable` once it has been reviewed.",
        "tags": [
          "Device Configuration Policies"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeviceConfigPolicyRequest"
              },
              "examples": {
                "single_requirement": {
                  "summary": "Policy for every production sensor",
                  "value": {
                    "name": "Production sensors",
                    "codec_id": "my-sensor-v1",
                    "config": {
                      "report_interval_seconds": 60,
                      "threshold_celsius": 30
                    },
                    "priority": 10,
                    "selector": [
                      {
                        "key": "env",
                        "operator": "eq",
                        "values": [
                          "prod"
                        ]
                      }
                    ]
                  }
                },
                "narrowed_by_firmware": {
                  "summary": "Higher priority policy narrowed to two firmware versions",
                  "value": {
                    "name": "Production sensors on 1.2.x",
                    "codec_id": "my-sensor-v1",
                    "config": {
                      "report_interval_seconds": 30,
                      "threshold_celsius": 30
                    },
                    "priority": 20,
                    "selector": [
                      {
                        "key": "env",
                        "operator": "eq",
                        "values": [
                          "prod"
                        ]
                      },
                      {
                        "key": "firmware",
                        "operator": "in",
                        "values": [
                          "1.2.0",
                          "1.2.1"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Device config policy created successfully, returning it in its initial disabled state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceConfigPolicy"
                },
                "example": {
                  "id": "kR3mQ7xa",
                  "owner_id": "iXeowDYO",
                  "name": "Production sensors",
                  "codec_id": "my-sensor-v1",
                  "config": {
                    "report_interval_seconds": 60,
                    "threshold_celsius": 30
                  },
                  "priority": 10,
                  "status": "disabled",
                  "selector": [
                    {
                      "key": "env",
                      "operator": "eq",
                      "values": [
                        "prod"
                      ]
                    }
                  ],
                  "created_at": "2026-08-14T10:15:00Z",
                  "created_by": "Job3ZjzC",
                  "updated_at": "2026-08-14T10:15:00Z",
                  "updated_by": "Job3ZjzC"
                }
              }
            }
          },
          "400": {
            "description": "Invalid policy supplied, with the specific problem in the message field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missing_field": {
                    "summary": "A required field is absent",
                    "value": {
                      "message": "codec_id is required"
                    }
                  },
                  "blank_name": {
                    "summary": "The name is present but blank",
                    "value": {
                      "message": "name must not be empty"
                    }
                  },
                  "negative_priority": {
                    "summary": "The priority is below zero",
                    "value": {
                      "message": "priority must not be negative"
                    }
                  },
                  "invalid_selector": {
                    "summary": "A selector requirement is malformed",
                    "value": {
                      "message": "invalid selector: selector operator \"eq\" requires exactly one value, got 2"
                    }
                  },
                  "unknown_codec": {
                    "summary": "No codec has the given codec_id",
                    "value": {
                      "message": "codec \"my-sensor-v1\" does not exist"
                    }
                  },
                  "codec_unsupported": {
                    "summary": "The codec cannot encode device configs",
                    "value": {
                      "message": "codec \"my-sensor-v1\" does not support device config encoding"
                    }
                  },
                  "invalid_config": {
                    "summary": "The config fails codec validation",
                    "value": {
                      "message": "config is not valid for codec \"my-sensor-v1\": report_interval_seconds must be between 10 and 3600"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "A policy with the given name already exists for the account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "message": "a policy named \"Production sensors\" already exists"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/device_config_policies/{policy_id}": {
      "get": {
        "operationId": "getDeviceConfigPolicy",
        "summary": "Retrieves a device configuration policy by ID",
        "description": "Returns the *Device Configuration Policy* identified by the given `policy_id`.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PolicyID"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeviceConfigPolicySuccess"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceConfigPolicyNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "put": {
        "operationId": "updateDeviceConfigPolicy",
        "summary": "Updates a device configuration policy by ID",
        "description": "Replaces the *Device Configuration Policy* identified by the given `policy_id` with the supplied representation. A `PUT` carries the whole policy, so `name`, `codec_id`, `config`, `priority`, and `selector` must all be present, and the supplied selector replaces the policy's requirements outright rather than merging into them. The `config` object is validated against `codec_id`, so a request that changes the codec must carry a configuration valid for the new one. Changing the selector or the codec re-shapes the set of devices the policy reaches. Names are unique per account, so renaming onto a name another policy holds is rejected. `status` is read-only here: the body may echo the policy's current status, which keeps a read, edit, and write round trip working, but an attempt to change it is rejected. Use `POST /v2/device_config_policies/{policy_id}:enable` and `:disable` instead. Returns the updated policy.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PolicyID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDeviceConfigPolicyRequest"
              },
              "examples": {
                "replace": {
                  "summary": "Complete representation of the policy",
                  "value": {
                    "name": "Production sensors",
                    "codec_id": "my-sensor-v1",
                    "config": {
                      "report_interval_seconds": 30,
                      "threshold_celsius": 30
                    },
                    "priority": 10,
                    "selector": [
                      {
                        "key": "env",
                        "operator": "eq",
                        "values": [
                          "prod"
                        ]
                      }
                    ]
                  }
                },
                "echoed_status": {
                  "summary": "Round trip of a policy read with GET, status echoed unchanged",
                  "value": {
                    "name": "Production sensors",
                    "codec_id": "my-sensor-v1",
                    "config": {
                      "report_interval_seconds": 30,
                      "threshold_celsius": 30
                    },
                    "priority": 10,
                    "status": "enabled",
                    "selector": [
                      {
                        "key": "env",
                        "operator": "eq",
                        "values": [
                          "prod"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeviceConfigPolicySuccess"
          },
          "400": {
            "description": "Invalid policy supplied, with the specific problem in the message field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missing_field": {
                    "summary": "A field the complete representation must carry is absent",
                    "value": {
                      "message": "priority is required"
                    }
                  },
                  "status_changed": {
                    "summary": "The body attempts to change the status",
                    "value": {
                      "message": "status cannot be updated; use the enable or disable endpoint to change it"
                    }
                  },
                  "invalid_status": {
                    "summary": "The status is outside the policy vocabulary",
                    "value": {
                      "message": "invalid status \"paused\": must be one of enabled, disabled"
                    }
                  },
                  "invalid_selector": {
                    "summary": "A selector requirement is malformed",
                    "value": {
                      "message": "invalid selector: selector operator \"in\" has duplicate value \"1.2.0\""
                    }
                  },
                  "invalid_config": {
                    "summary": "The config fails codec validation",
                    "value": {
                      "message": "config is not valid for codec \"my-sensor-v1\": report_interval_seconds must be between 10 and 3600"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceConfigPolicyNotFound"
          },
          "409": {
            "description": "A different policy with the given name already exists for the account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "message": "a policy named \"Production sensors\" already exists"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      },
      "delete": {
        "operationId": "deleteDeviceConfigPolicy",
        "summary": "Deletes a device configuration policy by ID",
        "description": "Deletes the *Device Configuration Policy* identified by the given `policy_id`. This operation is irreversible and frees the policy's name for reuse. The policy stops reaching further devices, and configuration it has already applied stays on the devices that received it.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PolicyID"
          }
        ],
        "responses": {
          "204": {
            "description": "Device config policy deleted successfully"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceConfigPolicyNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/device_config_policies/{policy_id}:enable": {
      "post": {
        "operationId": "enableDeviceConfigPolicy",
        "summary": "Enables a device configuration policy",
        "description": "Turns on the *Device Configuration Policy* identified by the given `policy_id` so that it applies to the devices it matches. Takes no request body. Enabling a policy that is already enabled succeeds and leaves it unchanged. Returns the updated policy.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PolicyID"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeviceConfigPolicySuccess"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceConfigPolicyNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/device_config_policies/{policy_id}:disable": {
      "post": {
        "operationId": "disableDeviceConfigPolicy",
        "summary": "Disables a device configuration policy",
        "description": "Turns off the *Device Configuration Policy* identified by the given `policy_id` so that it stops reaching further devices. Configuration it has already applied stays on the devices that received it. Takes no request body. Disabling a policy that is already disabled succeeds and leaves it unchanged. Returns the updated policy.",
        "tags": [
          "Device Configuration Policies"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PolicyID"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeviceConfigPolicySuccess"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceConfigPolicyNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-incubated": true
      }
    },
    "/v2/output/destinations": {
      "get": {
        "tags": [
          "Output Destinations"
        ],
        "summary": "Retrieves a list of output destinations",
        "description": "Returns a paginated list of *Output Destinations* for the authenticated account. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "operationId": "ListOutputDestinations",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing the output destination list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListOutputDestinationsResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page — more results exist",
                    "value": {
                      "records": [
                        {
                          "id": "utLLrPvb",
                          "owner_id": "ZxuCIYlI",
                          "name": "First Destination",
                          "type": "webhook",
                          "enabled": true,
                          "data": {
                            "url": "https://client.com/webhook"
                          }
                        },
                        {
                          "id": "V8Jew5Ob",
                          "owner_id": "ZxuCIYlI",
                          "name": "Second Destination",
                          "type": "azure_iot_hub",
                          "credentials_id": "Ck9cZn1F",
                          "enabled": true,
                          "data": {
                            "host": "client-iothub-001.azure-devices.net"
                          }
                        }
                      ],
                      "meta": {
                        "next_page_token": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa",
                        "more": true
                      }
                    }
                  },
                  "last_page": {
                    "summary": "Last page — no further results",
                    "value": {
                      "records": [
                        {
                          "id": "FgOtqbsU",
                          "owner_id": "ZxuCIYlI",
                          "name": "Last Destination",
                          "type": "webhook",
                          "enabled": true,
                          "data": {
                            "url": "https://client.com/webhook"
                          }
                        }
                      ],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "post": {
        "tags": [
          "Output Destinations"
        ],
        "summary": "Creates a new output destination",
        "description": "Creates a new *Output Destination* with the given configuration.",
        "operationId": "CreateOutputDestination",
        "responses": {
          "201": {
            "description": "Output destination created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentifiableOutputDestination"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OutputDestinationInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "$ref": "#/components/requestBodies/OutputDestinationRequestBody"
        }
      }
    },
    "/v2/output/destinations/{destination_id}": {
      "get": {
        "tags": [
          "Output Destinations"
        ],
        "summary": "Retrieves an output destination by ID",
        "description": "Returns the *Output Destination* identified by the given __destination_id__.",
        "operationId": "GetOutputDestination",
        "parameters": [
          {
            "name": "destination_id",
            "in": "path",
            "description": "Unique identifier of the *Output Destination*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IdentifiableOutputDestinationSuccessResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputDestinationNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "put": {
        "tags": [
          "Output Destinations"
        ],
        "summary": "Updates an output destination by ID",
        "description": "Replaces the *Output Destination* identified by the given __destination_id__ with the provided configuration.",
        "operationId": "UpdateOutputDestination",
        "parameters": [
          {
            "name": "destination_id",
            "in": "path",
            "description": "Unique identifier of the *Output Destination*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing the updated output destination",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentifiableOutputDestination"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OutputDestinationInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputDestinationNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutputDestination"
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Output Destinations"
        ],
        "summary": "Deletes an output destination by ID",
        "description": "Deletes the *Output Destination* identified by the given __destination_id__. This operation is irreversible.\n\n**Important:** Deleting an *Output Destination* also removes it from all associated *Output Alerts* without warning. This may leave one or more *Output Alerts* with zero associated *Output Destinations*.\n\nDeleting an *Output Destination* does not remove the associated *Output Credentials*.\n",
        "operationId": "DeleteOutputDestination",
        "parameters": [
          {
            "name": "destination_id",
            "in": "path",
            "description": "Unique identifier of the *Output Destination*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Output destination deleted successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputDestinationNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/alerts": {
      "get": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Retrieves a list of output alerts",
        "description": "Returns a paginated list of *Output Alerts* for the authenticated account. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "operationId": "ListOutputAlerts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing the output alert list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListOutputAlertsResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page — more results exist",
                    "value": {
                      "records": [
                        {
                          "id": "utLLrPvb",
                          "owner_id": "ZxuCIYlI",
                          "name": "First Alert",
                          "type": "gateway_connectivity",
                          "data": {
                            "node_ids": [
                              "FFFF00800001069F",
                              "2CC4070000002E86"
                            ]
                          },
                          "destination_ids": [
                            "0NIlbVnJ"
                          ]
                        },
                        {
                          "id": "V8Jew5Ob",
                          "owner_id": "ZxuCIYlI",
                          "name": "Second Alert",
                          "type": "gateway_connectivity",
                          "data": {
                            "node_ids": [
                              "FFFFA15A9C20F79F"
                            ]
                          },
                          "destination_ids": [
                            "PpfBSI6d"
                          ]
                        }
                      ],
                      "meta": {
                        "next_page_token": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa",
                        "more": true
                      }
                    }
                  },
                  "last_page": {
                    "summary": "Last page — no further results",
                    "value": {
                      "records": [
                        {
                          "id": "FgOtqbsU",
                          "owner_id": "ZxuCIYlI",
                          "name": "Last Alert",
                          "type": "gateway_connectivity",
                          "data": {
                            "node_ids": [
                              "FFFFA15A9C20F79F"
                            ]
                          },
                          "destination_ids": [
                            "vN6hwxwu"
                          ]
                        }
                      ],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "post": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Creates a new output alert",
        "description": "Creates a new *Output Alert* with the given configuration.",
        "operationId": "CreateOutputAlert",
        "responses": {
          "201": {
            "description": "Output alert created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentifiableOutputAlert"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OutputAlertInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutputAlert"
              }
            }
          }
        }
      }
    },
    "/v2/output/alerts/{alert_id}": {
      "get": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Retrieves an output alert by ID",
        "description": "Returns the *Output Alert* identified by the given __alert_id__.",
        "operationId": "GetOutputAlert",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IdentifiableOutputAlertSuccessResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "put": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Updates an output alert by ID",
        "description": "Replaces the *Output Alert* identified by the given __alert_id__ with the provided configuration.",
        "operationId": "UpdateOutputAlert",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IdentifiableOutputAlertSuccessResponse"
          },
          "400": {
            "$ref": "#/components/responses/OutputAlertInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutputAlert"
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Deletes an output alert by ID",
        "description": "Deletes the *Output Alert* identified by the given __alert_id__. This operation is irreversible.\n\nDeleting an *Output Alert* does not remove the associated *Output Destinations*.\n",
        "operationId": "DeleteOutputAlert",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Output alert deleted successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/alerts/{alert_id}/gateways:add": {
      "post": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Adds a gateway to an output alert",
        "description": "Adds the _Gateway_ identified by the given __node_id__ to the *Output Alert* identified by the given __alert_id__ if it does not already exist.\n\nReturns an HTTP `409 Conflict` error if the given __node_id__ is already associated to the *Output Alert*.\n",
        "operationId": "AddOutputAlertGateway",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddOutputAlertGatewayRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Gateway added to the output alert successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "409": {
            "description": "Gateway already associated to the output alert",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "message": "Gateway with Node ID 'FFFF00800001069F' already exists for Alert identified by 'TGexoQsP'"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/alerts/{alert_id}/gateways:remove": {
      "post": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Removes a gateway from an output alert",
        "description": "Removes the _Gateway_ identified by the given __node_id__ from the *Output Alert* identified by the given __alert_id__ if it exists.\n\nReturns an HTTP `412 Precondition Failed` error if the given __node_id__ is not currently associated to the *Output Alert*.\n",
        "operationId": "RemoveOutputAlertGateway",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoveOutputAlertGatewayRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Gateway removed from the output alert successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "412": {
            "description": "Gateway not associated to the output alert",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "message": "Alert Gateway request is not valid: '30DC64A5B1337FAB' not associated to Alert"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/alerts/{alert_id}/gateways:batch_add": {
      "post": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Adds a batch of gateways to an output alert",
        "description": "Adds all _Gateways_ in the given collection of __node_ids__ to the *Output Alert* identified by the given __alert_id__ if they do not already exist.\n\nThe entire batch fails with an HTTP `409 Conflict` error if any of the given __node_ids__ are already associated to the *Output Alert*.\n",
        "operationId": "BatchAddOutputAlertGateways",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchAddOutputAlertGatewayRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Gateways added to the output alert successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "409": {
            "description": "One or more gateways already associated to the output alert",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "message": "Gateway with Node ID 'FFFF00800001069F' already exists for Alert identified by 'TGexoQsP'"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/alerts/{alert_id}/gateways:batch_remove": {
      "post": {
        "tags": [
          "Output Alerts"
        ],
        "summary": "Removes a batch of gateways from an output alert",
        "description": "Removes all _Gateways_ in the given collection of __node_ids__ from the *Output Alert* identified by the given __alert_id__ if they exist.\n\nThe entire batch fails with an HTTP `412 Precondition Failed` error if any of the given __node_ids__ are not currently associated to the *Output Alert*.\n",
        "operationId": "BatchRemoveOutputAlertGateways",
        "parameters": [
          {
            "name": "alert_id",
            "in": "path",
            "description": "Unique identifier of the *Output Alert*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRemoveOutputAlertGatewayRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Gateways removed from the output alert successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputAlertNotFoundErrorResponse"
          },
          "412": {
            "description": "One or more gateways not associated to the output alert",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Non2XXResponse"
                },
                "example": {
                  "message": "Gateway with Node ID 'FFFF00800001069F' does not exist for Alert identified by 'TGexoQsP'"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    },
    "/v2/output/credentials": {
      "get": {
        "tags": [
          "Output Credentials"
        ],
        "summary": "Retrieves a list of output credentials",
        "description": "Returns a paginated list of *Output Credentials* for the authenticated account. Sensitive fields are redacted from the response. Use `page_token` to paginate through additional records. `limit` defaults to 100; large values are clamped to a server-side maximum. The `meta.more` field is always present and explicitly indicates whether a further page exists.",
        "operationId": "ListOutputCredentials",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing the output credentials list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListOutputCredentialsResponse"
                },
                "examples": {
                  "first_page": {
                    "summary": "First page — more results exist",
                    "value": {
                      "records": [
                        {
                          "id": "utLLrPvb",
                          "owner_id": "ZxuCIYlI",
                          "name": "First Credentials",
                          "type": "basic_auth"
                        },
                        {
                          "id": "V8Jew5Ob",
                          "owner_id": "ZxuCIYlI",
                          "name": "Second Credentials",
                          "type": "client_credentials"
                        }
                      ],
                      "meta": {
                        "next_page_token": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa",
                        "more": true
                      }
                    }
                  },
                  "last_page": {
                    "summary": "Last page — no further results",
                    "value": {
                      "records": [
                        {
                          "id": "FgOtqbsU",
                          "owner_id": "ZxuCIYlI",
                          "name": "Last Credentials",
                          "type": "x509_certificate"
                        }
                      ],
                      "meta": {
                        "more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "post": {
        "tags": [
          "Output Credentials"
        ],
        "summary": "Creates new output credentials",
        "description": "Creates new *Output Credentials* with the given configuration. Secrets are written to an encrypted store and never persisted in plain text.",
        "operationId": "CreateOutputCredentials",
        "responses": {
          "201": {
            "description": "Output credentials created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SafeIdentifiableOutputCredentials"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OutputCredentialsInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "$ref": "#/components/requestBodies/OutputCredentialsRequestBody"
        }
      }
    },
    "/v2/output/credentials/{credentials_id}": {
      "get": {
        "tags": [
          "Output Credentials"
        ],
        "summary": "Retrieves output credentials by ID",
        "description": "Returns the *Output Credentials* identified by the given __credentials_id__. Sensitive fields are redacted from the response.",
        "operationId": "GetOutputCredentials",
        "parameters": [
          {
            "name": "credentials_id",
            "in": "path",
            "description": "Unique identifier of the *Output Credentials*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IdentifiableOutputCredentialsSuccessResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputCredentialsNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      },
      "put": {
        "tags": [
          "Output Credentials"
        ],
        "summary": "Updates output credentials by ID",
        "description": "Replaces the *Output Credentials* identified by the given __credentials_id__ with the provided configuration.",
        "operationId": "UpdateOutputCredentials",
        "parameters": [
          {
            "name": "credentials_id",
            "in": "path",
            "description": "Unique identifier of the *Output Credentials*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IdentifiableOutputCredentialsSuccessResponse"
          },
          "400": {
            "$ref": "#/components/responses/OutputCredentialsInvalidInputErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputCredentialsNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        },
        "requestBody": {
          "$ref": "#/components/requestBodies/OutputCredentialsRequestBody"
        }
      },
      "delete": {
        "tags": [
          "Output Credentials"
        ],
        "summary": "Deletes output credentials by ID",
        "description": "Deletes the *Output Credentials* identified by the given __credentials_id__. This operation is irreversible.\n\n**Important:** Deleting *Output Credentials* also removes the association to *Output Destinations* without warning. This may leave one or more *Output Destinations* requiring association to different *Output Credentials*.\n",
        "operationId": "DeleteOutputCredentials",
        "parameters": [
          {
            "name": "credentials_id",
            "in": "path",
            "description": "Unique identifier of the *Output Credentials*.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Output credentials deleted successfully"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/OutputCredentialsNotFoundErrorResponse"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerErrorResponse"
          }
        }
      }
    }
  },
  "webhooks": {
    "outputAlertEvent": {
      "post": {
        "summary": "Delivers an output alert event",
        "description": "Delivers an *Output Alert Event* to each *Output Destination* associated with the *Output Alert* when the alert condition is met.",
        "operationId": "PostOutputAlert",
        "tags": [
          "Output Events"
        ],
        "requestBody": {
          "description": "Envelope containing *Output Alert Event* data.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutputAlertEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledgement of receipt of the *Output Alert Event*"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "limitParam": {
        "name": "limit",
        "in": "query",
        "description": "Maximum number of elements to return per page. Optional. When omitted, all results are returned in a single response.",
        "required": false,
        "schema": {
          "type": "integer",
          "format": "int32"
        }
      },
      "pageParam": {
        "name": "page",
        "in": "query",
        "description": "Page number of results to return. Optional. Default: 1.",
        "required": false,
        "schema": {
          "type": "integer",
          "format": "int32"
        }
      },
      "orderParam": {
        "name": "order_by",
        "in": "query",
        "description": "Sorts results by the specified field. Default: ascending alphabetical order. Prefix the value with a \"-\" to sort in descending order.",
        "required": false,
        "schema": {
          "type": "string"
        }
      },
      "fieldMaskParam": {
        "name": "field_mask",
        "in": "query",
        "description": "Selects which fields to include in the results. The specified field is included if present, along with the `dev_eui` field, which is always included. Provide an additional __field_mask__ parameter for each additional field.",
        "required": false,
        "schema": {
          "type": "string"
        }
      },
      "qParam": {
        "name": "q",
        "in": "query",
        "description": "Filters results by specific fields using a set of operators in a JSON-style format:\n\nOperator | Notes\n---|---\n= | Returns all results that are an exact match\n!= | Returns all results excluding those specified\n$like | Returns all results that match a \"~\" wildcard search\n$ilike | Returns all results that match a \"~\" case-insensitive wildcard search\n$in | Returns all results that match the specified list\n$nin | Returns all results excluding those in the specified list\n$and | Returns all results that match all query parameters\n$or | Returns all results that match any of the filter parameters \n$intersects | Returns all results that match a group field value search\n",
        "example": "{\"$or\":{\"name\":{\"$ilike\":\"~temperature~\"},\"health_state\":{\"=\":\"good\"}}}\n",
        "required": false,
        "schema": {
          "type": "string"
        }
      },
      "DevEUI": {
        "name": "dev_eui",
        "in": "path",
        "required": true,
        "description": "Device EUI — exactly 16 hexadecimal characters (case-insensitive).\nInternally normalized to uppercase.\n",
        "schema": {
          "type": "string",
          "pattern": "^[0-9A-Fa-f]{16}$",
          "example": "AABB1122CCDD3344"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum number of records to return. Defaults to an appropriate value for the entity type when omitted. Large values are clamped to a server-side maximum.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "example": 20
        }
      },
      "PageToken": {
        "name": "page_token",
        "in": "query",
        "required": false,
        "description": "Opaque pagination cursor from `meta.next_page_token` in the previous response.\nOmit to request the first page.\n",
        "schema": {
          "type": "string",
          "example": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa"
        }
      },
      "LabelKey": {
        "name": "key",
        "in": "path",
        "required": true,
        "description": "Label key to address. Canonicalized to lowercase to match stored keys.",
        "schema": {
          "type": "string",
          "example": "env"
        }
      },
      "Prefix": {
        "name": "prefix",
        "in": "query",
        "required": false,
        "description": "Filters results to those starting with the given prefix, for type-ahead. Case-insensitive. Omit to return every result.",
        "schema": {
          "type": "string",
          "example": "en"
        }
      },
      "PolicyID": {
        "name": "policy_id",
        "in": "path",
        "required": true,
        "description": "Unique identifier of the device configuration policy.",
        "schema": {
          "type": "string",
          "example": "kR3mQ7xa"
        }
      }
    },
    "schemas": {
      "Identifiable": {
        "description": "A resource with a unique identifier.",
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier of the resource."
          }
        },
        "examples": [
          {
            "id": "Xrzm28a0"
          }
        ]
      },
      "Owned": {
        "description": "A resource with an owner.",
        "type": "object",
        "properties": {
          "owner_id": {
            "type": "string",
            "description": "Unique identifier of the owner of the resource. Resources are isolated to their owner and are not visible across ownership boundaries."
          }
        },
        "examples": [
          {
            "owner_id": "iXeowDYO"
          }
        ]
      },
      "Device": {
        "description": "A LoRaWAN device record with configuration, statistics, and group associations.",
        "type": "object",
        "required": [
          "name",
          "dev_eui",
          "activation_type",
          "service_profile",
          "device_profile"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the _Device_. Required. Must be unique within the account."
          },
          "dev_eui": {
            "type": "string",
            "description": "Extended Unique Identifier (EUI-64) of the device. Required. Must be a 16-character hexadecimal string."
          },
          "owner_id": {
            "type": "string",
            "description": "Identifies the owner of the resource. Resources are isolated to their owner and are not visible across ownership boundaries."
          },
          "activation_type": {
            "type": "string",
            "enum": [
              "ABP",
              "OTAA"
            ],
            "description": "Activation method used by the device. Required.\n- `ABP`: Activation By Personalization — device keys are hardcoded.\n- `OTAA`: Over-The-Air Activation — device keys are negotiated via a join procedure.\n"
          },
          "service_profile": {
            "type": "string",
            "description": "Unique identifier of the _ServiceProfile_ assigned to the device. Required. Retrieve applicable values via GET `/v1/serviceprofiles`."
          },
          "device_profile": {
            "type": "string",
            "description": "Unique identifier of the _DeviceProfile_ assigned to the device. Required. Retrieve applicable values via GET `/v1/deviceprofiles`."
          },
          "decoder_type": {
            "type": "string",
            "description": "Unique identifier of the _Decoder_ used to decode packets from the device. Optional. Retrieve applicable values via GET `/v1/decodertypes`."
          },
          "output_profile": {
            "type": "string",
            "description": "Unique identifier of the _OutputProfile_ used for routing packets to external servers. Optional. Retrieve applicable values via GET `/v1/outputprofiles`."
          },
          "private_data": {
            "type": "boolean",
            "description": "Whether device data is private. True means data is not stored; false means data is stored for future processing."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of _Device_ creation in RFC 3339 format."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the last _Device_ modification in RFC 3339 format."
          },
          "updated_by": {
            "type": "string",
            "description": "Unique identifier of the _User_ or _Subscriber_ that last modified the _Device_."
          },
          "last_uplink": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the last uplink message from the _Device_ in RFC 3339 format. Null if the device has never sent an uplink."
          },
          "health_state": {
            "type": "string",
            "enum": [
              "good",
              "fair",
              "poor",
              "offline"
            ],
            "description": "Calculated health of the _Device_ based on recent activity.\n- `good`: Device is performing well with strong signal quality.\n- `fair`: Device is operational but with degraded signal quality.\n- `poor`: Device is experiencing significant signal degradation.\n- `offline`: Device has not communicated recently.\n"
          },
          "spreading_factor": {
            "type": "integer",
            "format": "int32",
            "description": "Current LoRa Spreading Factor of the device (e.g., 7 = SF7). Range: 7–12."
          },
          "average_rssi": {
            "type": "number",
            "format": "float",
            "description": "Average Received Signal Strength Indicator (RSSI) over the last 24 hours, in dBm."
          },
          "average_esp": {
            "type": "number",
            "format": "float",
            "description": "Average Estimated Signal Power (ESP) over the last 24 hours, in dBm."
          },
          "average_snr": {
            "type": "number",
            "format": "float",
            "description": "Average Signal-to-Noise Ratio (SNR) over the last 24 hours, in dB."
          },
          "packet_error_rate": {
            "type": "number",
            "format": "float",
            "description": "Percentage of dropped packets over the last 24 hours. Range: 0–100."
          },
          "battery_level": {
            "type": "integer",
            "description": "Reported battery level from the _Device_. Null if the device does not report battery status."
          },
          "average_weekly_packets": {
            "type": "integer",
            "format": "int32",
            "description": "Average number of packets per day over the past week."
          },
          "groups": {
            "type": "array",
            "description": "List of _Groups_ to which the _Device_ belongs.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Unique identifier of the _Group_."
                },
                "name": {
                  "type": "string",
                  "description": "Human-readable name of the _Group_."
                }
              }
            }
          }
        }
      },
      "GetDevicesResponse": {
        "description": "A paginated list of device records.",
        "type": "object",
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/DeviceListMeta"
          },
          "records": {
            "type": "array",
            "description": "List of _Device_ records returned by the query.",
            "items": {
              "$ref": "#/components/schemas/Device"
            }
          }
        }
      },
      "OutputAlert": {
        "description": "A configuration that defines alert rules and associated output destinations.",
        "type": "object",
        "required": [
          "name",
          "type",
          "destination_ids"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the _Alert_. Required."
          },
          "type": {
            "type": "string",
            "description": "Type of the _Alert_. Required.\n- `gateway_connectivity`: Triggers when a gateway connectivity status changes.\n",
            "enum": [
              "gateway_connectivity"
            ]
          },
          "data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GatewayConnectivityAlert"
              }
            ]
          },
          "destination_ids": {
            "type": "array",
            "description": "List of unique identifiers of the _Destinations_ to which alert events are delivered. Required. Minimum 1 item.",
            "items": {
              "type": "string"
            }
          }
        },
        "examples": [
          {
            "name": "CorbyCorp Gateway Alert",
            "type": "gateway_connectivity",
            "data": {
              "node_ids": [
                "FFFF00800001069F",
                "FFFFA15A9C20F79F"
              ]
            },
            "destination_ids": [
              "Md14GhHE",
              "wkBWFE4n"
            ]
          }
        ]
      },
      "IdentifiableOutputAlert": {
        "description": "An output alert with a unique identifier.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Identifiable"
          },
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "$ref": "#/components/schemas/OutputAlert"
          }
        ]
      },
      "GatewayConnectivityAlert": {
        "description": "Gateway connectivity alert configuration specifying which gateways to monitor.",
        "type": "object",
        "required": [
          "node_ids"
        ],
        "properties": {
          "node_ids": {
            "type": "array",
            "description": "List of gateway `node_id` values to monitor for connectivity changes. Required. Minimum 1 item.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ListOutputAlertsResponse": {
        "description": "A list of output alert records.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          },
          "records": {
            "type": "array",
            "description": "List of *Output Alert* records.",
            "items": {
              "$ref": "#/components/schemas/IdentifiableOutputAlert"
            }
          }
        }
      },
      "AddOutputAlertGatewayRequest": {
        "description": "A request to add a single gateway to an output alert.",
        "type": "object",
        "required": [
          "node_id"
        ],
        "properties": {
          "node_id": {
            "type": "string",
            "description": "Unique `node_id` of the _Gateway_ to add. Required."
          }
        },
        "examples": [
          {
            "node_id": "FFFF00800001069F"
          }
        ]
      },
      "RemoveOutputAlertGatewayRequest": {
        "description": "A request to remove a single gateway from an output alert.",
        "type": "object",
        "required": [
          "node_id"
        ],
        "properties": {
          "node_id": {
            "type": "string",
            "description": "Unique `node_id` of the _Gateway_ to remove. Required."
          }
        },
        "examples": [
          {
            "node_id": "FFFF00800001069F"
          }
        ]
      },
      "BatchAddOutputAlertGatewayRequest": {
        "description": "A request to add multiple gateways to an output alert.",
        "type": "object",
        "required": [
          "node_ids"
        ],
        "properties": {
          "node_ids": {
            "type": "array",
            "description": "List of gateway `node_id` values to add. Required. Minimum 1 item.",
            "items": {
              "type": "string"
            }
          }
        },
        "examples": [
          {
            "node_ids": [
              "FFFF00800001069F",
              "2CC4070000002E86",
              "FFFFA15A9C20F79F"
            ]
          }
        ]
      },
      "BatchRemoveOutputAlertGatewayRequest": {
        "description": "A request to remove multiple gateways from an output alert.",
        "type": "object",
        "required": [
          "node_ids"
        ],
        "properties": {
          "node_ids": {
            "type": "array",
            "description": "List of gateway `node_id` values to remove. Required. Minimum 1 item.",
            "items": {
              "type": "string"
            }
          }
        },
        "examples": [
          {
            "node_ids": [
              "FFFF00800001069F",
              "2CC4070000002E86",
              "FFFFA15A9C20F79F"
            ]
          }
        ]
      },
      "BasicAuth": {
        "description": "Basic authentication credentials consisting of a username and password.",
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "properties": {
          "username": {
            "type": "string",
            "description": "Username for authentication. Required."
          },
          "password": {
            "type": "string",
            "description": "Password for authentication. Required. Stored in an encrypted store and never persisted in plain text."
          }
        }
      },
      "ClientCredentials": {
        "description": "OAuth 2.0 client credentials used to obtain an access token.",
        "type": "object",
        "required": [
          "client_id",
          "client_secret",
          "auth_url"
        ],
        "properties": {
          "client_id": {
            "type": "string",
            "description": "Client identifier for the OAuth access token request. Required."
          },
          "client_secret": {
            "type": "string",
            "description": "Client secret for the OAuth access token request. Required. Stored in an encrypted store and never persisted in plain text."
          },
          "auth_url": {
            "type": "string",
            "description": "URL to which the OAuth access token request is sent. Required."
          },
          "scopes": {
            "type": "string",
            "description": "Space-separated list of scopes to include in the OAuth access token. Optional."
          },
          "audience": {
            "type": "string",
            "description": "Unique identifier of the target API that the JWT token is intended for. Optional."
          }
        }
      },
      "X509Certificate": {
        "description": "X.509 certificate credentials consisting of a public certificate and private key.",
        "type": "object",
        "required": [
          "private_key",
          "public_key"
        ],
        "properties": {
          "public_key": {
            "type": "string",
            "description": "Client certificate in PEM format with embedded newline characters. Required. Stored in an encrypted store and never persisted in plain text."
          },
          "private_key": {
            "type": "string",
            "description": "Client private key in PEM format with embedded newline characters. Required. Stored in an encrypted store and never persisted in plain text."
          }
        }
      },
      "AzureSharedAccessPolicy": {
        "description": "Azure IoT Hub Shared Access Policy credentials.",
        "type": "object",
        "required": [
          "policy_name",
          "shared_access_key"
        ],
        "properties": {
          "policy_name": {
            "type": "string",
            "description": "Name of the Azure *Shared Access Policy* with \"Device Connect\" permission. Required."
          },
          "shared_access_key": {
            "type": "string",
            "description": "Primary or secondary key of the *Shared Access Policy*. Required. Stored in an encrypted store and never persisted in plain text."
          }
        }
      },
      "OutputCredentials": {
        "description": "A set of credentials used to authenticate when delivering data to output destinations.",
        "type": "object",
        "required": [
          "name",
          "type",
          "data"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/OutputCredentialsName"
          },
          "type": {
            "$ref": "#/components/schemas/OutputCredentialsType"
          },
          "data": {
            "description": "Type-specific credential details. Required.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BasicAuth"
              },
              {
                "$ref": "#/components/schemas/ClientCredentials"
              },
              {
                "$ref": "#/components/schemas/X509Certificate"
              },
              {
                "$ref": "#/components/schemas/AzureSharedAccessPolicy"
              }
            ]
          }
        }
      },
      "IdentifiableOutputCredentials": {
        "description": "Output credentials with a unique identifier.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Identifiable"
          },
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "$ref": "#/components/schemas/OutputCredentials"
          }
        ]
      },
      "SafeOutputCredentials": {
        "description": "Output credentials with sensitive fields redacted.",
        "type": "object",
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/OutputCredentialsName"
          },
          "type": {
            "$ref": "#/components/schemas/OutputCredentialsType"
          }
        }
      },
      "SafeIdentifiableOutputCredentials": {
        "description": "Output credentials with a unique identifier and sensitive fields redacted.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Identifiable"
          },
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "$ref": "#/components/schemas/SafeOutputCredentials"
          }
        ]
      },
      "OutputCredentialsName": {
        "type": "string",
        "description": "Human-readable name of the _Credentials_. Required.",
        "examples": [
          "CorbyCorp admin user auth"
        ]
      },
      "OutputCredentialsType": {
        "type": "string",
        "description": "Type of the _Credentials_. Required.\n- `basic_auth`: Username and password authentication.\n- `client_credentials`: OAuth 2.0 client credentials grant.\n- `x509_certificate`: X.509 certificate-based authentication.\n- `azure_shared_access_policy`: Azure IoT Hub Shared Access Policy authentication.\n",
        "enum": [
          "basic_auth",
          "client_credentials",
          "x509_certificate",
          "azure_shared_access_policy"
        ]
      },
      "ListOutputCredentialsResponse": {
        "description": "A list of output credentials records with sensitive fields redacted.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          },
          "records": {
            "type": "array",
            "description": "List of *Output Credentials* records.",
            "items": {
              "$ref": "#/components/schemas/SafeIdentifiableOutputCredentials"
            }
          }
        }
      },
      "OutputDestination": {
        "description": "A destination to which output events are delivered.",
        "type": "object",
        "required": [
          "name",
          "type",
          "data"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the _Destination_. Required."
          },
          "type": {
            "type": "string",
            "description": "Type of the _Destination_. Required.\n- `webhook`: Delivers events via HTTP POST to a URL.\n- `azure_iot_hub`: Delivers events to an Azure IoT Hub.\n- `mqtt`: Delivers events to an MQTT broker.\n- `aws_iot_core`: Delivers events to AWS IoT Core.\n",
            "enum": [
              "webhook",
              "azure_iot_hub",
              "mqtt",
              "aws_iot_core"
            ]
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether *Output Events* are delivered to the _Destination_. True means events are delivered; false means delivery is paused. Optional."
          },
          "credentials_id": {
            "type": "string",
            "description": "Unique identifier of the _Credentials_ used to authenticate delivery. Optional."
          },
          "data": {
            "description": "Type-specific destination configuration details. Required.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/WebhookDestination"
              },
              {
                "$ref": "#/components/schemas/AzureIOTHubDestination"
              },
              {
                "$ref": "#/components/schemas/MQTTDestination"
              },
              {
                "$ref": "#/components/schemas/AWSIOTCoreDestination"
              }
            ]
          }
        }
      },
      "IdentifiableOutputDestination": {
        "description": "An output destination with a unique identifier.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Identifiable"
          },
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "$ref": "#/components/schemas/OutputDestination"
          }
        ]
      },
      "ListOutputDestinationsResponse": {
        "description": "A list of output destination records.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          },
          "records": {
            "type": "array",
            "description": "List of *Output Destination* records.",
            "items": {
              "$ref": "#/components/schemas/IdentifiableOutputDestination"
            }
          }
        }
      },
      "WebhookDestination": {
        "description": "Webhook-specific destination configuration.",
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "URL to which *Output Events* are delivered via HTTP POST. Required."
          },
          "headers": {
            "type": "array",
            "description": "List of custom HTTP headers included when delivering an *Output Event* to the webhook. Optional.",
            "items": {
              "$ref": "#/components/schemas/WebhookHeader"
            }
          }
        }
      },
      "WebhookHeader": {
        "description": "A custom HTTP header included in webhook deliveries.",
        "type": "object",
        "required": [
          "header",
          "value"
        ],
        "properties": {
          "header": {
            "type": "string",
            "description": "Name of the HTTP header. Required."
          },
          "value": {
            "type": "string",
            "description": "Value of the HTTP header. Required."
          }
        }
      },
      "AzureIOTHubDestination": {
        "description": "Azure IoT Hub-specific destination configuration.",
        "type": "object",
        "required": [
          "host"
        ],
        "properties": {
          "host": {
            "type": "string",
            "description": "Fully-qualified hostname of the Azure IoT Hub to which *Output Events* are delivered. Required.\nFormat: `{iothub-name}.azure-devices.net`.\n"
          }
        }
      },
      "MQTTDestination": {
        "description": "MQTT broker-specific destination configuration.",
        "type": "object",
        "required": [
          "host",
          "topic"
        ],
        "properties": {
          "host": {
            "type": "string",
            "description": "Hostname and port of the MQTT broker to which *Output Events* are delivered. Required.\nFormat: `{host}:{port}`. Must not include the scheme.\n"
          },
          "topic": {
            "type": "string",
            "description": "Topic on the MQTT broker to which *Output Events* are published. Required."
          },
          "tls_enabled": {
            "type": "boolean",
            "description": "Whether events are sent over TLS. True means TLS is enabled; false means TLS is disabled. Optional."
          },
          "custom_client_id": {
            "type": "string",
            "description": "Client ID used when connecting to the MQTT broker. Optional. Supports `${DEVEUI}` and `${FPORT}` placeholders,\nwhich are replaced with the actual __dev_eui__ and __fport__ values before delivery. When omitted, the connection\nis established without a client ID.\n"
          }
        }
      },
      "AWSIOTCoreDestination": {
        "description": "AWS IoT Core-specific destination configuration.",
        "type": "object",
        "required": [
          "endpoint"
        ],
        "properties": {
          "endpoint": {
            "type": "string",
            "description": "Endpoint URL of the AWS IoT Core instance to which *Output Events* are delivered. Required.\nFormat: `{account-specific-prefix}.iot.{aws-region}.amazonaws.com`.\n"
          }
        }
      },
      "DeviceListMeta": {
        "description": "Pagination metadata for list responses.",
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of results matching the query parameters."
          },
          "count": {
            "type": "integer",
            "description": "Number of results returned in the current page. Equal to `total` when no limit is set."
          },
          "page": {
            "type": "integer",
            "description": "Current page number. Default: 1."
          },
          "more": {
            "type": "boolean",
            "description": "Whether additional pages of results exist. True means more results are available; false means the current page is the last."
          }
        }
      },
      "Non2XXResponse": {
        "description": "An error response returned for non-2xx status codes.",
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32",
            "description": "Error code specific to the type of error that occurred. Optional."
          },
          "message": {
            "type": "string",
            "description": "Developer-facing error message describing the failure."
          },
          "details": {
            "type": "array",
            "description": "List of additional error detail messages. Optional.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "OutputAlertEvent": {
        "description": "An event produced when an output alert condition is met.",
        "type": "object",
        "required": [
          "type",
          "timestamp",
          "data"
        ],
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of when the event was processed, in RFC 3339 format."
          },
          "type": {
            "type": "string",
            "enum": [
              "gateway_connectivity"
            ],
            "description": "Type of the alert event.\n- `gateway_connectivity`: Indicates a change in gateway connectivity status.\n"
          },
          "data": {
            "type": "object",
            "description": "Type-specific event payload.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/GatewayConnectivityEvent"
              }
            ]
          }
        },
        "examples": [
          {
            "timestamp": "2023-01-10T14:58:35.455152Z",
            "type": "gateway_connectivity",
            "data": {
              "timestamp": "2023-01-10T14:58:29.076699Z",
              "node_id": "FFFFA15A9C20F79F",
              "status": "offline"
            }
          }
        ]
      },
      "GatewayConnectivityEvent": {
        "description": "Event payload describing a gateway connectivity status change.",
        "type": "object",
        "required": [
          "node_id",
          "timestamp",
          "status"
        ],
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of when the connectivity status changed, in RFC 3339 format."
          },
          "node_id": {
            "type": "string",
            "description": "Unique `node_id` of the _Gateway_ whose connectivity status changed."
          },
          "status": {
            "type": "string",
            "enum": [
              "online",
              "offline"
            ],
            "description": "Current connectivity status of the _Gateway_.\n- `online`: Gateway is connected and communicating.\n- `offline`: Gateway is not communicating.\n"
          }
        }
      },
      "ConfigResponse": {
        "description": "The reported and desired configuration of a device, and who may set it.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "type": "object",
            "required": [
              "dev_eui",
              "owner_id",
              "control",
              "reported",
              "desired"
            ],
            "properties": {
              "dev_eui": {
                "type": "string",
                "description": "Device EUI (uppercase).",
                "example": "AABB1122CCDD3344"
              },
              "control": {
                "$ref": "#/components/schemas/ConfigControlSection",
                "description": "Who may set the device configuration, and when and by whom that was last decided."
              },
              "reported": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ReportedConfigSection"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Last configuration observed from a device uplink. `null` if the device\nhas never sent a config uplink.\n"
              },
              "desired": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DesiredConfigSection"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Most recent config rollout regardless of status. `null` if no rollout has\never been created for the device.\n"
              }
            }
          }
        ]
      },
      "ConfigControlSection": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "description": "Who may set this device's configuration.\n- `policy`: Any device configuration policy whose label selector the device matches may configure it.\n- `manual`: A person has claimed the device, so every policy that matches it stands aside and leaves its configuration alone.\n",
            "enum": [
              "policy",
              "manual"
            ],
            "example": "manual"
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When the control mode last changed. Absent for a device that has never left policy control.",
            "example": "2026-04-20T08:55:00Z"
          },
          "updated_by": {
            "type": ["string", "null"],
            "description": "Identity that last changed the control mode. Absent for a device that has never left policy control.",
            "example": "Job3ZjzC"
          }
        }
      },
      "ReportedConfigSection": {
        "type": "object",
        "required": [
          "config",
          "last_uplink_at"
        ],
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Decoded device configuration as reported by the device.",
            "example": {
              "report_interval_seconds": 300,
              "threshold_celsius": 25
            }
          },
          "last_uplink_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the uplink from which this config was last observed.",
            "example": "2026-04-18T10:00:00Z"
          }
        }
      },
      "DesiredConfigSection": {
        "type": "object",
        "required": [
          "config",
          "source_type",
          "status",
          "created_by",
          "updated_by",
          "created_at",
          "updated_at",
          "progress"
        ],
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "The desired configuration that was submitted.",
            "example": {
              "report_interval_seconds": 60,
              "threshold_celsius": 30
            }
          },
          "source_type": {
            "type": "string",
            "description": "How this desired config was created.\n- `manual`: Submitted by a user via the API.\n- `policy`: Applied automatically by a device configuration policy whose label selector the device matches.\n",
            "enum": [
              "manual",
              "policy"
            ],
            "example": "manual"
          },
          "policy_id": {
            "type": ["string", "null"],
            "description": "Identifier of the device configuration policy that created this desired config. Absent when `source_type` is `manual`.",
            "example": "Pol7KdmR"
          },
          "status": {
            "type": "string",
            "description": "Current lifecycle status of the rollout.\n- `pending`: Briefly transitional — rollout accepted but first fragment not yet scheduled for transmission.\n- `in_progress`: First fragment scheduled for transmission; delivery underway.\n- `applied`: All fragments confirmed.\n- `failed`: A fragment failed after exhausting retries.\n- `cancelled`: Cancelled via DELETE before completion.\n",
            "enum": [
              "pending",
              "in_progress",
              "applied",
              "failed",
              "cancelled"
            ],
            "example": "in_progress"
          },
          "failure_reason": {
            "type": ["string", "null"],
            "description": "Human-readable failure description. Present only when `status` is `failed`.",
            "example": "downlink delivery failed: tx error"
          },
          "created_by": {
            "type": "string",
            "description": "Identity that created the rollout.",
            "example": "Job3ZjzC"
          },
          "updated_by": {
            "type": "string",
            "description": "Identity that last updated the rollout.",
            "example": "Job3ZjzC"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-04-20T09:00:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-04-20T09:00:05Z"
          },
          "started_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When the first fragment entered `ready` state (i.e. when the rollout\ntransitioned to `in_progress`). `null` only while `status` is `pending`.\n",
            "example": "2026-04-20T09:00:05Z"
          },
          "completed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When the rollout reached a terminal state (`applied`, `failed`, or `cancelled`).\n`null` while the rollout is still active.\n",
            "example": "2026-04-20T09:01:00Z"
          },
          "progress": {
            "$ref": "#/components/schemas/DesiredConfigProgress",
            "description": "Fragment delivery progress. Always present."
          }
        }
      },
      "DesiredConfigProgress": {
        "type": "object",
        "required": [
          "total_fragments",
          "fragments_confirmed",
          "fragments"
        ],
        "properties": {
          "total_fragments": {
            "type": "integer",
            "description": "Total number of downlink fragments in this rollout.",
            "example": 2
          },
          "fragments_confirmed": {
            "type": "integer",
            "description": "Number of fragments that have been confirmed.",
            "example": 1
          },
          "fragments": {
            "type": "array",
            "description": "Per-fragment delivery state, ordered by sequence number.",
            "items": {
              "$ref": "#/components/schemas/DesiredConfigFragment"
            }
          }
        }
      },
      "DesiredConfigFragment": {
        "type": "object",
        "required": [
          "sequence",
          "status",
          "attempt_count"
        ],
        "properties": {
          "sequence": {
            "type": "integer",
            "description": "1-based position of this fragment within the rollout.",
            "example": 1
          },
          "status": {
            "type": "string",
            "description": "Current delivery status of this fragment.\n- `pending`: Not yet scheduled for transmission — either the rollout was just accepted or a prior fragment is still being confirmed.\n- `ready`: Scheduled for the next transmission attempt.\n- `queued`: Submitted to the network server.\n- `sent`: Network server confirmed gateway transmission.\n- `confirmed`: Device acknowledged (strategy-dependent).\n- `failed`: Delivery failed after retry exhaustion.\n- `cancelled`: Cancelled before confirmation.\n- `gateway_unavailable`: No connected gateway can reach the device; fragment is suspended and will resume automatically when device activity is observed.\n",
            "enum": [
              "pending",
              "ready",
              "queued",
              "sent",
              "confirmed",
              "failed",
              "cancelled",
              "gateway_unavailable"
            ],
            "example": "confirmed"
          },
          "attempt_count": {
            "type": "integer",
            "description": "Number of delivery attempts initiated for this fragment. Set to `1` when the\nfragment enters `ready` state (marking the start of the first ready→queued→sent\ncycle). Incremented on each retry. `0` only while the fragment is `pending`.\n",
            "example": 1
          },
          "ready_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this fragment most recently entered `ready` state. Reset on each retry, so it\nalways reflects the start of the current `ready→queued` delivery cycle. `null` for\n`pending` fragments and for fragments created before this field was introduced.\n",
            "example": "2026-04-20T09:00:04Z"
          },
          "queued_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When the fragment was submitted to the network server. `null` until `queued`.",
            "example": "2026-04-20T09:00:05Z"
          },
          "sent_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Gateway transmission timestamp reported by the network server. `null` until `sent`.\nThis is the network server's clock, not the API server's.\n",
            "example": "2026-04-20T09:00:06Z"
          },
          "confirmed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this fragment was confirmed (strategy-dependent). `null` until `confirmed`.",
            "example": "2026-04-20T09:00:08Z"
          },
          "gateway_unavailable_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this fragment entered `gateway_unavailable` state. Non-null only while the\nfragment is suspended waiting for device activity to resume. Cleared when the\nfragment returns to `ready`.\n",
            "example": "2026-04-20T09:00:09Z"
          }
        }
      },
      "ConfigHistoryResponse": {
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "records": {
            "type": "array",
            "description": "History entries ordered most-recent first.",
            "items": {
              "$ref": "#/components/schemas/HistoricalReportedConfig"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "ListMeta": {
        "type": "object",
        "required": [
          "more"
        ],
        "properties": {
          "next_page_token": {
            "type": "string",
            "description": "Opaque cursor for the next page. Pass as `page_token` on the next request.\nPresent only when `more` is `true`.\n",
            "example": "MjAyNi0wNS0yMFQxNDozMjowMC4xMjM0NTZa"
          },
          "more": {
            "type": "boolean",
            "description": "Whether a subsequent page of results exists. Always present.",
            "example": true
          }
        }
      },
      "HistoricalReportedConfig": {
        "type": "object",
        "required": [
          "config",
          "observed_at"
        ],
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Decoded device configuration as reported at this point in time.",
            "example": {
              "report_interval_seconds": 60,
              "threshold_celsius": 30
            }
          },
          "observed_at": {
            "type": "string",
            "format": "date-time",
            "description": "When this configuration was first observed — the moment the reported-config\nchange was detected from an uplink. Microsecond precision.\n",
            "example": "2026-05-20T14:32:00.123456Z"
          }
        }
      },
      "PutDesiredConfigRequest": {
        "type": "object",
        "required": [
          "config"
        ],
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Desired device configuration. The structure is codec-specific — the device's\ncodec type determines how this object is validated and encoded into downlink\nfragments.\n",
            "example": {
              "report_interval_seconds": 60,
              "threshold_celsius": 30
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Human-readable description of the error.",
            "example": "device not found"
          }
        }
      },
      "DeviceLabels": {
        "description": "Labels attached to a device, as a map of `key`/`value` pairs. An empty object means the device carries no labels.",
        "type": "object",
        "additionalProperties": {
          "type": "string",
          "description": "Value assigned to the label key. Any key may be supplied; 1 to 128 characters, spaces and mixed case allowed."
        }
      },
      "LabelSelectorRequirement": {
        "description": "A single requirement on a label key. A device must satisfy every requirement in the selector.",
        "type": "object",
        "required": [
          "key",
          "operator",
          "values"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Label key to match. Lowercased and trimmed before matching. Required.",
            "example": "env"
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "in"
            ],
            "description": "Comparison to apply. Required. `eq` matches a single exact value; `in` matches any one of the given values.",
            "example": "eq"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values to compare against. Required. `eq` takes exactly one value; `in` takes at least one. Values are trimmed, case-preserved, and must be unique within a requirement.",
            "example": [
              "prod"
            ]
          }
        }
      },
      "LabelSelector": {
        "description": "A conjunction of label requirements. A device matches when it satisfies every one. Must contain at least one requirement, and each key may appear only once.",
        "type": "array",
        "minItems": 1,
        "items": {
          "$ref": "#/components/schemas/LabelSelectorRequirement"
        }
      },
      "SearchDevicesByLabelsRequest": {
        "description": "A request to search devices by label selector.",
        "type": "object",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "$ref": "#/components/schemas/LabelSelector"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "default": 100,
            "description": "Maximum number of devices to return in this page. Defaults to 100. Large values are clamped to a server-side maximum.",
            "example": 50
          },
          "page_token": {
            "type": "string",
            "description": "Opaque pagination cursor from `meta.next_page_token` in the previous response. Omit to request the first page.",
            "example": "WyJpWGVvd0RZTyIsIjJDQzQwN0ZGRkU1MTcwMzgiXQ"
          },
          "include_count": {
            "type": "boolean",
            "default": false,
            "description": "Whether to also count every matching device. True returns the total across all pages in `meta.total_count` and slows the response; false omits the count. Defaults to false.",
            "example": true
          }
        }
      },
      "DeviceMatchRecord": {
        "description": "A device matching a label selector.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "type": "object",
            "required": [
              "owner_id",
              "dev_eui"
            ],
            "properties": {
              "dev_eui": {
                "type": "string",
                "description": "Extended Unique Identifier of the matching device.",
                "example": "2CC407FFFE517038"
              }
            }
          }
        ]
      },
      "DeviceSearchMeta": {
        "description": "Pagination metadata for a label search response, with an optional total match count.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "properties": {
              "total_count": {
                "type": "integer",
                "description": "Total number of matching devices across all pages. Present only when the request set `include_count` to `true`.\n",
                "example": 42
              }
            }
          }
        ]
      },
      "DeviceSearchResponse": {
        "description": "A paginated list of devices matching a label selector.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "records": {
            "type": "array",
            "description": "Matching devices ordered by `dev_eui`.",
            "items": {
              "$ref": "#/components/schemas/DeviceMatchRecord"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/DeviceSearchMeta"
          }
        }
      },
      "DeviceSearchNDJSONStream": {
        "description": "NDJSON stream represented as an array for documentation purposes. In the actual response each element is a newline-delimited JSON object. Data records come first; the final element is always a metadata object with a `meta` key. Absence of the final metadata element indicates a mid-stream error, so an unexpected EOF should be treated as a failure. Send `Accept: application/jsonl` to receive `Content-Type: application/jsonl` instead; the server echoes the media type the client requested and the body is identical.",
        "type": "array",
        "items": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/DeviceMatchRecord"
            },
            {
              "type": "object",
              "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
              "required": [
                "meta"
              ],
              "properties": {
                "meta": {
                  "$ref": "#/components/schemas/DeviceSearchMeta"
                }
              }
            }
          ]
        }
      },
      "LabelKeyRecord": {
        "description": "A label key in use.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "type": "object",
            "required": [
              "owner_id",
              "key"
            ],
            "properties": {
              "key": {
                "type": "string",
                "description": "Label key in use.",
                "example": "env"
              }
            }
          }
        ]
      },
      "LabelValueRecord": {
        "description": "A label value in use for the requested key.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "type": "object",
            "required": [
              "owner_id",
              "value"
            ],
            "properties": {
              "value": {
                "type": "string",
                "description": "Value in use for the requested key.",
                "example": "prod"
              }
            }
          }
        ]
      },
      "LabelKeysResponse": {
        "description": "A paginated list of the label keys in use.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "records": {
            "type": "array",
            "description": "Distinct label keys ordered by `key`.",
            "items": {
              "$ref": "#/components/schemas/LabelKeyRecord"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "LabelValuesResponse": {
        "description": "A paginated list of the values in use for a label key.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "records": {
            "type": "array",
            "description": "Distinct values ordered by `value`.",
            "items": {
              "$ref": "#/components/schemas/LabelValueRecord"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "LabelKeysNDJSONStream": {
        "description": "NDJSON stream represented as an array for documentation purposes. In the actual response each element is a newline-delimited JSON object. Data records come first; the final element is always a metadata object with a `meta` key. Absence of the final metadata element indicates a mid-stream error, so an unexpected EOF should be treated as a failure. Send `Accept: application/jsonl` to receive `Content-Type: application/jsonl` instead; the server echoes the media type the client requested and the body is identical.",
        "type": "array",
        "items": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/LabelKeyRecord"
            },
            {
              "type": "object",
              "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
              "required": [
                "meta"
              ],
              "properties": {
                "meta": {
                  "$ref": "#/components/schemas/ListMeta"
                }
              }
            }
          ]
        }
      },
      "LabelValuesNDJSONStream": {
        "description": "NDJSON stream represented as an array for documentation purposes. In the actual response each element is a newline-delimited JSON object. Data records come first; the final element is always a metadata object with a `meta` key. Absence of the final metadata element indicates a mid-stream error, so an unexpected EOF should be treated as a failure. Send `Accept: application/jsonl` to receive `Content-Type: application/jsonl` instead; the server echoes the media type the client requested and the body is identical.",
        "type": "array",
        "items": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/LabelValueRecord"
            },
            {
              "type": "object",
              "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
              "required": [
                "meta"
              ],
              "properties": {
                "meta": {
                  "$ref": "#/components/schemas/ListMeta"
                }
              }
            }
          ]
        }
      },
      "DeviceConfigPolicy": {
        "description": "A device configuration applied automatically to every device a label selector matches.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Identifiable"
          },
          {
            "$ref": "#/components/schemas/Owned"
          },
          {
            "type": "object",
            "required": [
              "id",
              "owner_id",
              "name",
              "codec_id",
              "config",
              "priority",
              "status",
              "selector",
              "created_at",
              "created_by",
              "updated_at",
              "updated_by"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "Human-readable name for the policy. Required. Must not be blank, and must be unique within the account.",
                "example": "Production sensors"
              },
              "codec_id": {
                "type": "string",
                "description": "Unique identifier of the codec the configuration is authored against. Required. Only devices using this codec are matched, because the configuration is meaningful to that codec alone.",
                "example": "my-sensor-v1"
              },
              "config": {
                "type": "object",
                "additionalProperties": true,
                "description": "Desired device configuration the policy applies, in the format the codec accepts. Required. Validated against `codec_id` on write and rejected when the codec does not accept it.",
                "example": {
                  "report_interval_seconds": 60,
                  "threshold_celsius": 30
                }
              },
              "priority": {
                "type": "integer",
                "minimum": 0,
                "description": "Resolves conflicts when several policies match the same device. The highest priority wins and the others stand down for that device.",
                "example": 10
              },
              "status": {
                "type": "string",
                "enum": [
                  "enabled",
                  "disabled"
                ],
                "description": "Whether the policy applies to the devices it matches. Read-only, changed through the enable and disable endpoints rather than by writing it.\n- `enabled`: The policy applies to the devices it matches.\n- `disabled`: The policy applies to no devices. New policies start here.\n",
                "example": "enabled"
              },
              "selector": {
                "$ref": "#/components/schemas/LabelSelector",
                "description": "Label selector choosing the devices the policy applies to. Required. Must contain at least one requirement."
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the policy was created.",
                "example": "2026-08-14T10:15:00Z"
              },
              "created_by": {
                "type": "string",
                "description": "Identity that created the policy.",
                "example": "Job3ZjzC"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the policy was last changed. Equal to `created_at` until the policy is first changed.",
                "example": "2026-08-20T16:42:00Z"
              },
              "updated_by": {
                "type": "string",
                "description": "Identity that last changed the policy.",
                "example": "Job3ZjzC"
              }
            }
          }
        ]
      },
      "CreateDeviceConfigPolicyRequest": {
        "description": "A request to create a device configuration policy.",
        "type": "object",
        "required": [
          "name",
          "codec_id",
          "config",
          "selector"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name for the policy. Required. Must not be blank, and must be unique within the account.",
            "example": "Production sensors"
          },
          "codec_id": {
            "type": "string",
            "description": "Unique identifier of the codec the configuration is authored against. Required. Only devices using this codec are matched, because the configuration is meaningful to that codec alone.",
            "example": "my-sensor-v1"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Desired device configuration the policy applies, in the format the codec accepts. Required. Validated against `codec_id` on write and rejected when the codec does not accept it.",
            "example": {
              "report_interval_seconds": 60,
              "threshold_celsius": 30
            }
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "description": "Resolves conflicts when several policies match the same device. The highest priority wins and the others stand down for that device. Optional, defaulting to 0. Must not be negative.",
            "example": 10
          },
          "selector": {
            "$ref": "#/components/schemas/LabelSelector",
            "description": "Label selector choosing the devices the policy applies to. Required. Must contain at least one requirement."
          }
        }
      },
      "UpdateDeviceConfigPolicyRequest": {
        "description": "A complete representation of a device configuration policy, replacing the stored one.",
        "type": "object",
        "required": [
          "name",
          "codec_id",
          "config",
          "priority",
          "selector"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name for the policy. Required. Must not be blank, and must be unique within the account.",
            "example": "Production sensors"
          },
          "codec_id": {
            "type": "string",
            "description": "Unique identifier of the codec the configuration is authored against. Required. Only devices using this codec are matched, because the configuration is meaningful to that codec alone.",
            "example": "my-sensor-v1"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Desired device configuration the policy applies, in the format the codec accepts. Required. Validated against `codec_id` on write and rejected when the codec does not accept it.",
            "example": {
              "report_interval_seconds": 60,
              "threshold_celsius": 30
            }
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "description": "Resolves conflicts when several policies match the same device. The highest priority wins and the others stand down for that device. Required, because a complete representation carries it. Must not be negative.",
            "example": 10
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ],
            "description": "Status the policy already has. Optional, and accepted only so a policy read with `GET` can be written back unchanged. Supplying a status different from the current one is rejected; use the enable and disable endpoints to change it.",
            "example": "enabled"
          },
          "selector": {
            "$ref": "#/components/schemas/LabelSelector",
            "description": "Label selector choosing the devices the policy applies to. Required. Must contain at least one requirement."
          }
        }
      },
      "ListDeviceConfigPoliciesResponse": {
        "description": "A paginated list of device configuration policies.",
        "type": "object",
        "required": [
          "records",
          "meta"
        ],
        "properties": {
          "records": {
            "type": "array",
            "description": "Device config policies ordered by `id`.",
            "items": {
              "$ref": "#/components/schemas/DeviceConfigPolicy"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "DeviceConfigPoliciesNDJSONStream": {
        "description": "NDJSON stream represented as an array for documentation purposes. In the actual response each element is a newline-delimited JSON object. Data records come first; the final element is always a metadata object with a `meta` key. Absence of the final metadata element indicates a mid-stream error, so an unexpected EOF should be treated as a failure. Send `Accept: application/jsonl` to receive `Content-Type: application/jsonl` instead; the server echoes the media type the client requested and the body is identical.",
        "type": "array",
        "items": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/DeviceConfigPolicy"
            },
            {
              "type": "object",
              "description": "Final metadata line. Clients distinguish it from data records by the presence of the `meta` key.",
              "required": [
                "meta"
              ],
              "properties": {
                "meta": {
                  "$ref": "#/components/schemas/ListMeta"
                }
              }
            }
          ]
        }
      }
    },
    "requestBodies": {
      "OutputDestinationRequestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OutputDestination"
            },
            "examples": {
              "Webhook": {
                "value": {
                  "name": "CorbyCorp Webhook Event Monitor",
                  "type": "webhook",
                  "enabled": true,
                  "credentials_id": "xLu4B38N",
                  "data": {
                    "url": "https://monitor.corbycorp.com/gateways/alerts",
                    "headers": [
                      {
                        "header": "api_key",
                        "value": "YWxramRhc2RnYXNkZ2FzZGdsYXNkZ2FzZAo="
                      },
                      {
                        "header": "accept",
                        "value": "application/json"
                      }
                    ]
                  }
                }
              },
              "Azure IoT Hub": {
                "value": {
                  "name": "CorbyCorp IoTHub Event Monitor",
                  "type": "azure_iot_hub",
                  "enabled": true,
                  "credentials_id": "GRVVcAC-",
                  "data": {
                    "host": "corbycorp-hub.azure-devices.net"
                  }
                }
              },
              "MQTT": {
                "value": {
                  "name": "CorbyCorp MQTT Event Monitor",
                  "type": "mqtt",
                  "enabled": true,
                  "credentials_id": "5DFk8vzO",
                  "data": {
                    "host": "corbycorp-mqtt:8883",
                    "topic": "machineq/output/events",
                    "tls_enabled": true,
                    "custom_client_id": "/devices/${DEVEUI}/${FPORT}"
                  }
                }
              },
              "AWS IoT Core": {
                "value": {
                  "name": "CorbyCorp Iot Core Event Monitor",
                  "type": "aws_iot_core",
                  "enabled": true,
                  "credentials_id": "Tz07qwZq",
                  "data": {
                    "endpoint": "corbycorp-thing.iot.us-east-1.amazonaws.com"
                  }
                }
              }
            }
          }
        }
      },
      "OutputCredentialsRequestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OutputCredentials"
            },
            "examples": {
              "BasicAuth": {
                "value": {
                  "name": "CorbyCorp user auth",
                  "type": "basic_auth",
                  "data": {
                    "username": "gateway_monitor",
                    "password": "$ecret!"
                  }
                }
              },
              "ClientCredentials": {
                "value": {
                  "name": "CorbyCorp websec client",
                  "type": "client_credentials",
                  "data": {
                    "client_id": "gateway_monitor",
                    "client_secret": "dnwnvwtqylskrlvzushd",
                    "auth_url": "https://oauth.corbycorp.com/oauth2/token",
                    "scopes": "alert:reader gateway:admin",
                    "audience": "https://api.corbycorp.net"
                  }
                }
              },
              "X509Certificate": {
                "value": {
                  "name": "CorbyCorp X509 cert",
                  "type": "x509_certificate",
                  "data": {
                    "public_key": "-----BEGIN CERTIFICATE-----\nMIICuTCCAl6gAwIBAgIUPBcCp/humG2kg2I7dKdblhsndzcwCgYIKoZIzj0EAwIw...n9uSb6PE0Q1XejUiVCtY8gAgJnzoc4dzsTQNNsg=\n-----END CERTIFICATE-----",
                    "private_key": "-----BEGIN PRIVATE KEY-----\nMHcCAQEEIKtpBmtz3AmjzovVIoslZ2bu12zKiWHxiAArmQWAoHU8oAoGCCqGSM49...xveOJ4==\n-----END PRIVATE KEY-----"
                  }
                }
              },
              "AzureSharedAccessPolicy": {
                "value": {
                  "name": "CorbyCorp Iot Hub Owner",
                  "type": "azure_shared_access_policy",
                  "data": {
                    "policy_name": "iothubowner",
                    "shared_access_key": "TMjz20pTp19zBeH6yt7Ugb7sJ04Qk4JdTlkach99pNHU="
                  }
                }
              }
            }
          }
        }
      }
    },
    "responses": {
      "IdentifiableOutputCredentialsSuccessResponse": {
        "description": "Successful response containing the output credentials",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SafeIdentifiableOutputCredentials"
            }
          }
        }
      },
      "OutputCredentialsNotFoundErrorResponse": {
        "description": "Output credentials not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Could not find Credentials identified by 'iN0pLTEv'"
            }
          }
        }
      },
      "OutputCredentialsInvalidInputErrorResponse": {
        "description": "Invalid output credentials input",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Credentials are not valid: 'name' is required."
            }
          }
        }
      },
      "IdentifiableOutputDestinationSuccessResponse": {
        "description": "Successful response containing the output destination",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/IdentifiableOutputDestination"
            }
          }
        }
      },
      "OutputDestinationNotFoundErrorResponse": {
        "description": "Output destination not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Could not find Destination identified by '2Daub56g'"
            }
          }
        }
      },
      "OutputDestinationInvalidInputErrorResponse": {
        "description": "Invalid output destination input",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Destination is not valid: 'name' is required."
            }
          }
        }
      },
      "IdentifiableOutputAlertSuccessResponse": {
        "description": "Successful response containing the output alert",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/IdentifiableOutputAlert"
            }
          }
        }
      },
      "OutputAlertNotFoundErrorResponse": {
        "description": "Output alert not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Could not find Alert identified by 'TGexoQsP'"
            }
          }
        }
      },
      "OutputAlertInvalidInputErrorResponse": {
        "description": "Invalid output alert input",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "Alert is not valid: 'name' is required."
            }
          }
        }
      },
      "UnauthorizedErrorResponse": {
        "description": "Missing or invalid authorization token",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "code": 16,
              "message": "invalid token or token is expired."
            }
          }
        }
      },
      "InternalServerErrorResponse": {
        "description": "Unexpected internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Non2XXResponse"
            },
            "example": {
              "message": "unexpected error occurred, please try the request again."
            }
          }
        }
      },
      "BadRequest": {
        "description": "Invalid request — the message field describes the specific problem",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "Invalid request parameter: 'dev_eui' must be a valid device EUI (16 hexadecimal characters)"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid authentication credentials",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "unauthorized"
            }
          }
        }
      },
      "NotFound": {
        "description": "Device not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "device not found for dev_eui: AABB1122CCDD3344"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Unexpected internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "internal server error"
            }
          }
        }
      },
      "InvalidLabel": {
        "description": "A label key or value is invalid, or the body is not a JSON object of strings",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "invalid_key": {
                "summary": "Key contains an illegal character",
                "value": {
                  "message": "label key \"bad key\" must contain only lowercase letters, digits, '.', '_' or '-' and start and end with a letter or digit"
                }
              },
              "value_too_long": {
                "summary": "Value exceeds the length cap",
                "value": {
                  "message": "label value must be 1 to 128 characters, got 140"
                }
              },
              "duplicate_key": {
                "summary": "Two keys collide after normalization",
                "value": {
                  "message": "duplicate label key after normalization: \"env\""
                }
              }
            }
          }
        }
      },
      "DeviceConfigPolicySuccess": {
        "description": "Successful response containing the device configuration policy",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DeviceConfigPolicy"
            },
            "example": {
              "id": "kR3mQ7xa",
              "owner_id": "iXeowDYO",
              "name": "Production sensors",
              "codec_id": "my-sensor-v1",
              "config": {
                "report_interval_seconds": 60,
                "threshold_celsius": 30
              },
              "priority": 10,
              "status": "enabled",
              "selector": [
                {
                  "key": "env",
                  "operator": "eq",
                  "values": [
                    "prod"
                  ]
                }
              ],
              "created_at": "2026-08-14T10:15:00Z",
              "created_by": "Job3ZjzC",
              "updated_at": "2026-08-20T16:42:00Z",
              "updated_by": "Job3ZjzC"
            }
          }
        }
      },
      "DeviceConfigPolicyNotFound": {
        "description": "No device configuration policy with the given identifier exists for the account",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "could not find device configuration policy identified by 'kR3mQ7xa'"
            }
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Device",
      "tags": [
        "Devices",
        "Device Configuration",
        "Device Labels",
        "Device Configuration Policies"
      ]
    },
    {
      "name": "Labels",
      "tags": [
        "Labels"
      ]
    },
    {
      "name": "Output System",
      "tags": [
        "Overview",
        "Output Credentials",
        "Output Destinations",
        "Output Alerts",
        "Output Events"
      ]
    }
  ],
  "x-resourceObjects": {
    "Devices": "Device",
    "Device Configuration": "ConfigResponse",
    "Labels": "LabelKeyRecord",
    "Output Credentials": "IdentifiableOutputCredentials",
    "Output Destinations": "IdentifiableOutputDestination",
    "Output Alerts": "IdentifiableOutputAlert",
    "Output Events": "GatewayConnectivityEvent",
    "Device Configuration Policies": "DeviceConfigPolicy"
  }
}
