{
  "components": {
    "schemas": {
      "alarm_rule": {
        "properties": {
          "activation": {
            "type": "object"
          },
          "check_interval": {
            "properties": {
              "magnitude": {
                "enum": [
                  "second",
                  "minute",
                  "hour",
                  "day",
                  "week",
                  "month",
                  "year"
                ],
                "type": "string"
              },
              "value": {
                "minimum": 0,
                "type": "number"
              }
            },
            "type": "object"
          },
          "data": {
            "type": "object"
          },
          "description": {
            "$ref": "#/components/schemas/resource_description"
          },
          "name": {
            "$ref": "#/components/schemas/resource_name"
          },
          "normalization": {
            "type": "object"
          },
          "reminder": {
            "type": "object"
          },
          "rule": {
            "$ref": "#/components/schemas/resource_id"
          },
          "severity": {
            "maximum": 4,
            "minimum": 0,
            "type": "number"
          }
        },
        "title": "Alarm Rule",
        "type": "object"
      },
      "bucket_backend": {
        "description": "Specifies the database backend to use for storage, with an option for default (represented by an empty string), 'mongodb', or 'influxdb'.",
        "enum": [
          "",
          "mongodb",
          "influxdb",
          "dynamodb"
        ],
        "title": "Bucket Backend",
        "type": "string"
      },
      "bucket_config": {
        "description": "Configuration schema for a data bucket specifying how data is sourced and updated. This schema supports multiple source types including devices and MQTT topics, each with its own set of required properties.",
        "oneOf": [
          {
            "additionalProperties": false,
            "description": "Configuration for data sourced from a device. This requires specifying the device, user, resource, update interval, and optional tags.",
            "properties": {
              "device": {
                "$ref": "#/components/schemas/resource_id",
                "description": "The unique identifier for the device."
              },
              "interval": {
                "description": "The time between updates, in seconds.",
                "type": "number"
              },
              "resource": {
                "description": "The specific resource from the device being tracked.",
                "maxLength": 255,
                "type": "string"
              },
              "source": {
                "description": "Indicates the data source is a device.",
                "enum": [
                  "device"
                ],
                "type": "string"
              },
              "tags": {
                "description": "A collection of tags for categorization, limited to 5.",
                "items": {
                  "$ref": "#/components/schemas/resource_id"
                },
                "maxItems": 5,
                "type": "array"
              },
              "update": {
                "description": "Specifies that the bucket is updated at regular intervals.",
                "enum": [
                  "interval"
                ],
                "type": "string"
              },
              "user": {
                "$ref": "#/components/schemas/resource_id",
                "description": "The unique identifier for the user associated with this bucket."
              }
            },
            "required": [
              "source",
              "device",
              "resource",
              "update",
              "interval"
            ],
            "type": "object"
          },
          {
            "additionalProperties": false,
            "description": "Configuration for data sourced from a device with event-based or no updates. This variation does not require an interval.",
            "properties": {
              "device": {
                "$ref": "#/components/schemas/resource_id",
                "description": "The unique identifier for the device."
              },
              "resource": {
                "description": "The specific resource from the device being tracked.",
                "maxLength": 255,
                "type": "string"
              },
              "source": {
                "description": "Indicates the data source is a device.",
                "enum": [
                  "device"
                ],
                "type": "string"
              },
              "tags": {
                "description": "A collection of tags for categorization, limited to 5.",
                "items": {
                  "$ref": "#/components/schemas/resource_id"
                },
                "maxItems": 5,
                "type": "array"
              },
              "update": {
                "description": "Specifies how the bucket is updated: either by specific events or not updated automatically.",
                "enum": [
                  "events",
                  "none"
                ],
                "type": "string"
              },
              "user": {
                "$ref": "#/components/schemas/resource_id",
                "description": "The unique identifier for the user associated with this bucket."
              }
            },
            "required": [
              "source",
              "device",
              "resource",
              "update"
            ],
            "type": "object"
          },
          {
            "additionalProperties": false,
            "description": "Configuration for data sourced from an MQTT topic. This requires specifying the topic and allows optional tags.",
            "properties": {
              "source": {
                "description": "Indicates the data source is an MQTT topic.",
                "enum": [
                  "mqtt"
                ],
                "type": "string"
              },
              "tags": {
                "description": "A collection of tags for categorization, limited to 5.",
                "items": {
                  "$ref": "#/components/schemas/resource_id"
                },
                "maxItems": 5,
                "type": "array"
              },
              "topic": {
                "description": "The MQTT topic from which data is sourced.",
                "maxLength": 512,
                "type": "string"
              }
            },
            "required": [
              "source",
              "topic"
            ],
            "type": "object"
          },
          {
            "additionalProperties": false,
            "description": "Configuration for data manually written or provided via an API. This variation only requires source specification and allows optional tags.",
            "properties": {
              "source": {
                "description": "Indicates the data source is either manually written ('write') or sourced via an API ('api').",
                "enum": [
                  "write",
                  "api"
                ],
                "type": "string"
              },
              "tags": {
                "description": "A collection of tags for categorization, limited to 5.",
                "items": {
                  "$ref": "#/components/schemas/resource_id"
                },
                "maxItems": 5,
                "type": "array"
              }
            },
            "required": [
              "source"
            ],
            "type": "object"
          }
        ],
        "title": "Bucket Config"
      },
      "bucket_retention": {
        "description": "Configuration schema for data bucket retention policy.",
        "properties": {
          "period": {
            "description": "The duration of the retention period. 0 for unlimited retention.",
            "examples": [
              30
            ],
            "minimum": 0,
            "type": "integer"
          },
          "unit": {
            "description": "The unit of measurement for the retention period.",
            "enum": [
              "hours",
              "days",
              "weeks",
              "months",
              "years"
            ],
            "examples": [
              "days"
            ],
            "type": "string"
          }
        },
        "required": [],
        "title": "Bucket Retention",
        "type": "object"
      },
      "claim_config": {
        "additionalProperties": false,
        "properties": {
          "domain": {
            "pattern": "^([a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\\.[a-zA-Z]{2,11}?$",
            "type": "string"
          },
          "max_claims": {
            "minimum": 0,
            "type": "integer"
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/resource_id"
            },
            "type": "array"
          },
          "members_roles": {
            "items": {
              "$ref": "#/components/schemas/resource_id"
            },
            "type": "array"
          },
          "projects": {
            "items": {
              "$ref": "#/components/schemas/resource_id"
            },
            "type": "array"
          },
          "resources": {
            "items": {
              "properties": {
                "identifiers": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "type": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "resources"
        ],
        "title": "Claim Config",
        "type": "object"
      },
      "comparison_expressions": {
        "description": "Comparison expressions for conditional evaluation. Every comparison but present / absent is false on a missing field.",
        "enum": [
          "above",
          "below",
          "equal",
          "not_equal",
          "inside",
          "outside",
          "present",
          "absent"
        ],
        "title": "Comparison Expressions",
        "type": "string"
      },
      "operator_expressions": {
        "description": "Operator expressions for conditional evaluation",
        "enum": [
          "and",
          "or"
        ],
        "title": "Operator Expressions",
        "type": "string"
      },
      "permission": {
        "patternProperties": {
          "^[a-zA-Z0-9_-]{1,32}$|^\\*$": {
            "minProperties": 1,
            "patternProperties": {
              "^[a-zA-Z0-9_]{1,32}(?:@[a-zA-Z0-9_]{1,32})?$|^\\*$": {
                "oneOf": [
                  {
                    "pattern": "^[a-zA-Z0-9_\\*]{1,64}$|^\\*$",
                    "type": "string"
                  },
                  {
                    "items": {
                      "oneOf": [
                        {
                          "pattern": "^[a-zA-Z0-9_\\*]{1,64}$|^\\*$",
                          "type": "string"
                        },
                        {
                          "patternProperties": {
                            "^[a-zA-Z0-9_-]{1,32}$": {
                              "oneOf": [
                                {
                                  "pattern": "^[a-zA-Z0-9_\\*]{1,32}$|^\\*$",
                                  "type": "string"
                                },
                                {
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              ]
                            }
                          },
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  }
                ]
              }
            }
          }
        },
        "title": "Permission",
        "type": "object"
      },
      "product_conditional_icon": {
        "additionalProperties": false,
        "description": "Conditional Icon schema for a product",
        "properties": {
          "conditions": {
            "items": {
              "oneOf": [
                {
                  "additionalProperties": false,
                  "properties": {
                    "comparison": {
                      "$ref": "#/components/schemas/comparison_expressions"
                    },
                    "field": {
                      "maxLength": 255,
                      "minLength": 1,
                      "type": "string"
                    },
                    "operator": {
                      "$ref": "#/components/schemas/operator_expressions"
                    },
                    "tag": {
                      "type": "string"
                    },
                    "value": {
                      "maxLength": 255,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "value"
                  ]
                },
                {
                  "additionalProperties": false,
                  "properties": {
                    "comparison": {
                      "$ref": "#/components/schemas/comparison_expressions"
                    },
                    "field": {
                      "maxLength": 255,
                      "minLength": 1,
                      "type": "string"
                    },
                    "max": {
                      "maxLength": 255,
                      "minLength": 1,
                      "type": "string"
                    },
                    "min": {
                      "maxLength": 255,
                      "minLength": 1,
                      "type": "string"
                    },
                    "operator": {
                      "$ref": "#/components/schemas/operator_expressions"
                    },
                    "tag": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "min",
                    "max"
                  ]
                }
              ],
              "required": [
                "comparison",
                "field",
                "operator",
                "tag"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "icon": {
            "$ref": "#/components/schemas/product_icon"
          }
        },
        "required": [
          "icon"
        ],
        "title": "Product Conditional Icon",
        "type": "object"
      },
      "product_config": {
        "additionalProperties": false,
        "description": "Configuration schema for a product",
        "properties": {
          "fields": {
            "items": {
              "$ref": "#/components/schemas/product_field"
            },
            "type": "array"
          },
          "icons": {
            "items": {
              "$ref": "#/components/schemas/product_conditional_icon"
            },
            "type": "array"
          },
          "type": {
            "description": "Product type that determines the device status view",
            "enum": [
              "",
              "thinremote"
            ],
            "type": "string"
          }
        },
        "required": [],
        "title": "Product Config",
        "type": "object"
      },
      "product_field": {
        "additionalProperties": false,
        "description": "Field schema for a product",
        "properties": {
          "icon": {
            "$ref": "#/components/schemas/product_icon"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "type": "string"
          },
          "primary": {
            "type": "boolean"
          },
          "type": {
            "enum": [
              "string",
              "number",
              "date",
              "time",
              "datetime",
              "timeago"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "title": "Product Field",
        "type": "object"
      },
      "product_icon": {
        "additionalProperties": false,
        "description": "Icon schema for a product",
        "properties": {
          "background": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "size": {
            "type": "number"
          },
          "source": {
            "type": "string"
          },
          "type": {
            "description": "Icon type: font-awesome or svg",
            "enum": [
              "fa",
              "svg"
            ],
            "type": "string"
          }
        },
        "required": [
          "type",
          "source"
        ],
        "title": "Product Icon",
        "type": "object"
      },
      "product_profile_category": {
        "additionalProperties": {
          "$ref": "#/components/schemas/product_profile_entry"
        },
        "description": "Every entry of a category, by id. Replaces the whole category: entries missing from the body are removed (for properties, also the default property on the devices).",
        "title": "Product profile category",
        "type": [
          "object",
          "null"
        ]
      },
      "product_profile_code": {
        "description": "JavaScript run by the server for this product: functions referenced by payload_function, device_id_resolver and function targets. Inline in `code`, or the files of a file storage in `storage` (takes precedence): its `index.js`, or `<path>/index.js` with `path`, so one storage can hold a whole application (dashboard, product code…).",
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "path": {
            "description": "Folder of the storage with the code (its index.js and node_modules), relative to the storage root, e.g. \"code/meter\". Empty: the storage root.",
            "type": [
              "string",
              "null"
            ]
          },
          "storage": {
            "description": "File storage id with the product code.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "Product profile code",
        "type": [
          "object",
          "null"
        ]
      },
      "product_profile_entry": {
        "description": "One entry of a product profile category; its id is the {resource} path parameter (or the key in a category body). Entries only run when `enabled` is true. Fields by category. properties: `data` fills the device property of the same id (optional), `default.value` (any value but null: {}, [], \"\", 0 and false count) / `form` / `perm` make it a property of the product, which every device of the product inherits (source: product) until it sets its own. buckets: `data` writes into the bucket with the entry id, created on the first write, outside any project (devices read it through GET /devices/{device}/buckets/{bucket}/data); an id containing {{device}} gives one bucket per device (such ids only fit the whole-category PUT, as the {resource} path parameter cannot hold braces), otherwise one shared bucket tagged with device (and group); `tags`, `backend`, `retention`. flows: `data` → `sink`, `split_data` sends each array element separately. api: resources added to every device of the product: `request.data` (target), `response.data` (response), `device_id_resolver` (function of the product code that returns the device id from the payload, needed to call the resource through POST /products/{product}/resources/{resource}), `handle_connectivity` (validate / auto-provision the device on calls; default true for resource_stream targets). autoprovisions: `config`. endpoints: deprecated, use flows with an endpoint_call sink.",
        "properties": {
          "backend": {
            "description": "buckets: storage backend of the bucket when it is created (mongodb, influxdb, dynamodb; default the server's)."
          },
          "config": {
            "description": "autoprovisions: when a device that does not exist authenticates or calls a resource and its id matches `pattern`, it is created in this product (HTTP, or Subdevice for MQTT), with asset `type` / `group` and `project` if given.",
            "properties": {
              "group": {
                "description": "Asset group for the new devices.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "description": "pattern",
                "type": [
                  "string",
                  "null"
                ]
              },
              "pattern": {
                "description": "Regular expression on the device id, e.g. ^meter_[0-9]{6}$.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "project": {
                "description": "Project for the new devices.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "type": {
                "description": "Asset type for the new devices.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/product_profile_source"
              },
              {
                "items": {
                  "$ref": "#/components/schemas/product_profile_source"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Data source, or an array of sources."
          },
          "default": {
            "description": "properties: value of the product property that the devices inherit until they set their own, in `value`. Any value but null counts, {} and [] included.",
            "properties": {
              "value": {}
            },
            "type": [
              "object",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "device_id_resolver": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "form": {
            "description": "properties: form used by the console to edit the value (`fields`).",
            "type": [
              "object",
              "null"
            ]
          },
          "handle_connectivity": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "perm": {
            "description": "properties: console permissions, as the roles that do not see the property (hidden) or cannot edit it (readOnly); as in device properties.",
            "properties": {
              "hidden": {
                "items": {
                  "enum": [
                    "owner",
                    "member"
                  ],
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ],
                "uniqueItems": true
              },
              "readOnly": {
                "items": {
                  "enum": [
                    "owner",
                    "member"
                  ],
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ],
                "uniqueItems": true
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "request": {
            "properties": {
              "data": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/product_profile_target"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "response": {
            "properties": {
              "data": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/product_profile_response"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "retention": {
            "description": "buckets: retention of the bucket when it is created.",
            "properties": {
              "period": {
                "description": "0 = unlimited.",
                "type": [
                  "integer",
                  "string",
                  "null"
                ]
              },
              "unit": {
                "description": "hours | days | weeks | months | years",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "sink": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/product_profile_target"
              },
              {
                "type": "null"
              }
            ]
          },
          "split_data": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "tags": {
            "description": "buckets: record fields stored as tags (filterable), e.g. [\"line\"].",
            "type": [
              "array",
              "null"
            ]
          },
          "type": {
            "description": "properties: \"\" or configuration.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "Product profile entry",
        "type": [
          "object",
          "null"
        ]
      },
      "product_profile_payload_type": {
        "description": "How the payload is built. template_payload (default): `payload` is a template that may use {{payload}}, {{payload.field}}, {{device}}, {{property.<name>}}, {{api.<resource>}} or {{meta.<device field>}}; without `payload` it yields nothing, so a properties or buckets entry writes nothing. source_payload: the data as received (the same as `payload` \"{{payload}}\"). source_event: the whole event (device, product, timestamps, payload…). none: no payload.",
        "type": [
          "string",
          "null"
        ]
      },
      "product_profile_response": {
        "description": "What an API resource answers (`response.data`). `source` selects it: request_response: what the request target returned; topic → `topic`: wait for a message on that MQTT topic (from the same device, or any with `publish_source`: any); property → `property`; resource → `resource`; function → `function`; endpoint_call → `endpoint`; none. The answer can be shaped with `payload` / `payload_type` / `payload_function`.",
        "properties": {
          "endpoint": {
            "type": [
              "string",
              "null"
            ]
          },
          "function": {
            "type": [
              "string",
              "null"
            ]
          },
          "payload": {
            "description": "Template string (payload_type template_payload) or JSON value."
          },
          "payload_function": {
            "type": [
              "string",
              "null"
            ]
          },
          "payload_type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/product_profile_payload_type"
              },
              {
                "type": "null"
              }
            ]
          },
          "property": {
            "type": [
              "string",
              "null"
            ]
          },
          "publish_source": {
            "description": "source topic: empty (only the same device) or any.",
            "type": [
              "string",
              "null"
            ]
          },
          "resource": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "description": "request_response | topic | property | resource | function | endpoint_call | none",
            "type": [
              "string",
              "null"
            ]
          },
          "topic": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "Product profile API response",
        "type": [
          "object",
          "null"
        ]
      },
      "product_profile_source": {
        "description": "Where a properties / buckets / flows entry gets its data. `source` selects the fields used: topic → `topic` (MQTT topic, + and # wildcards; {{name}} placeholders match one level, and in buckets each one becomes a tag of the record, with {{field}} naming the record field so several topics merge into one record); resource → `resource`, `update` (interval | events) with `interval` + `magnitude`; resource_stream → `resource_stream` (the device pushes it); product_stream → `product_stream`; event → `event` with optional `filter`. Only devices of this product are listened to. The received data can then be transformed with `payload_type` / `payload` and `payload_function`.",
        "properties": {
          "event": {
            "description": "source event: server event name, e.g. device_state_change, device_property_update, bucket_write.",
            "type": [
              "string",
              "null"
            ]
          },
          "filter": {
            "description": "source event: extra filters (event field: value or regex). The product filter is always added.",
            "type": [
              "object",
              "null"
            ]
          },
          "interval": {
            "description": "source resource with update interval: number of `magnitude` units between reads, e.g. 60.",
            "type": [
              "number",
              "string",
              "null"
            ]
          },
          "magnitude": {
            "description": "second (default) | minute | hour | day | week | month | year",
            "type": [
              "string",
              "null"
            ]
          },
          "patch": {
            "description": "properties only: merge the value into the device property instead of replacing it.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "payload": {
            "description": "Template string (payload_type template_payload) or JSON value."
          },
          "payload_function": {
            "description": "Name of a function of the product code that receives the payload and returns the value to use.",
            "type": [
              "string",
              "null"
            ]
          },
          "payload_type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/product_profile_payload_type"
              },
              {
                "type": "null"
              }
            ]
          },
          "product_stream": {
            "description": "source product_stream: stream published by an API resource or flow of this product (target product_stream).",
            "type": [
              "string",
              "null"
            ]
          },
          "resource": {
            "description": "source resource: device resource read by the server.",
            "type": [
              "string",
              "null"
            ]
          },
          "resource_stream": {
            "description": "source resource_stream: device resource the device streams on its own.",
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "description": "topic | resource | resource_stream | product_stream | event",
            "type": [
              "string",
              "null"
            ]
          },
          "topic": {
            "description": "source topic: MQTT topic of the device messages, e.g. devices/{{device}}/telemetry.",
            "type": [
              "string",
              "null"
            ]
          },
          "update": {
            "description": "source resource: interval (default, read every `interval` `magnitude`) | events (the device streams it when it changes).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "Product profile data source",
        "type": [
          "object",
          "null"
        ]
      },
      "product_profile_target": {
        "description": "What an API resource request (`request.data`) or a flow (`sink`) does. `target` selects the fields used: topic → `topic` (+ `retain`): publish to the device over MQTT; resource → `resource`: call a device resource (IOTMP devices); resource_stream → `resource_stream`; property → `property`: set a device property; function → `function`: run a function of the product code; endpoint_call → `endpoint`: call an endpoint; plugin_endpoint → `plugin` + `path`; product_stream → `product_stream` (and optional `product`): publish to a product stream; none. The body sent is built from `payload` / `payload_type` / `payload_function`. A target needs a device: the one in the URL, the source device, or the one returned by the entry's `device_id_resolver`.",
        "properties": {
          "endpoint": {
            "description": "target endpoint_call: endpoint id (may use placeholders).",
            "type": [
              "string",
              "null"
            ]
          },
          "function": {
            "type": [
              "string",
              "null"
            ]
          },
          "path": {
            "description": "target plugin_endpoint: path inside the plugin, e.g. /api/process.",
            "type": [
              "string",
              "null"
            ]
          },
          "payload": {
            "description": "Template string (payload_type template_payload) or JSON value."
          },
          "payload_function": {
            "type": [
              "string",
              "null"
            ]
          },
          "payload_type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/product_profile_payload_type"
              },
              {
                "type": "null"
              }
            ]
          },
          "plugin": {
            "type": [
              "string",
              "null"
            ]
          },
          "product": {
            "type": [
              "string",
              "null"
            ]
          },
          "product_stream": {
            "type": [
              "string",
              "null"
            ]
          },
          "property": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource_stream": {
            "type": [
              "string",
              "null"
            ]
          },
          "retain": {
            "description": "target topic: publish as a retained MQTT message.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "target": {
            "description": "topic | resource | resource_stream | property | function | endpoint_call | plugin_endpoint | product_stream | none",
            "type": [
              "string",
              "null"
            ]
          },
          "topic": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "Product profile target",
        "type": [
          "object",
          "null"
        ]
      },
      "product_service": {
        "description": "A service the devices of the product expose, reached through the server: web (HTTP proxy) or vnc (remote desktop). The target is the address and port as seen from the device.",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "security": {
            "properties": {
              "ip_filtering": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "timeout_minutes": {
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "target": {
            "properties": {
              "address": {
                "description": "e.g. 127.0.0.1",
                "type": [
                  "string",
                  "null"
                ]
              },
              "port": {
                "description": "e.g. 8080",
                "type": [
                  "integer",
                  "string",
                  "null"
                ]
              },
              "secure": {
                "description": "The target uses TLS.",
                "type": [
                  "boolean",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "type": {
            "description": "web (default) | vnc",
            "type": [
              "string",
              "null"
            ]
          },
          "vnc": {
            "properties": {
              "compression": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "quality": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "scale": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "shared": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "viewonly": {
                "type": [
                  "boolean",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          }
        },
        "title": "Product service",
        "type": [
          "object",
          "null"
        ]
      },
      "projects_ids": {
        "description": "A collection of unique project IDs, ensuring no duplicates within the array.",
        "items": {
          "description": "An array of unique project identifiers, each following a 'username@project' format with each part limited to 32 alphanumeric characters, underscores or hyphens.",
          "example": [
            "project1@domain1",
            "project2@domain2"
          ],
          "pattern": "^[a-zA-Z0-9_-]{1,32}@[a-zA-Z0-9_-]{1,32}$",
          "title": "Project IDs",
          "type": "string"
        },
        "title": "Projects IDs Array",
        "type": "array",
        "uniqueItems": true
      },
      "property": {
        "description": "Schema for a property",
        "properties": {
          "description": {
            "$ref": "#/components/schemas/resource_description"
          },
          "form": {
            "additionalProperties": false,
            "properties": {
              "fields": {}
            },
            "required": [
              "fields"
            ],
            "type": "object"
          },
          "name": {
            "$ref": "#/components/schemas/resource_name"
          },
          "perm": {
            "additionalProperties": false,
            "properties": {
              "hidden": {
                "items": {
                  "enum": [
                    "owner",
                    "member"
                  ],
                  "type": "string"
                },
                "type": "array",
                "uniqueItems": true
              },
              "readOnly": {
                "items": {
                  "enum": [
                    "owner",
                    "member"
                  ],
                  "type": "string"
                },
                "type": "array",
                "uniqueItems": true
              }
            },
            "type": "object"
          },
          "property": {
            "$ref": "#/components/schemas/resource_id"
          },
          "type": {
            "enum": [
              "",
              "configuration"
            ],
            "type": "string"
          },
          "value": {}
        },
        "title": "Property",
        "type": "object"
      },
      "property_create": {
        "allOf": [
          {
            "$ref": "#/components/schemas/property"
          },
          {
            "required": [
              "property",
              "value"
            ],
            "type": "object"
          }
        ],
        "description": "Schema for creating a property",
        "title": "Property Create"
      },
      "property_update": {
        "allOf": [
          {
            "$ref": "#/components/schemas/property"
          },
          {
            "required": [
              "value"
            ],
            "type": "object"
          }
        ],
        "description": "Schema for updating a property",
        "title": "Property Update"
      },
      "resource_description": {
        "description": "A brief description of the resource, providing context or additional information, limited to 255 characters.",
        "example": [
          "Bucket storing all device measurements.",
          "Dashbord for main floor."
        ],
        "maxLength": 255,
        "title": "Resource Description",
        "type": "string"
      },
      "resource_id": {
        "description": "A unique identifier for resources, consisting of alphanumeric characters, underscores, or hyphens, and limited to 32 characters.",
        "example": [
          "resource_123",
          "abcd-1234"
        ],
        "pattern": "^[a-zA-Z0-9_-]{1,32}$",
        "title": "Resource ID",
        "type": "string"
      },
      "resource_name": {
        "description": "The name of the resource, limited to 255 characters. It can include any character.",
        "example": [
          "Raspberry Pi",
          "Arduino MKR1000"
        ],
        "maxLength": 255,
        "title": "Resource Name",
        "type": "string"
      },
      "sync_config": {
        "oneOf": [
          {
            "additionalProperties": false,
            "properties": {
              "available": {
                "minimum": 0,
                "type": "integer"
              },
              "timeout": {
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "available"
            ],
            "type": "object"
          }
        ],
        "title": "Sync Config"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "bearerFormat": "JWT",
        "scheme": "bearer",
        "type": "http"
      },
      "oauth": {
        "flows": {
          "password": {
            "scopes": {
              "basic": "manage user account"
            },
            "tokenUrl": "https://YOUR_SERVER/oauth/token"
          }
        },
        "type": "oauth2"
      }
    }
  },
  "info": {
    "description": "Thinger.io Server API",
    "title": "Thinger.io Server API",
    "version": "1.0.0"
  },
  "openapi": "3.1.1",
  "paths": {
    "/.well-known/acme-challenge/{token}": {
      "parameters": [
        {
          "in": "path",
          "name": "token",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]+",
            "type": "string"
          }
        }
      ]
    },
    "/brand/{file}": {
      "parameters": [
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ]
    },
    "/oauth/authorize/{identity_provider}": {
      "parameters": [
        {
          "in": "path",
          "name": "identity_provider",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/oauth/device/verification": {
      "post": {
        "operationId": "User_AuthorizeDeviceVerification",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AuthorizeDevice",
        "tags": [
          "Users"
        ]
      }
    },
    "/oauth/token": {
      "post": {
        "operationId": "Authentication_AuthenticateToken",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "password",
                      "refresh_token"
                    ],
                    "description": "`password` to sign in with the credentials of the account, `refresh_token` to get a new access token."
                  },
                  "username": {
                    "type": "string",
                    "description": "Username of the account. With `grant_type=password`."
                  },
                  "password": {
                    "type": "string",
                    "description": "Password of the account. With `grant_type=password`."
                  },
                  "refresh_token": {
                    "type": "string",
                    "description": "Refresh token of an earlier response. With `grant_type=refresh_token`."
                  }
                }
              },
              "examples": {
                "Sign in": {
                  "value": "grant_type=password&username=YOUR_USER&password=YOUR_PASSWORD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "Authenticate",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "Server_ReadApiOpenapi.json",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerApi",
        "tags": [
          "Server"
        ]
      }
    },
    "/users/{user}/plugins/{plugin}{path}": {
      "delete": {
        "operationId": "Plugin_CallPluginEndpointDelete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ]
      },
      "get": {
        "operationId": "Plugin_CallPluginEndpointGet",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ]
      },
      "head": {
        "operationId": "Plugin_CallPluginEndpointHead",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ],
        "x-internal": true
      },
      "options": {
        "operationId": "Plugin_CallPluginEndpointOptions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ],
        "x-internal": true
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "path",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Plugin_CallPluginEndpointPatch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ]
      },
      "post": {
        "operationId": "Plugin_CallPluginEndpointPost",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ]
      },
      "put": {
        "operationId": "Plugin_CallPluginEndpointPut",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ]
      },
      "trace": {
        "operationId": "Plugin_CallPluginEndpointTrace",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallPluginEndpoint",
        "tags": [
          "Plugins"
        ],
        "x-internal": true
      }
    },
    "/v1/accounts/password": {
      "post": {
        "operationId": "User_CreatePassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "CreateUserPassword",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/accounts/password/reset": {
      "post": {
        "operationId": "User_CreatePasswordReset",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "CreateUserPasswordReset",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/brands": {
      "get": {
        "operationId": "Brand_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "brand": "iot.example.com",
                    "created": 1792263090749,
                    "description": "Console for Example customers",
                    "enabled": true,
                    "modified": 1792263090749,
                    "name": "Example IoT"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListBrands",
        "tags": [
          "Brands"
        ]
      },
      "post": {
        "operationId": "Brand_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Brand for a domain": {
                  "value": {
                    "brand": "iot.example.com",
                    "config": {
                      "accounts": {
                        "allow_password": true,
                        "public_sign_up": false
                      },
                      "copyright": "© Example Inc.",
                      "email": "support@example.com",
                      "login": {
                        "background_color": "#132533",
                        "box_class": "login-center"
                      },
                      "name": "Example",
                      "show_community": false,
                      "style": {
                        "topBar": {
                          "background": "#132533",
                          "color": "#ffffff"
                        }
                      },
                      "title": "Example IoT Console",
                      "url": "https://www.example.com"
                    },
                    "description": "Console for Example customers",
                    "enabled": true,
                    "name": "Example IoT"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "brand": {
                    "description": "The domain the brand applies to (e.g. iot.example.com): the console is branded for requests to that host. Point the domain to this server and register it in domains to get its certificate.",
                    "pattern": "^([a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+(?:\\.[a-zA-Z]{2,11})?$",
                    "type": "string"
                  },
                  "config": {
                    "description": "Look and behaviour of the console when it is opened on the brand domain. With PUT it replaces the whole stored config (and images missing from it are deleted); PATCH merges it into the stored one.",
                    "properties": {
                      "accounts": {
                        "description": "Sign-up and login on this domain. Each key overrides the server setting of the same name (host settings, accounts.*).",
                        "properties": {
                          "allow_password": {
                            "description": "Password login (default true).",
                            "type": "boolean"
                          },
                          "allow_passwordless": {
                            "description": "Passkey login.",
                            "type": "boolean"
                          },
                          "cross_sign_in": {
                            "description": "false: only accounts created on this domain can sign in here (default true).",
                            "type": "boolean"
                          },
                          "federated_login": {
                            "description": "Show the identity provider buttons.",
                            "type": "boolean"
                          },
                          "identity_providers": {
                            "description": "Identity provider ids offered on this domain; empty offers every enabled one.",
                            "items": {},
                            "type": "array"
                          },
                          "no_robot": {
                            "description": "reCAPTCHA on sign-up. The secret is only returned to admins.",
                            "properties": {
                              "enabled": {
                                "type": "boolean"
                              },
                              "recaptcha": {
                                "properties": {
                                  "secret": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "public_sign_up": {
                            "description": "Anyone can create an account.",
                            "type": "boolean"
                          },
                          "public_sign_up_member_owner": {
                            "description": "Owner (admin or domain admin) of the project new members join.",
                            "type": "string"
                          },
                          "public_sign_up_member_role": {
                            "description": "Role id given to the new members.",
                            "type": "string"
                          },
                          "public_sign_up_project": {
                            "properties": {
                              "limit_bucket_access": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "public_sign_up_role": {
                            "description": "Role of the new accounts: user or member.",
                            "type": "string"
                          },
                          "require_2fa": {
                            "description": "Require a second factor.",
                            "type": "boolean"
                          }
                        },
                        "type": "object"
                      },
                      "bright_logo": {
                        "description": "Menu logo. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "copyright": {
                        "description": "Footer text.",
                        "type": "string"
                      },
                      "dark_logo": {
                        "description": "Platform logo: login and public pages, exports. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "description": {
                        "description": "Meta description (also og:description).",
                        "type": "string"
                      },
                      "email": {
                        "description": "Support address shown in the menu (mailto). Not the sender of emails: see the brand email.",
                        "type": "string"
                      },
                      "favicon": {
                        "description": "Browser icon. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "icon": {
                        "description": "Menu icon when the menu is folded. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "index_scripts": {
                        "description": "Raw HTML/JS injected in the page head (analytics…). Empty uses the default tag manager.",
                        "type": "string"
                      },
                      "keywords": {
                        "description": "Meta keywords.",
                        "type": "string"
                      },
                      "login": {
                        "description": "Login page.",
                        "properties": {
                          "background_color": {
                            "description": "CSS color.",
                            "type": "string"
                          },
                          "background_image": {
                            "description": "Image URL.",
                            "type": "string"
                          },
                          "background_style": {
                            "description": "Extra CSS as \"property:value;property:value\" (values cannot contain ':').",
                            "type": "string"
                          },
                          "box_class": {
                            "description": "Position of the login box: login-center, login-left or login-right.",
                            "type": "string"
                          },
                          "box_style": {
                            "description": "Inline CSS of the login box.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "name": {
                        "description": "Company name, used as title prefix and logo alt text.",
                        "type": "string"
                      },
                      "product_types": {
                        "description": "Options of the product type selector.",
                        "items": {
                          "properties": {
                            "label": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "pwa": {
                        "description": "Web app manifest (installable app). Served as is at /manifest.webmanifest.",
                        "properties": {
                          "background_color": {
                            "type": "string"
                          },
                          "display": {
                            "description": "e.g. standalone.",
                            "type": "string"
                          },
                          "icons": {
                            "description": "192x192 and 512x512 icons, each for purpose any and maskable.",
                            "items": {
                              "properties": {
                                "purpose": {
                                  "description": "any or maskable.",
                                  "type": "string"
                                },
                                "sizes": {
                                  "description": "e.g. 192x192.",
                                  "type": "string"
                                },
                                "src": {
                                  "description": "data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "type": {
                                  "description": "e.g. image/png.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "name": {
                            "type": "string"
                          },
                          "short_name": {
                            "type": "string"
                          },
                          "start_url": {
                            "type": "string"
                          },
                          "theme_color": {
                            "description": "CSS color, also the browser theme color.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "share_image": {
                        "description": "Image for link previews (og:image). data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "show_community": {
                        "description": "Show the community links in the menu (default true).",
                        "type": "boolean"
                      },
                      "show_version": {
                        "description": "Show the server version (default true).",
                        "type": "boolean"
                      },
                      "style": {
                        "properties": {
                          "topBar": {
                            "description": "Console top bar.",
                            "properties": {
                              "background": {
                                "description": "CSS color.",
                                "type": "string"
                              },
                              "color": {
                                "description": "CSS color of the text and icons.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      },
                      "title": {
                        "description": "Page title (also og:title).",
                        "type": "string"
                      },
                      "url": {
                        "description": "Link of the logo on the login and public pages.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "description": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "brand"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateBrand",
        "tags": [
          "Brands"
        ]
      }
    },
    "/v1/brands/{brand}": {
      "delete": {
        "operationId": "Brand_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteBrand",
        "tags": [
          "Brands"
        ]
      },
      "get": {
        "operationId": "Brand_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Brand for a domain": {
                    "value": {
                      "brand": "iot.example.com",
                      "config": {
                        "accounts": {
                          "allow_password": true,
                          "public_sign_up": false
                        },
                        "copyright": "© Example Inc.",
                        "email": "support@example.com",
                        "login": {
                          "background_color": "#132533",
                          "box_class": "login-center"
                        },
                        "name": "Example",
                        "show_community": false,
                        "style": {
                          "topBar": {
                            "background": "#132533",
                            "color": "#ffffff"
                          }
                        },
                        "title": "Example IoT Console",
                        "url": "https://www.example.com"
                      },
                      "created": 1792263090749,
                      "description": "Console for Example customers",
                      "enabled": true,
                      "modified": 1792263090749,
                      "name": "Example IoT"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadBrandConfig",
        "tags": [
          "Brands"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "brand",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Brand_Patch",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change the SMTP password": {
                  "value": {
                    "email": {
                      "settings": {
                        "smtp": {
                          "password": "new-app-password"
                        }
                      }
                    }
                  }
                },
                "Change the title only": {
                  "value": {
                    "config": {
                      "title": "New Console Title"
                    }
                  }
                },
                "Disable public sign-up": {
                  "value": {
                    "config": {
                      "accounts": {
                        "public_sign_up": false
                      }
                    }
                  }
                },
                "Remove a logo": {
                  "value": {
                    "config": {
                      "icon": null
                    }
                  }
                },
                "Replace a logo": {
                  "value": {
                    "config": {
                      "dark_logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Partial update: only the fields sent change; config and email are merged into the stored ones (RFC 7386 merge patch: a null value removes a key). Images left out are kept.",
                "properties": {
                  "config": {
                    "description": "Look and behaviour of the console when it is opened on the brand domain. With PUT it replaces the whole stored config (and images missing from it are deleted); PATCH merges it into the stored one.",
                    "properties": {
                      "accounts": {
                        "description": "Sign-up and login on this domain. Each key overrides the server setting of the same name (host settings, accounts.*).",
                        "properties": {
                          "allow_password": {
                            "description": "Password login (default true).",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "allow_passwordless": {
                            "description": "Passkey login.",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "cross_sign_in": {
                            "description": "false: only accounts created on this domain can sign in here (default true).",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "federated_login": {
                            "description": "Show the identity provider buttons.",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "identity_providers": {
                            "description": "Identity provider ids offered on this domain; empty offers every enabled one.",
                            "items": {},
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "no_robot": {
                            "description": "reCAPTCHA on sign-up. The secret is only returned to admins.",
                            "properties": {
                              "enabled": {
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              },
                              "recaptcha": {
                                "properties": {
                                  "secret": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "type": [
                                  "object",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "public_sign_up": {
                            "description": "Anyone can create an account.",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "public_sign_up_member_owner": {
                            "description": "Owner (admin or domain admin) of the project new members join.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "public_sign_up_member_role": {
                            "description": "Role id given to the new members.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "public_sign_up_project": {
                            "properties": {
                              "limit_bucket_access": {
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "public_sign_up_role": {
                            "description": "Role of the new accounts: user or member.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "require_2fa": {
                            "description": "Require a second factor.",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "bright_logo": {
                        "description": "Menu logo. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "copyright": {
                        "description": "Footer text.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "dark_logo": {
                        "description": "Platform logo: login and public pages, exports. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "description": {
                        "description": "Meta description (also og:description).",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "email": {
                        "description": "Support address shown in the menu (mailto). Not the sender of emails: see the brand email.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "favicon": {
                        "description": "Browser icon. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "icon": {
                        "description": "Menu icon when the menu is folded. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "index_scripts": {
                        "description": "Raw HTML/JS injected in the page head (analytics…). Empty uses the default tag manager.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "keywords": {
                        "description": "Meta keywords.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "login": {
                        "description": "Login page.",
                        "properties": {
                          "background_color": {
                            "description": "CSS color.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "background_image": {
                            "description": "Image URL.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "background_style": {
                            "description": "Extra CSS as \"property:value;property:value\" (values cannot contain ':').",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "box_class": {
                            "description": "Position of the login box: login-center, login-left or login-right.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "box_style": {
                            "description": "Inline CSS of the login box.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "name": {
                        "description": "Company name, used as title prefix and logo alt text.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "product_types": {
                        "description": "Options of the product type selector.",
                        "items": {
                          "properties": {
                            "label": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "value": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "type": [
                          "array",
                          "null"
                        ]
                      },
                      "pwa": {
                        "description": "Web app manifest (installable app). Served as is at /manifest.webmanifest.",
                        "properties": {
                          "background_color": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "display": {
                            "description": "e.g. standalone.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "icons": {
                            "description": "192x192 and 512x512 icons, each for purpose any and maskable.",
                            "items": {
                              "properties": {
                                "purpose": {
                                  "description": "any or maskable.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "sizes": {
                                  "description": "e.g. 192x192.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "src": {
                                  "description": "data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "type": {
                                  "description": "e.g. image/png.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "short_name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "start_url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "theme_color": {
                            "description": "CSS color, also the browser theme color.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "share_image": {
                        "description": "Image for link previews (og:image). data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "show_community": {
                        "description": "Show the community links in the menu (default true).",
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "show_version": {
                        "description": "Show the server version (default true).",
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "style": {
                        "properties": {
                          "topBar": {
                            "description": "Console top bar.",
                            "properties": {
                              "background": {
                                "description": "CSS color.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "color": {
                                "description": "CSS color of the text and icons.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "title": {
                        "description": "Page title (also og:title).",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "url": {
                        "description": "Link of the logo on the login and public pages.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "description": {
                    "type": "string"
                  },
                  "email": {
                    "description": "Emails sent to accounts of this domain (verification, password…). With PUT it replaces the whole stored email config; PATCH merges it. Read it with GET /v1/brands/{brand}/email and try a template with POST /v1/brands/{brand}/email/test.",
                    "properties": {
                      "custom": {
                        "description": "true: send with `settings` instead of the server mail settings.",
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "settings": {
                        "properties": {
                          "from": {
                            "description": "Sender address.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "from_name": {
                            "description": "Sender name.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ses": {
                            "properties": {
                              "aws_access_key_id": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "aws_region": {
                                "description": "e.g. eu-west-1.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "aws_secret_access_key": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "smtp": {
                            "properties": {
                              "host": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "password": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "port": {
                                "description": "As a string, e.g. \"587\" (numbers are ignored by the server).",
                                "pattern": "^[0-9]{1,5}$",
                                "type": [
                                  "string",
                                  "integer",
                                  "null"
                                ]
                              },
                              "secure": {
                                "description": "true: implicit TLS (usually port 465); false: the server must offer STARTTLS (usually 587).",
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              },
                              "username": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "type": {
                            "description": "smtp or ses.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "templates": {
                        "description": "Per template: email_verification, forgot_password, create_password, device_disabled. Missing fields use the defaults. Subject and body may use {{code}} (the token for the link), {{user}}, {{email}}, {{host}}, {{admin}}, {{host_url}} and, in device_disabled, {{device}}. Links: {{host_url}}/verify_email?code={{code}}, {{host_url}}/password?code={{code}} (forgot_password), {{host_url}}/create_password?code={{code}}. {{name}}, {{url}}, {{logo}} and {{description}} only exist in the built-in defaults: in a custom template write the brand name and the logo URL (e.g. https://<brand>/brand/images/dark_logo.png) directly. The 'enabled' flag is not enforced yet.",
                        "properties": {
                          "create_password": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string",
                                  "null"
                                ]
                              },
                              "from": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "from_name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "subject": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "device_disabled": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string",
                                  "null"
                                ]
                              },
                              "from": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "from_name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "subject": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "email_verification": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string",
                                  "null"
                                ]
                              },
                              "from": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "from_name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "subject": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "forgot_password": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string",
                                  "null"
                                ]
                              },
                              "from": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "from_name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "subject": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateBrand",
        "tags": [
          "Brands"
        ]
      },
      "put": {
        "operationId": "Brand_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Replace the whole config (logos missing from it are deleted)": {
                  "value": {
                    "config": {
                      "bright_logo": "/brand/images/bright_logo.png",
                      "dark_logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
                      "name": "Example",
                      "style": {
                        "topBar": {
                          "background": "#132533",
                          "color": "#ffffff"
                        }
                      },
                      "title": "Example IoT Console"
                    }
                  }
                },
                "Send emails with Amazon SES": {
                  "value": {
                    "email": {
                      "custom": true,
                      "settings": {
                        "from": "noreply@example.com",
                        "from_name": "Example IoT",
                        "ses": {
                          "aws_access_key_id": "AKIA…",
                          "aws_region": "eu-west-1",
                          "aws_secret_access_key": "…"
                        },
                        "type": "ses"
                      }
                    }
                  }
                },
                "Send emails with SMTP": {
                  "value": {
                    "email": {
                      "custom": true,
                      "settings": {
                        "from": "noreply@example.com",
                        "from_name": "Example IoT",
                        "smtp": {
                          "host": "smtp.example.com",
                          "password": "app-password",
                          "port": "587",
                          "secure": false,
                          "username": "noreply@example.com"
                        },
                        "type": "smtp"
                      }
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "description": "Look and behaviour of the console when it is opened on the brand domain. With PUT it replaces the whole stored config (and images missing from it are deleted); PATCH merges it into the stored one.",
                    "properties": {
                      "accounts": {
                        "description": "Sign-up and login on this domain. Each key overrides the server setting of the same name (host settings, accounts.*).",
                        "properties": {
                          "allow_password": {
                            "description": "Password login (default true).",
                            "type": "boolean"
                          },
                          "allow_passwordless": {
                            "description": "Passkey login.",
                            "type": "boolean"
                          },
                          "cross_sign_in": {
                            "description": "false: only accounts created on this domain can sign in here (default true).",
                            "type": "boolean"
                          },
                          "federated_login": {
                            "description": "Show the identity provider buttons.",
                            "type": "boolean"
                          },
                          "identity_providers": {
                            "description": "Identity provider ids offered on this domain; empty offers every enabled one.",
                            "items": {},
                            "type": "array"
                          },
                          "no_robot": {
                            "description": "reCAPTCHA on sign-up. The secret is only returned to admins.",
                            "properties": {
                              "enabled": {
                                "type": "boolean"
                              },
                              "recaptcha": {
                                "properties": {
                                  "secret": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "public_sign_up": {
                            "description": "Anyone can create an account.",
                            "type": "boolean"
                          },
                          "public_sign_up_member_owner": {
                            "description": "Owner (admin or domain admin) of the project new members join.",
                            "type": "string"
                          },
                          "public_sign_up_member_role": {
                            "description": "Role id given to the new members.",
                            "type": "string"
                          },
                          "public_sign_up_project": {
                            "properties": {
                              "limit_bucket_access": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "public_sign_up_role": {
                            "description": "Role of the new accounts: user or member.",
                            "type": "string"
                          },
                          "require_2fa": {
                            "description": "Require a second factor.",
                            "type": "boolean"
                          }
                        },
                        "type": "object"
                      },
                      "bright_logo": {
                        "description": "Menu logo. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "copyright": {
                        "description": "Footer text.",
                        "type": "string"
                      },
                      "dark_logo": {
                        "description": "Platform logo: login and public pages, exports. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "description": {
                        "description": "Meta description (also og:description).",
                        "type": "string"
                      },
                      "email": {
                        "description": "Support address shown in the menu (mailto). Not the sender of emails: see the brand email.",
                        "type": "string"
                      },
                      "favicon": {
                        "description": "Browser icon. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "icon": {
                        "description": "Menu icon when the menu is folded. data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "index_scripts": {
                        "description": "Raw HTML/JS injected in the page head (analytics…). Empty uses the default tag manager.",
                        "type": "string"
                      },
                      "keywords": {
                        "description": "Meta keywords.",
                        "type": "string"
                      },
                      "login": {
                        "description": "Login page.",
                        "properties": {
                          "background_color": {
                            "description": "CSS color.",
                            "type": "string"
                          },
                          "background_image": {
                            "description": "Image URL.",
                            "type": "string"
                          },
                          "background_style": {
                            "description": "Extra CSS as \"property:value;property:value\" (values cannot contain ':').",
                            "type": "string"
                          },
                          "box_class": {
                            "description": "Position of the login box: login-center, login-left or login-right.",
                            "type": "string"
                          },
                          "box_style": {
                            "description": "Inline CSS of the login box.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "name": {
                        "description": "Company name, used as title prefix and logo alt text.",
                        "type": "string"
                      },
                      "product_types": {
                        "description": "Options of the product type selector.",
                        "items": {
                          "properties": {
                            "label": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "pwa": {
                        "description": "Web app manifest (installable app). Served as is at /manifest.webmanifest.",
                        "properties": {
                          "background_color": {
                            "type": "string"
                          },
                          "display": {
                            "description": "e.g. standalone.",
                            "type": "string"
                          },
                          "icons": {
                            "description": "192x192 and 512x512 icons, each for purpose any and maskable.",
                            "items": {
                              "properties": {
                                "purpose": {
                                  "description": "any or maskable.",
                                  "type": "string"
                                },
                                "sizes": {
                                  "description": "e.g. 192x192.",
                                  "type": "string"
                                },
                                "src": {
                                  "description": "data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "type": {
                                  "description": "e.g. image/png.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "name": {
                            "type": "string"
                          },
                          "short_name": {
                            "type": "string"
                          },
                          "start_url": {
                            "type": "string"
                          },
                          "theme_color": {
                            "description": "CSS color, also the browser theme color.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "share_image": {
                        "description": "Image for link previews (og:image). data:image/png;base64,… or data:image/webp;base64,… to replace the image (stored under /brand/images/), the stored /brand/images/… URL to keep it, \"\" or null to remove it.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "show_community": {
                        "description": "Show the community links in the menu (default true).",
                        "type": "boolean"
                      },
                      "show_version": {
                        "description": "Show the server version (default true).",
                        "type": "boolean"
                      },
                      "style": {
                        "properties": {
                          "topBar": {
                            "description": "Console top bar.",
                            "properties": {
                              "background": {
                                "description": "CSS color.",
                                "type": "string"
                              },
                              "color": {
                                "description": "CSS color of the text and icons.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      },
                      "title": {
                        "description": "Page title (also og:title).",
                        "type": "string"
                      },
                      "url": {
                        "description": "Link of the logo on the login and public pages.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "description": {
                    "type": "string"
                  },
                  "email": {
                    "description": "Emails sent to accounts of this domain (verification, password…). With PUT it replaces the whole stored email config; PATCH merges it. Read it with GET /v1/brands/{brand}/email and try a template with POST /v1/brands/{brand}/email/test.",
                    "properties": {
                      "custom": {
                        "description": "true: send with `settings` instead of the server mail settings.",
                        "type": "boolean"
                      },
                      "settings": {
                        "properties": {
                          "from": {
                            "description": "Sender address.",
                            "type": "string"
                          },
                          "from_name": {
                            "description": "Sender name.",
                            "type": "string"
                          },
                          "ses": {
                            "properties": {
                              "aws_access_key_id": {
                                "type": "string"
                              },
                              "aws_region": {
                                "description": "e.g. eu-west-1.",
                                "type": "string"
                              },
                              "aws_secret_access_key": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "smtp": {
                            "properties": {
                              "host": {
                                "type": "string"
                              },
                              "password": {
                                "type": "string"
                              },
                              "port": {
                                "description": "As a string, e.g. \"587\" (numbers are ignored by the server).",
                                "pattern": "^[0-9]{1,5}$",
                                "type": [
                                  "string",
                                  "integer"
                                ]
                              },
                              "secure": {
                                "description": "true: implicit TLS (usually port 465); false: the server must offer STARTTLS (usually 587).",
                                "type": "boolean"
                              },
                              "username": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": {
                            "description": "smtp or ses.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "templates": {
                        "description": "Per template: email_verification, forgot_password, create_password, device_disabled. Missing fields use the defaults. Subject and body may use {{code}} (the token for the link), {{user}}, {{email}}, {{host}}, {{admin}}, {{host_url}} and, in device_disabled, {{device}}. Links: {{host_url}}/verify_email?code={{code}}, {{host_url}}/password?code={{code}} (forgot_password), {{host_url}}/create_password?code={{code}}. {{name}}, {{url}}, {{logo}} and {{description}} only exist in the built-in defaults: in a custom template write the brand name and the logo URL (e.g. https://<brand>/brand/images/dark_logo.png) directly. The 'enabled' flag is not enforced yet.",
                        "properties": {
                          "create_password": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": "string"
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string"
                                ]
                              },
                              "from": {
                                "type": "string"
                              },
                              "from_name": {
                                "type": "string"
                              },
                              "subject": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "device_disabled": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": "string"
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string"
                                ]
                              },
                              "from": {
                                "type": "string"
                              },
                              "from_name": {
                                "type": "string"
                              },
                              "subject": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "email_verification": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": "string"
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string"
                                ]
                              },
                              "from": {
                                "type": "string"
                              },
                              "from_name": {
                                "type": "string"
                              },
                              "subject": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "forgot_password": {
                            "properties": {
                              "body": {
                                "description": "HTML.",
                                "type": "string"
                              },
                              "enabled": {
                                "description": "The built-in defaults carry it as a string.",
                                "type": [
                                  "boolean",
                                  "string"
                                ]
                              },
                              "from": {
                                "type": "string"
                              },
                              "from_name": {
                                "type": "string"
                              },
                              "subject": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateBrand",
        "tags": [
          "Brands"
        ]
      }
    },
    "/v1/brands/{brand}/email": {
      "parameters": [
        {
          "in": "path",
          "name": "brand",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ]
    },
    "/v1/brands/{brand}/email/test": {
      "parameters": [
        {
          "in": "path",
          "name": "brand",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Brand_TestEmail",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Password reset email": {
                  "description": "Sent to the calling admin's email address with the saved brand settings.",
                  "value": {
                    "template": "forgot_password"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "template": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "template"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "TestBrandEmail",
        "tags": [
          "Brands"
        ]
      }
    },
    "/v1/claims": {
      "post": {
        "operationId": "Claim_Request",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Claim into a project": {
                  "description": "Called by the account that claims; the project must be one shared with it by the claim owner.",
                  "value": {
                    "code": "a1B2c3D4e5",
                    "project": "my_greenhouse"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "code": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "project": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "code",
                  "project"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RequestClaim",
        "tags": [
          "Claims"
        ]
      }
    },
    "/v1/claims/{code}": {
      "get": {
        "operationId": "Claim_Read",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadClaim",
        "tags": [
          "Claims"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "code",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/domains": {
      "get": {
        "operationId": "Domain_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090747,
                    "description": "Console and API for Example customers",
                    "domain": "iot.example.com",
                    "modified": 1792263090747
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDomains",
        "tags": [
          "Domains"
        ]
      },
      "post": {
        "operationId": "Domain_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Custom domain": {
                  "value": {
                    "description": "Console and API for Example customers",
                    "domain": "iot.example.com"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "domain": {
                    "description": "Hostname to serve with its own TLS certificate, e.g. iot.example.com. Before verifying, point it to this server (A/AAAA record to its IP, or CNAME to its hostname) and make sure port 80 is reachable from the internet: POST /v1/domains/{domain}/verify gets a Let's Encrypt certificate through an HTTP-01 challenge (a *.wildcard needs the DNS-01 challenge, only on Thinger-hosted servers). Certificates renew automatically while the DNS keeps pointing here. Brand the console on it by creating a brand with the same id.",
                    "pattern": "^([a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\\.[a-zA-Z]{2,11}?$",
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "domain"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateDomain",
        "tags": [
          "Domains"
        ]
      }
    },
    "/v1/domains/{domain}": {
      "delete": {
        "operationId": "Domain_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDomain",
        "tags": [
          "Domains"
        ]
      },
      "get": {
        "operationId": "Domain_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Custom domain": {
                    "value": {
                      "created": 1792263090747,
                      "description": "Console and API for Example customers",
                      "domain": "iot.example.com",
                      "modified": 1792263090747
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDomainConfig",
        "tags": [
          "Domains"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "domain",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+\\.[a-zA-Z]{2,11}?)",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Domain_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "description": "Console and API for Example customers",
                    "domain": "iot.example.com"
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Console and API for Example customers"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDomain",
        "tags": [
          "Domains"
        ]
      }
    },
    "/v1/domains/{domain}/verify": {
      "parameters": [
        {
          "in": "path",
          "name": "domain",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+\\.[a-zA-Z]{2,11}?)",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Domain_Verify",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "VerifyDomain",
        "tags": [
          "Domains"
        ]
      }
    },
    "/v1/endpoints/templates": {
      "get": {
        "operationId": "Endpoint_ListTemplates",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListEndpointTemplates",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/endpoints/templates/{endpoint}": {
      "get": {
        "operationId": "Endpoint_ReadTemplateConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadEndpointTemplateConfig",
        "tags": [
          "Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "endpoint",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/hosts": {
      "get": {
        "operationId": "Host_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListHosts",
        "tags": [
          "Hosts"
        ]
      },
      "post": {
        "operationId": "Host_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "host": {
                    "description": "Hostname of the server. Hosts register themselves when they start.",
                    "pattern": "^([a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+(?:\\.[a-zA-Z]{2,11})?$",
                    "type": "string"
                  }
                },
                "required": [
                  "host"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateHost",
        "tags": [
          "Hosts"
        ]
      }
    },
    "/v1/hosts/{host}": {
      "delete": {
        "operationId": "Host_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteHost",
        "tags": [
          "Hosts"
        ]
      },
      "get": {
        "operationId": "Host_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadHostConfig",
        "tags": [
          "Hosts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "host",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Host_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Describe the host": {
                  "value": {
                    "description": "Primary server, eu-west-1"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateHost",
        "tags": [
          "Hosts"
        ]
      }
    },
    "/v1/hosts/{host}/logs": {
      "get": {
        "description": "Server output (stdout and stderr) of the host. A websocket upgrade streams new lines live; a plain GET returns the last lines as text/plain. Reads the logs of the Docker container the server runs in (deployment.container_name, default \"thinger\"); other cluster hosts are proxied.",
        "operationId": "Host_ReadLogs",
        "parameters": [
          {
            "description": "Plain GET: number of last lines (1-5000, default 200).",
            "in": "query",
            "name": "lines",
            "schema": {
              "default": 200,
              "maximum": 5000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Plain GET: prefix each line with its timestamp.",
            "in": "query",
            "name": "timestamps",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Plain GET: only lines after this unix timestamp, or this many seconds ago when below 31536000.",
            "in": "query",
            "name": "since",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadHostLogs",
        "tags": [
          "Hosts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "host",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ]
    },
    "/v1/hosts/{host}/restart": {
      "parameters": [
        {
          "in": "path",
          "name": "host",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Host_UpdateStateRestart",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateHostState",
        "tags": [
          "Hosts"
        ]
      }
    },
    "/v1/hosts/{host}/settings": {
      "get": {
        "operationId": "Host_ReadSettings",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadHostSettings",
        "tags": [
          "Hosts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "host",
          "required": true,
          "schema": {
            "pattern": "^(?:[a-zA-Z0-9_-]+\\.*[a-zA-Z0-9][a-zA-Z0-9_-]+(?:\\.[a-zA-Z]{2,11})?)",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Host_UpdateSettings",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change the MQTT ports": {
                  "value": {
                    "mqtt_server": {
                      "port": "1884",
                      "ssl_port": "8884"
                    }
                  }
                },
                "Enable projects, members and identity providers": {
                  "value": {
                    "accounts": {
                      "limits": {
                        "identity_providers": {
                          "max_count": 5
                        },
                        "projects": {
                          "max_count": -1
                        },
                        "projects_members": {
                          "max_count": -1
                        }
                      }
                    }
                  }
                },
                "Remove a custom setting (back to the provider value)": {
                  "value": {
                    "deployment": {
                      "x_frame_options": null
                    }
                  }
                },
                "Send server emails with SMTP": {
                  "value": {
                    "email": {
                      "from": "noreply@example.com",
                      "from_name": "Example IoT",
                      "smtp": {
                        "host": "smtp.example.com",
                        "password": "app-password",
                        "port": "587",
                        "secure": false,
                        "username": "noreply@example.com"
                      },
                      "type": "smtp"
                    }
                  }
                }
              },
              "schema": {
                "description": "Merged (RFC 7386 merge patch: null removes a key) into the host custom settings, on top of the provider settings. Changes apply after POST /v1/hosts/{host}/restart. Ports are strings: numbers are ignored by the server. On cloud instances (configured by a subscription), database, plugins, rate_limiter, http_server.hosts, accounts.limits.{accounts,brands,domains,members} and deployment.container_name belong to the plan: sending them returns 403, and stored ones are ignored.",
                "properties": {
                  "accounts": {
                    "description": "Accounts and limits. Brands can override the sign-up and login keys per domain.",
                    "properties": {
                      "admin_emails": {
                        "description": "Email addresses whose accounts become admins."
                      },
                      "allow_password": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "allow_passwordless": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "federated_login": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "identity_providers": {
                        "description": "Identity provider ids offered on login; empty offers every enabled one."
                      },
                      "invalid_email_domains": {
                        "description": "Email domains rejected on sign-up."
                      },
                      "invalid_usernames": {
                        "description": "Usernames that cannot be registered."
                      },
                      "limits": {
                        "description": "Per collection: {\"<collection>\": {\"max_count\": n}} with -1 = unlimited and 0 = disabled. Collections: access_tokens, buckets, dashboards, devices, endpoints, plugins, projects, projects_members, storages, alarms_rules, alarms_instances, syncs, types, groups, products, proxies, oauth_clients, identity_providers (default 0: set it to enable them). Also buckets.retention {period, unit} and buckets / endpoints min_interval. Accounts can override them with their own limits.",
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "max_password_length": {
                        "description": "Default 48.",
                        "type": [
                          "integer",
                          "string",
                          "null"
                        ]
                      },
                      "min_password_length": {
                        "description": "Default 8.",
                        "type": [
                          "integer",
                          "string",
                          "null"
                        ]
                      },
                      "public_sign_up": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "public_sign_up_role": {
                        "description": "user or member.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "require_2fa": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "require_email_verification": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "required_email_domains": {
                        "description": "Only these email domains can sign up."
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "buckets": {
                    "properties": {
                      "export": {
                        "description": "Where bucket exports are written: type filesystem ({filesystem: {export_path}}) or s3 ({s3: {bucket_id, aws_access_key_id, aws_secret_access_key, aws_region}}).",
                        "properties": {
                          "type": {
                            "description": "filesystem or s3.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "storage": {
                        "description": "Where bucket data is stored: default is mongodb, influxdb or dynamodb, each with its own connection settings (mongodb {connection_string, max_retention, default_retention}, influxdb {host, port, username, password}, dynamodb {table_name, aws_access_key_id, aws_secret_access_key, aws_region}).",
                        "properties": {
                          "default": {
                            "description": "mongodb, influxdb or dynamodb.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "deployment": {
                    "properties": {
                      "contact_email": {
                        "description": "The account registered with this email becomes admin; also {{admin}} in email templates.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "content_security_policy": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "disable_swagger": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "x_frame_options": {
                        "description": "Default SAMEORIGIN.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "email": {
                    "description": "Server mail settings, used when a brand has no custom email.",
                    "properties": {
                      "from": {
                        "description": "Sender address.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "from_name": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ses": {
                        "properties": {
                          "aws_access_key_id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "aws_region": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "aws_secret_access_key": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "smtp": {
                        "properties": {
                          "host": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "password": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "port": {
                            "description": "As a string, e.g. \"587\".",
                            "pattern": "^[0-9]{1,5}$",
                            "type": [
                              "string",
                              "integer",
                              "null"
                            ]
                          },
                          "secure": {
                            "description": "true: implicit TLS (465); false: STARTTLS (587).",
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "username": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "type": {
                        "description": "smtp or ses.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "http_server": {
                    "description": "HTTP API and console.",
                    "properties": {
                      "address": {
                        "description": "Listening address, e.g. 0.0.0.0.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "enabled": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "port": {
                        "description": "e.g. \"80\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      },
                      "ssl_port": {
                        "description": "e.g. \"443\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "mqtt_server": {
                    "description": "MQTT broker for devices.",
                    "properties": {
                      "address": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "enabled": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "port": {
                        "description": "e.g. \"1883\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      },
                      "ssl_port": {
                        "description": "e.g. \"8883\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "proxies": {
                    "properties": {
                      "dynamic_port_range_end": {
                        "description": "Last one (default 51000).",
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "dynamic_port_range_start": {
                        "description": "First port given to proxies without a fixed port (default 50000).",
                        "type": [
                          "integer",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "scripting_engine": {
                    "description": "{\"nodejs\": {\"enabled\": true}}: JavaScript for product scripts.",
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "ssl": {
                    "properties": {
                      "client_ca_certs": {
                        "description": "PEM certificates to accept as client certificates.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ssl_ciphers": {
                        "description": "OpenSSL cipher list.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ssl_enable_legacy_protocols": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "ssl_prefer_server_ciphers": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "thing_server": {
                    "description": "IOTMP server for devices.",
                    "properties": {
                      "address": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "enabled": {
                        "type": [
                          "boolean",
                          "null"
                        ]
                      },
                      "port": {
                        "description": "e.g. \"25200\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      },
                      "port_v2": {
                        "description": "IOTMP v2, default \"25204\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      },
                      "ssl_port": {
                        "description": "e.g. \"25202\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      },
                      "ssl_port_v2": {
                        "description": "IOTMP v2 over TLS, default \"25206\".",
                        "pattern": "^[0-9]{1,5}$",
                        "type": [
                          "string",
                          "integer",
                          "null"
                        ]
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateHostSettings",
        "tags": [
          "Hosts"
        ]
      }
    },
    "/v1/identity_providers": {
      "get": {
        "operationId": "IdentityProvider_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090753,
                    "enabled": true,
                    "identity_provider": "google",
                    "modified": 1792263090753,
                    "name": "Google",
                    "type": "oidc"
                  },
                  {
                    "created": 1792263090753,
                    "enabled": true,
                    "identity_provider": "entra",
                    "modified": 1792263090753,
                    "name": "Microsoft",
                    "type": "oidc"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListIdentityProviders",
        "tags": [
          "IdentityProviders"
        ]
      },
      "post": {
        "operationId": "IdentityProvider_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Google, existing accounts only": {
                  "value": {
                    "client_id": "<client-id>.apps.googleusercontent.com",
                    "client_secret": "<client-secret>",
                    "display": {
                      "button_text": "Sign in with Google"
                    },
                    "domain": "accounts.google.com",
                    "enabled": true,
                    "identity_provider": "google",
                    "name": "Google",
                    "provisioning": {
                      "email_trust_mode": "verify_with_claim",
                      "mode": "match_only"
                    },
                    "type": "oidc"
                  }
                },
                "Microsoft Entra ID": {
                  "value": {
                    "client_id": "<application-id>",
                    "client_secret": "<client-secret>",
                    "display": {
                      "button_text": "Sign in with Microsoft"
                    },
                    "domain": "login.microsoftonline.com/<tenant-id>/v2.0",
                    "enabled": true,
                    "identity_provider": "entra",
                    "name": "Microsoft",
                    "provisioning": {
                      "allowed_domains": [
                        "example.com"
                      ],
                      "email_trust_mode": "trust_idp",
                      "mode": "auto_provision"
                    },
                    "scopes": [
                      "openid",
                      "profile",
                      "email"
                    ],
                    "type": "oidc"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "OpenID Connect provider for the console login. Disabled by default: set accounts.limits.identity_providers.max_count in the host settings (and restart). Register https://<brand domain>/oauth/callback as redirect URI in the provider, check it with POST /v1/identity_providers/{id}/test, and offer it on a domain with the brand config accounts.federated_login / accounts.identity_providers.",
                "properties": {
                  "attribute_mapping": {
                    "properties": {
                      "company": {
                        "default": "organization",
                        "description": "Claim to use for company - not a standard OIDC claim",
                        "type": "string"
                      },
                      "email": {
                        "default": "email",
                        "type": "string"
                      },
                      "location": {
                        "default": "locale",
                        "description": "Claim to use for location",
                        "type": "string"
                      },
                      "name": {
                        "default": "name",
                        "type": "string"
                      },
                      "picture": {
                        "default": "picture",
                        "type": "string"
                      },
                      "username": {
                        "default": "preferred_username",
                        "description": "Claim to use for username",
                        "type": "string"
                      },
                      "website": {
                        "default": "website",
                        "description": "Claim to use for profile URL",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "client_id": {
                    "description": "OAuth2 client ID registered with the IdP",
                    "type": "string"
                  },
                  "client_secret": {
                    "description": "OAuth2 client secret",
                    "type": "string"
                  },
                  "description": {
                    "description": "Optional description",
                    "type": "string"
                  },
                  "display": {
                    "properties": {
                      "button_text": {
                        "type": "string"
                      },
                      "logo": {
                        "description": "Logo as base64 data URL",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "domain": {
                    "description": "Identity provider domain, e.g. your-tenant.us.auth0.com",
                    "type": "string"
                  },
                  "enabled": {
                    "default": true,
                    "type": "boolean"
                  },
                  "identity_provider": {
                    "description": "Unique identifier for the identity provider",
                    "pattern": "^[a-zA-Z0-9-_]{1,32}$",
                    "type": "string"
                  },
                  "name": {
                    "description": "Display name for the identity provider",
                    "type": "string"
                  },
                  "provisioning": {
                    "properties": {
                      "allowed_domains": {
                        "description": "Allowed email domains. Leave empty to allow all.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "email_trust_mode": {
                        "default": "verify_with_claim",
                        "description": "Email verification mode",
                        "enum": [
                          "trust_idp",
                          "verify_with_claim",
                          "always_verify"
                        ],
                        "type": "string"
                      },
                      "mode": {
                        "default": "auto_provision",
                        "description": "User provisioning mode",
                        "enum": [
                          "auto_provision",
                          "match_only"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "scopes": {
                    "default": [
                      "openid",
                      "profile",
                      "email"
                    ],
                    "description": "OAuth2 scopes to request",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "token_endpoint_auth_method": {
                    "default": "client_secret_post",
                    "description": "Token endpoint authentication method",
                    "enum": [
                      "client_secret_post",
                      "client_secret_basic",
                      "none"
                    ],
                    "type": "string"
                  },
                  "type": {
                    "description": "Identity provider type - currently only OIDC supported",
                    "enum": [
                      "oidc"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "identity_provider",
                  "name",
                  "type",
                  "domain",
                  "client_id",
                  "client_secret"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateIdentityProvider",
        "tags": [
          "IdentityProviders"
        ]
      }
    },
    "/v1/identity_providers/{identity_provider}": {
      "delete": {
        "operationId": "IdentityProvider_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteIdentityProvider",
        "tags": [
          "IdentityProviders"
        ]
      },
      "get": {
        "operationId": "IdentityProvider_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Google, existing accounts only": {
                    "value": {
                      "client_id": "<client-id>.apps.googleusercontent.com",
                      "client_secret": "<client-secret>",
                      "created": 1792263090753,
                      "display": {
                        "button_text": "Sign in with Google"
                      },
                      "domain": "accounts.google.com",
                      "enabled": true,
                      "identity_provider": "google",
                      "modified": 1792263090753,
                      "name": "Google",
                      "provisioning": {
                        "email_trust_mode": "verify_with_claim",
                        "mode": "match_only"
                      },
                      "type": "oidc"
                    }
                  },
                  "Microsoft Entra ID": {
                    "value": {
                      "client_id": "<application-id>",
                      "client_secret": "<client-secret>",
                      "created": 1792263090753,
                      "display": {
                        "button_text": "Sign in with Microsoft"
                      },
                      "domain": "login.microsoftonline.com/<tenant-id>/v2.0",
                      "enabled": true,
                      "identity_provider": "entra",
                      "modified": 1792263090753,
                      "name": "Microsoft",
                      "provisioning": {
                        "allowed_domains": [
                          "example.com"
                        ],
                        "email_trust_mode": "trust_idp",
                        "mode": "auto_provision"
                      },
                      "scopes": [
                        "openid",
                        "profile",
                        "email"
                      ],
                      "type": "oidc"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadIdentityProviderConfig",
        "tags": [
          "IdentityProviders"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "identity_provider",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "IdentityProvider_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "client_id": "<client-id>.apps.googleusercontent.com",
                    "client_secret": "<client-secret>",
                    "display": {
                      "button_text": "Sign in with Google"
                    },
                    "domain": "accounts.google.com",
                    "enabled": true,
                    "identity_provider": "google",
                    "name": "Google",
                    "provisioning": {
                      "email_trust_mode": "verify_with_claim",
                      "mode": "match_only"
                    },
                    "type": "oidc"
                  }
                },
                "Update 'client_id'": {
                  "value": {
                    "client_id": "<client-id>.apps.googleusercontent.com"
                  }
                },
                "Update 'client_secret'": {
                  "value": {
                    "client_secret": "<client-secret>"
                  }
                },
                "Update 'display'": {
                  "value": {
                    "display": {
                      "button_text": "Sign in with Google"
                    }
                  }
                },
                "Update 'domain'": {
                  "value": {
                    "domain": "accounts.google.com"
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Google"
                  }
                },
                "Update 'provisioning'": {
                  "value": {
                    "provisioning": {
                      "email_trust_mode": "verify_with_claim",
                      "mode": "match_only"
                    }
                  }
                },
                "Update 'type'": {
                  "value": {
                    "type": "oidc"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "attribute_mapping": {
                    "properties": {
                      "company": {
                        "type": "string"
                      },
                      "email": {
                        "type": "string"
                      },
                      "location": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "picture": {
                        "type": "string"
                      },
                      "username": {
                        "type": "string"
                      },
                      "website": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "display": {
                    "properties": {
                      "button_text": {
                        "type": "string"
                      },
                      "logo": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "domain": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  },
                  "provisioning": {
                    "properties": {
                      "allowed_domains": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "email_trust_mode": {
                        "enum": [
                          "trust_idp",
                          "verify_with_claim",
                          "always_verify"
                        ],
                        "type": "string"
                      },
                      "mode": {
                        "enum": [
                          "auto_provision",
                          "match_only"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "scopes": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "token_endpoint_auth_method": {
                    "enum": [
                      "client_secret_post",
                      "client_secret_basic",
                      "none"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateIdentityProvider",
        "tags": [
          "IdentityProviders"
        ]
      }
    },
    "/v1/identity_providers/{identity_provider}/test": {
      "parameters": [
        {
          "in": "path",
          "name": "identity_provider",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/oauth/providers/{identity_provider}": {
      "parameters": [
        {
          "in": "path",
          "name": "identity_provider",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/oauth_clients": {
      "get": {
        "operationId": "OauthClient_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090752,
                    "description": "Mobile and web app of Example",
                    "enabled": true,
                    "modified": 1792263090752,
                    "name": "Example App",
                    "oauth_client": "example_app"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListOauthClients",
        "tags": [
          "OauthClients"
        ]
      },
      "post": {
        "operationId": "OauthClient_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Web application": {
                  "value": {
                    "description": "Mobile and web app of Example",
                    "enabled": true,
                    "name": "Example App",
                    "oauth_client": "example_app",
                    "prompt": "Example App wants to read your devices",
                    "redirect_uri": "https://app.example.com/oauth/callback\nhttp://localhost:4200/oauth/callback",
                    "scope": {
                      "Device": {
                        "*": [
                          "ListDevices",
                          "ReadDevice"
                        ]
                      }
                    },
                    "secret": "change-this-long-random-secret"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "enabled": {
                    "description": "Disabled clients cannot authorize nor get tokens.",
                    "type": "boolean"
                  },
                  "name": {
                    "description": "Application name shown on the consent screen.",
                    "type": "string"
                  },
                  "oauth_client": {
                    "description": "Client id used by the application in the OAuth2 flows (authorization code, device flow).",
                    "pattern": "^[a-zA-Z0-9-_]{1,32}$",
                    "type": "string"
                  },
                  "picture": {
                    "description": "Logo shown on the consent screen, as a data URL.",
                    "type": "string"
                  },
                  "prompt": {
                    "description": "Text of the consent screen.",
                    "type": "string"
                  },
                  "redirect_uri": {
                    "description": "Allowed redirect URIs, one per line (newline separated). The redirect_uri of each request must match one of them exactly (case-insensitive).",
                    "type": "string"
                  },
                  "scope": {
                    "description": "Permissions requested for the application, as a permission tree ({\"Device\": {\"*\": [\"ReadDevice\"]}}). Informational: the token scope comes from the authorize request.",
                    "type": "object"
                  },
                  "secret": {
                    "description": "Client secret. Stored as is and returned to admins.",
                    "type": "string"
                  }
                },
                "required": [
                  "oauth_client",
                  "name",
                  "secret",
                  "redirect_uri"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateOauthClient",
        "tags": [
          "OauthClients"
        ]
      }
    },
    "/v1/oauth_clients/{oauth_client}": {
      "delete": {
        "operationId": "OauthClient_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteOauthClient",
        "tags": [
          "OauthClients"
        ]
      },
      "get": {
        "operationId": "OauthClient_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Web application": {
                    "value": {
                      "created": 1792263090752,
                      "description": "Mobile and web app of Example",
                      "enabled": true,
                      "modified": 1792263090752,
                      "name": "Example App",
                      "oauth_client": "example_app",
                      "prompt": "Example App wants to read your devices",
                      "redirect_uri": "https://app.example.com/oauth/callback\nhttp://localhost:4200/oauth/callback",
                      "scope": {
                        "Device": {
                          "*": [
                            "ListDevices",
                            "ReadDevice"
                          ]
                        }
                      },
                      "secret": "change-this-long-random-secret"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadOauthClientConfig",
        "tags": [
          "OauthClients"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "oauth_client",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "OauthClient_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "description": "Mobile and web app of Example",
                    "enabled": true,
                    "name": "Example App",
                    "oauth_client": "example_app",
                    "prompt": "Example App wants to read your devices",
                    "redirect_uri": "https://app.example.com/oauth/callback\nhttp://localhost:4200/oauth/callback",
                    "scope": {
                      "Device": {
                        "*": [
                          "ListDevices",
                          "ReadDevice"
                        ]
                      }
                    },
                    "secret": "change-this-long-random-secret"
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Mobile and web app of Example"
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Example App"
                  }
                },
                "Update 'prompt'": {
                  "value": {
                    "prompt": "Example App wants to read your devices"
                  }
                },
                "Update 'redirect_uri'": {
                  "value": {
                    "redirect_uri": "https://app.example.com/oauth/callback\nhttp://localhost:4200/oauth/callback"
                  }
                },
                "Update 'scope'": {
                  "value": {
                    "scope": {
                      "Device": {
                        "*": [
                          "ListDevices",
                          "ReadDevice"
                        ]
                      }
                    }
                  }
                },
                "Update 'secret'": {
                  "value": {
                    "secret": "change-this-long-random-secret"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  },
                  "picture": {
                    "type": "string"
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "object"
                  },
                  "secret": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateOauthClient",
        "tags": [
          "OauthClients"
        ]
      }
    },
    "/v1/oauth_clients/{oauth_client}/info": {
      "parameters": [
        {
          "in": "path",
          "name": "oauth_client",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/proxies": {
      "get": {
        "operationId": "Proxy_ListProxies",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090786,
                    "description": "Served at https://grafana.<server hostname>: the proxy id is the subdomain, and it needs a wildcard certificate",
                    "enabled": true,
                    "modified": 1792263090786,
                    "name": "Grafana",
                    "proxy": "grafana"
                  },
                  {
                    "created": 1792263090786,
                    "description": "TCP Proxy Description",
                    "enabled": true,
                    "modified": 1792263090786,
                    "name": "TCP Proxy Name",
                    "proxy": "tcp_proxy_id"
                  },
                  {
                    "created": 1792263090786,
                    "description": "TCP Proxy Description",
                    "enabled": true,
                    "modified": 1792263090786,
                    "name": "TCP Proxy Name",
                    "proxy": "tcp_proxy_id"
                  },
                  {
                    "created": 1792263090786,
                    "description": "UDP Proxy Description",
                    "enabled": true,
                    "modified": 1792263090786,
                    "name": "UDP Proxy Name",
                    "proxy": "udp_proxy_id"
                  },
                  {
                    "created": 1792263090786,
                    "description": "UDP Proxy Description",
                    "enabled": true,
                    "modified": 1792263090786,
                    "name": "UDP Proxy Name",
                    "proxy": "udp_proxy_id"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProxies",
        "tags": [
          "Proxies"
        ]
      },
      "post": {
        "operationId": "Proxy_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "HTTPS Subdomain to Plugin": {
                  "value": {
                    "config": {
                      "protocol": "tcp",
                      "source": {
                        "routing": "subdomain",
                        "secure": true
                      },
                      "target": {
                        "plugin": {
                          "name": "grafana",
                          "user": "user_id"
                        },
                        "port": 3000,
                        "secure": false,
                        "type": "plugin"
                      }
                    },
                    "description": "Served at https://grafana.<server hostname>: the proxy id is the subdomain, and it needs a wildcard certificate",
                    "enabled": true,
                    "name": "Grafana",
                    "proxy": "grafana"
                  }
                },
                "TCP Proxy to Host": {
                  "value": {
                    "config": {
                      "protocol": "tcp",
                      "source": {
                        "port": 8090,
                        "secure": true
                      },
                      "target": {
                        "address": "localhost",
                        "port": 8086,
                        "secure": false,
                        "type": "address"
                      }
                    },
                    "description": "TCP Proxy Description",
                    "enabled": true,
                    "name": "TCP Proxy Name",
                    "proxy": "tcp_proxy_id"
                  }
                },
                "TCP Proxy to Plugin": {
                  "value": {
                    "config": {
                      "protocol": "tcp",
                      "source": {
                        "port": 8090,
                        "secure": true
                      },
                      "target": {
                        "plugin": {
                          "name": "plugin_id",
                          "user": "user_id"
                        },
                        "port": 8086,
                        "secure": false,
                        "type": "plugin"
                      }
                    },
                    "description": "TCP Proxy Description",
                    "enabled": true,
                    "name": "TCP Proxy Name",
                    "proxy": "tcp_proxy_id"
                  }
                },
                "UDP Proxy to Host": {
                  "value": {
                    "config": {
                      "protocol": "udp",
                      "source": {
                        "port": 9000
                      },
                      "target": {
                        "address": "localhost",
                        "port": 9000,
                        "type": "address"
                      }
                    },
                    "description": "UDP Proxy Description",
                    "enabled": true,
                    "name": "UDP Proxy Name",
                    "proxy": "udp_proxy_id"
                  }
                },
                "UDP Proxy to Plugin": {
                  "value": {
                    "config": {
                      "protocol": "udp",
                      "source": {
                        "port": 9000
                      },
                      "target": {
                        "plugin": {
                          "name": "plugin_id",
                          "user": "user_id"
                        },
                        "port": 9000,
                        "type": "plugin"
                      }
                    },
                    "description": "UDP Proxy Description",
                    "enabled": true,
                    "name": "UDP Proxy Name",
                    "proxy": "udp_proxy_id"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "description": "protocol: tcp, udp, tcp_iotmp or http_iotmp. source: {port (number), secure (TLS), routing: port | subdomain (the proxy id becomes the subdomain of the server hostname), allowed_ips (IOTMP)}. target: {type: address | plugin, address, plugin: {user, name}, port (number), secure, timeout (seconds, default 10)}; IOTMP protocols also take target.user and target.device. options.timeout_minutes expires sessions. port_management (default true) opens ports on Thinger-hosted servers. Creating or updating starts the listener right away; an update with a partial config replaces the stored config.",
                    "type": "object"
                  },
                  "description": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  },
                  "proxy": {
                    "pattern": "^[a-zA-Z0-9-_]{1,32}$",
                    "type": "string"
                  }
                },
                "required": [
                  "proxy",
                  "name",
                  "config"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProxy",
        "tags": [
          "Proxies"
        ]
      }
    },
    "/v1/proxies/{proxy}": {
      "delete": {
        "operationId": "Proxy_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProxy",
        "tags": [
          "Proxies"
        ]
      },
      "get": {
        "operationId": "Proxy_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "HTTPS Subdomain to Plugin": {
                    "value": {
                      "config": {
                        "protocol": "tcp",
                        "source": {
                          "routing": "subdomain",
                          "secure": true
                        },
                        "target": {
                          "plugin": {
                            "name": "grafana",
                            "user": "user_id"
                          },
                          "port": 3000,
                          "secure": false,
                          "type": "plugin"
                        }
                      },
                      "created": 1792263090786,
                      "description": "Served at https://grafana.<server hostname>: the proxy id is the subdomain, and it needs a wildcard certificate",
                      "enabled": true,
                      "modified": 1792263090786,
                      "name": "Grafana",
                      "proxy": "grafana"
                    }
                  },
                  "TCP Proxy to Host": {
                    "value": {
                      "config": {
                        "protocol": "tcp",
                        "source": {
                          "port": 8090,
                          "secure": true
                        },
                        "target": {
                          "address": "localhost",
                          "port": 8086,
                          "secure": false,
                          "type": "address"
                        }
                      },
                      "created": 1792263090786,
                      "description": "TCP Proxy Description",
                      "enabled": true,
                      "modified": 1792263090786,
                      "name": "TCP Proxy Name",
                      "proxy": "tcp_proxy_id"
                    }
                  },
                  "TCP Proxy to Plugin": {
                    "value": {
                      "config": {
                        "protocol": "tcp",
                        "source": {
                          "port": 8090,
                          "secure": true
                        },
                        "target": {
                          "plugin": {
                            "name": "plugin_id",
                            "user": "user_id"
                          },
                          "port": 8086,
                          "secure": false,
                          "type": "plugin"
                        }
                      },
                      "created": 1792263090786,
                      "description": "TCP Proxy Description",
                      "enabled": true,
                      "modified": 1792263090786,
                      "name": "TCP Proxy Name",
                      "proxy": "tcp_proxy_id"
                    }
                  },
                  "UDP Proxy to Host": {
                    "value": {
                      "config": {
                        "protocol": "udp",
                        "source": {
                          "port": 9000
                        },
                        "target": {
                          "address": "localhost",
                          "port": 9000,
                          "type": "address"
                        }
                      },
                      "created": 1792263090786,
                      "description": "UDP Proxy Description",
                      "enabled": true,
                      "modified": 1792263090786,
                      "name": "UDP Proxy Name",
                      "proxy": "udp_proxy_id"
                    }
                  },
                  "UDP Proxy to Plugin": {
                    "value": {
                      "config": {
                        "protocol": "udp",
                        "source": {
                          "port": 9000
                        },
                        "target": {
                          "plugin": {
                            "name": "plugin_id",
                            "user": "user_id"
                          },
                          "port": 9000,
                          "type": "plugin"
                        }
                      },
                      "created": 1792263090786,
                      "description": "UDP Proxy Description",
                      "enabled": true,
                      "modified": 1792263090786,
                      "name": "UDP Proxy Name",
                      "proxy": "udp_proxy_id"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProxyConfig",
        "tags": [
          "Proxies"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "proxy",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Proxy_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "config": {
                      "protocol": "tcp",
                      "source": {
                        "routing": "subdomain",
                        "secure": true
                      },
                      "target": {
                        "plugin": {
                          "name": "grafana",
                          "user": "user_id"
                        },
                        "port": 3000,
                        "secure": false,
                        "type": "plugin"
                      }
                    },
                    "description": "Served at https://grafana.<server hostname>: the proxy id is the subdomain, and it needs a wildcard certificate",
                    "enabled": true,
                    "name": "Grafana",
                    "proxy": "grafana"
                  }
                },
                "Update 'config'": {
                  "value": {
                    "config": {
                      "protocol": "tcp",
                      "source": {
                        "routing": "subdomain",
                        "secure": true
                      },
                      "target": {
                        "plugin": {
                          "name": "grafana",
                          "user": "user_id"
                        },
                        "port": 3000,
                        "secure": false,
                        "type": "plugin"
                      }
                    }
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Served at https://grafana.<server hostname>: the proxy id is the subdomain, and it needs a wildcard certificate"
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Grafana"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "type": "object"
                  },
                  "description": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProxy",
        "tags": [
          "Proxies"
        ]
      }
    },
    "/v1/server/actions": {
      "get": {
        "operationId": "Server_ReadActions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadServerActions",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/assets": {
      "get": {
        "operationId": "Server_ReadAssets",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerAssets",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/buckets/backends": {
      "get": {
        "operationId": "Server_ReadBucketsBackends",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerBucketsBackends",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/events": {
      "get": {
        "operationId": "Server_ReadEvents",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerEvents",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/healthcheck": {
      "get": {
        "operationId": "Server_ReadHealthcheck",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerHealthcheck",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/settings": {
      "get": {
        "operationId": "Server_ReadSettings",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadServerSettings",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/statistics": {
      "get": {
        "operationId": "Server_ReadStatistics",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadServerStatistics",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/swagger.json": {
      "get": {
        "operationId": "Server_ReadApiSwagger.json",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "ReadServerApi",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/server/version": {
      "get": {
        "operationId": "Server_ReadVersion",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadServerVersion",
        "tags": [
          "Server"
        ]
      }
    },
    "/v1/users": {
      "get": {
        "operationId": "User_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090745,
                    "email": "jdoe@example.com",
                    "enabled": true,
                    "modified": 1792263090745,
                    "role": "user",
                    "user": "jdoe",
                    "verified": true
                  },
                  {
                    "created": 1792263090745,
                    "email": "operator1@example.com",
                    "enabled": true,
                    "modified": 1792263090745,
                    "role": "member",
                    "user": "operator1",
                    "verified": true
                  },
                  {
                    "created": 1792263090745,
                    "email": "jdoe@example.com",
                    "enabled": true,
                    "modified": 1792263090745,
                    "role": "user",
                    "user": "jdoe",
                    "verified": true
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListUsers",
        "tags": [
          "Users"
        ]
      },
      "post": {
        "operationId": "User_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Account that sets its own password": {
                  "value": {
                    "email": "jdoe@example.com",
                    "enabled": true,
                    "password": "",
                    "role": "user",
                    "user": "jdoe",
                    "verified": true
                  }
                },
                "Member of a project": {
                  "value": {
                    "email": "operator1@example.com",
                    "enabled": true,
                    "options": {
                      "project": {
                        "default": "plant_madrid"
                      }
                    },
                    "password": "a-strong-password",
                    "role": "member",
                    "user": "operator1",
                    "verified": true
                  }
                },
                "Regular account": {
                  "value": {
                    "email": "jdoe@example.com",
                    "enabled": true,
                    "password": "a-strong-password",
                    "role": "user",
                    "user": "jdoe",
                    "verified": true
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "email": {
                    "format": "email",
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "options": {
                    "additionalProperties": false,
                    "properties": {
                      "project": {
                        "additionalProperties": false,
                        "properties": {
                          "default": {
                            "$ref": "#/components/schemas/resource_id"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  },
                  "password": {
                    "description": "Empty, when an admin creates the account: the user receives an email to set it.",
                    "maxLength": 72,
                    "type": "string"
                  },
                  "recaptcha": {
                    "type": "string"
                  },
                  "role": {
                    "description": "user: a regular account. admin: server administrator (only admins create admins and domain admins). domain_admin: administers the accounts of its hosts. member: only works inside the projects it is invited to (needs options.project.default).",
                    "enum": [
                      "user",
                      "admin",
                      "member",
                      "domain_admin"
                    ],
                    "type": "string"
                  },
                  "user": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "verified": {
                    "description": "Email already verified (admins can skip the verification email).",
                    "type": "boolean"
                  }
                },
                "required": [
                  "user",
                  "email",
                  "password"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateUser",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/email/verify": {
      "post": {
        "operationId": "User_VerifyEmail",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          }
        },
        "summary": "VerifyUserEmail",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}": {
      "delete": {
        "operationId": "User_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteUser",
        "tags": [
          "Users"
        ]
      },
      "get": {
        "operationId": "User_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Account that sets its own password": {
                    "value": {
                      "created": 1792263090745,
                      "email": "jdoe@example.com",
                      "enabled": true,
                      "modified": 1792263090745,
                      "password": "",
                      "role": "user",
                      "user": "jdoe",
                      "verified": true
                    }
                  },
                  "Member of a project": {
                    "value": {
                      "created": 1792263090745,
                      "email": "operator1@example.com",
                      "enabled": true,
                      "modified": 1792263090745,
                      "options": {
                        "project": {
                          "default": "plant_madrid"
                        }
                      },
                      "password": "a-strong-password",
                      "role": "member",
                      "user": "operator1",
                      "verified": true
                    }
                  },
                  "Regular account": {
                    "value": {
                      "created": 1792263090745,
                      "email": "jdoe@example.com",
                      "enabled": true,
                      "modified": 1792263090745,
                      "password": "a-strong-password",
                      "role": "user",
                      "user": "jdoe",
                      "verified": true
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserConfig",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable an account": {
                  "value": {
                    "enabled": false
                  }
                },
                "Make it a domain admin of a brand": {
                  "value": {
                    "host": [
                      "iot.example.com"
                    ],
                    "role": "domain_admin"
                  }
                },
                "Raise its limits": {
                  "value": {
                    "limits": {
                      "buckets": {
                        "max_count": 50
                      },
                      "devices": {
                        "max_count": 500
                      }
                    }
                  }
                },
                "Set a new password": {
                  "value": {
                    "password": "a-new-strong-password"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "host": {
                    "description": "Domains the account belongs to (set on sign-up from the request host). Used for the brand emails, brand cross_sign_in and domain admins.",
                    "items": {
                      "pattern": "^(?:[a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+(?:\\.[a-zA-Z]{2,11})?$",
                      "type": "string"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "limits": {
                    "description": "Per-account overrides of the server limits: {\"<collection>\": {\"max_count\": n}} (-1 = unlimited, 0 = disabled), and buckets.retention {period, unit}.",
                    "type": "object"
                  },
                  "options": {
                    "additionalProperties": false,
                    "properties": {
                      "additionalProperties": false,
                      "project": {
                        "properties": {
                          "default": {
                            "$ref": "#/components/schemas/resource_id"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  },
                  "password": {
                    "maxLength": 72,
                    "minLength": 6,
                    "type": "string"
                  },
                  "role": {
                    "enum": [
                      "user",
                      "admin",
                      "member",
                      "domain_admin"
                    ],
                    "type": "string"
                  },
                  "verified": {
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateUser",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/account": {
      "get": {
        "operationId": "User_ReadAccount",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserAccount",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/alarms/instances": {
      "get": {
        "operationId": "Alarm_ListInstances",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListAlarmInstances",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_CreateInstance",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "alarm": {
                    "additionalProperties": false,
                    "properties": {
                      "rule": {
                        "$ref": "#/components/schemas/resource_id"
                      }
                    },
                    "type": "object"
                  },
                  "annotation": {
                    "maxLength": 512,
                    "type": "string"
                  },
                  "asset_group": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "asset_type": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "evaluation": {
                    "properties": {
                      "last_completed": {
                        "type": "number"
                      },
                      "last_values": {
                        "type": "object"
                      },
                      "total_duration": {
                        "type": "number"
                      }
                    },
                    "type": "object"
                  },
                  "instance": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "origin": {
                    "properties": {
                      "id": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "name": {
                        "$ref": "#/components/schemas/resource_name"
                      },
                      "source": {
                        "enum": [
                          "device",
                          "user"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "source",
                      "id",
                      "name"
                    ],
                    "type": "object"
                  },
                  "reactivation": {
                    "properties": {
                      "timespan": {
                        "properties": {
                          "magnitude": {
                            "enum": [
                              "second",
                              "minute",
                              "hour",
                              "day",
                              "week",
                              "month",
                              "year"
                            ],
                            "type": "string"
                          },
                          "value": {
                            "minimum": 0,
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      "type": {
                        "enum": [
                          "none",
                          "timespan"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "severity": {
                    "maximum": 4,
                    "minimum": 0,
                    "type": "number"
                  },
                  "state": {
                    "maximum": 4,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "required": [
                  "instance",
                  "alarm",
                  "name",
                  "state",
                  "severity",
                  "origin",
                  "evaluation"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateAlarmInstance",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/instances/stats": {
      "get": {
        "operationId": "Alarm_ReadInstanceStats",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAlarmInstanceStats",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/alarms/instances/{instance}": {
      "delete": {
        "operationId": "Alarm_DeleteInstance",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteAlarmInstance",
        "tags": [
          "Alarms"
        ]
      },
      "get": {
        "operationId": "Alarm_ReadInstanceConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAlarmInstanceConfig",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "instance",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Alarm_UpdateInstance",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Acknowledge": {
                  "value": {
                    "annotation": "Technician on the way",
                    "state": 2
                  }
                },
                "Clear": {
                  "value": {
                    "annotation": "Fan replaced",
                    "state": 5
                  }
                },
                "Shelve for 4 hours": {
                  "value": {
                    "annotation": "Planned maintenance",
                    "reactivation": {
                      "timespan": {
                        "magnitude": "hour",
                        "value": 4
                      },
                      "type": "timespan"
                    },
                    "state": 4
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Mostly used to change the state of an alarm instance: 0 none, 1 activated, 2 acknowledged, 3 latched, 4 shelved, 5 cleared (final). 'reactivation' sets when an acknowledged, shelved or latched alarm becomes active again if the condition persists.",
                "properties": {
                  "annotation": {
                    "maxLength": 512,
                    "type": "string"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "reactivation": {
                    "properties": {
                      "timespan": {
                        "properties": {
                          "magnitude": {
                            "enum": [
                              "second",
                              "minute",
                              "hour",
                              "day",
                              "week",
                              "month",
                              "year"
                            ],
                            "type": "string"
                          },
                          "value": {
                            "minimum": 0,
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      "type": {
                        "enum": [
                          "none",
                          "timespan"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "state": {
                    "maximum": 6,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateAlarmInstance",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/instances/{instance}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "instance",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Alarm_UpdateInstanceProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateAlarmInstanceProjects",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules": {
      "get": {
        "operationId": "Alarm_ListRules",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090787,
                    "description": "Mean temperature above 30 for 3 checks in a row, per device",
                    "enabled": true,
                    "modified": 1792263090787,
                    "name": "Greenhouse too hot",
                    "rule": "greenhouse_hot"
                  },
                  {
                    "created": 1792263090787,
                    "description": "Any device of the smart_meter product disconnected",
                    "enabled": true,
                    "modified": 1792263090787,
                    "name": "Meter offline",
                    "rule": "meter_offline"
                  },
                  {
                    "created": 1792263090787,
                    "description": "Hourly max depth of each well above its own limit: the 'limits' property of the device, or of its asset type, asset group or product when the device has none",
                    "enabled": true,
                    "modified": 1792263090787,
                    "name": "Water table too deep",
                    "rule": "well_too_deep"
                  },
                  {
                    "created": 1792263090787,
                    "description": "Battery level reported in the 'battery' property below 15%, devices of the 'field_sensors' group",
                    "enabled": true,
                    "modified": 1792263090787,
                    "name": "Low battery",
                    "rule": "low_battery"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListAlarmRules",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_CreateRule",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Bucket threshold": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "climate.temperature",
                            "operator": "and",
                            "type": "value_check",
                            "value": "30"
                          }
                        ],
                        "confirmation": {
                          "mode": "sequence",
                          "sequence": {
                            "value": 3
                          }
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 5
                      },
                      "data": {
                        "sources": [
                          {
                            "bucket": {
                              "aggregation": {
                                "period": "5m",
                                "type": "mean"
                              },
                              "group_by": [
                                "device"
                              ],
                              "id": "greenhouse_climate",
                              "mapping": [
                                "temperature"
                              ]
                            },
                            "name": "climate",
                            "source": "bucket"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "climate.temperature",
                            "operator": "and",
                            "type": "value_check",
                            "value": "28"
                          }
                        ],
                        "confirmation": {
                          "mode": "timespan",
                          "timespan": {
                            "magnitude": "minute",
                            "value": 15
                          }
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "reminder": {
                        "interval": {
                          "magnitude": "day",
                          "value": 1
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ],
                        "type": "interval"
                      },
                      "severity": 3
                    },
                    "description": "Mean temperature above 30 for 3 checks in a row, per device",
                    "enabled": true,
                    "name": "Greenhouse too hot",
                    "rule": "greenhouse_hot"
                  }
                },
                "Device offline": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "equal",
                            "field": "status.connection.active",
                            "operator": "and",
                            "type": "value_check",
                            "value": "0"
                          }
                        ],
                        "confirmation": {
                          "mode": "timespan",
                          "timespan": {
                            "magnitude": "minute",
                            "value": 10
                          }
                        },
                        "notifications": [
                          {
                            "id": "support_webhook",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 1
                      },
                      "data": {
                        "sources": [
                          {
                            "device_status": {
                              "fields": [
                                "connection.active",
                                "connection.ts"
                              ],
                              "product": "smart_meter"
                            },
                            "name": "status",
                            "source": "device_status"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "equal",
                            "field": "status.connection.active",
                            "operator": "and",
                            "type": "value_check",
                            "value": "1"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 2
                    },
                    "description": "Any device of the smart_meter product disconnected",
                    "enabled": true,
                    "name": "Meter offline",
                    "rule": "meter_offline"
                  }
                },
                "Per-device threshold": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "well.depth_m",
                            "operator": "and",
                            "type": "value_check",
                            "value": "limits.value.max_depth_m"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 15
                      },
                      "data": {
                        "sources": [
                          {
                            "bucket": {
                              "aggregation": {
                                "period": "1h",
                                "type": "max"
                              },
                              "group_by": [
                                "device"
                              ],
                              "id": "well_levels",
                              "mapping": [
                                "depth_m"
                              ]
                            },
                            "name": "well",
                            "source": "bucket"
                          },
                          {
                            "device_property": {
                              "fields": [
                                "value.max_depth_m"
                              ],
                              "product": "piezometer",
                              "property": "limits"
                            },
                            "name": "limits",
                            "source": "device_property"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "well.depth_m",
                            "operator": "and",
                            "type": "value_check",
                            "value": "limits.value.max_depth_m * 0.9"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 2
                    },
                    "description": "Hourly max depth of each well above its own limit: the 'limits' property of the device, or of its asset type, asset group or product when the device has none",
                    "enabled": true,
                    "name": "Water table too deep",
                    "rule": "well_too_deep"
                  }
                },
                "Property condition": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "battery.value.level",
                            "operator": "and",
                            "type": "value_check",
                            "value": "15"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "hour",
                        "value": 1
                      },
                      "data": {
                        "sources": [
                          {
                            "device_property": {
                              "asset_group": "field_sensors",
                              "fields": [
                                "value.level"
                              ],
                              "property": "battery"
                            },
                            "name": "battery",
                            "source": "device_property"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "battery.value.level",
                            "operator": "and",
                            "type": "value_check",
                            "value": "50"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 1
                    },
                    "description": "Battery level reported in the 'battery' property below 15%, devices of the 'field_sensors' group",
                    "enabled": true,
                    "name": "Low battery",
                    "rule": "low_battery"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "An alarm rule checks its data sources every check_interval and raises one alarm instance per device that meets the activation conditions. Sources: 'bucket' (bucket data, optionally aggregated and grouped by device), 'device_property' (a device property, resolved with type / group / product inheritance) and 'device_status' (connection.active, connection.ts). Sources can be narrowed with project, product, asset_type, asset_group or device. Conditions read '<source name>.<field>' and compare it with above, below, equal, not_equal (value), inside, outside (min, max), present or absent; a comparison on a field the device does not have is false (a bucket source with several mapping fields keeps a device that only has some of them), so 'a above 5 or b above 5' works on devices without b, and a device is skipped only when it has none of the fields the conditions read or misses a whole source (unless present / absent are used); values are strings, and can be expressions over other sources of the same device (e.g. 'limits.value.max_depth_m', a per-device threshold from a device_property source). device_property fields are paths in the property document: 'value.<field>'. Confirmation: immediate, sequence (N detections in a row) or timespan. Notifications call endpoints.",
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/alarm_rule"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "rule": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "rule",
                  "name",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateAlarmRule",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}": {
      "delete": {
        "operationId": "Alarm_DeleteRule",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteAlarmRule",
        "tags": [
          "Alarms"
        ]
      },
      "get": {
        "operationId": "Alarm_ReadRuleConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Bucket threshold": {
                    "value": {
                      "config": {
                        "activation": {
                          "conditions": [
                            {
                              "comparison": "above",
                              "field": "climate.temperature",
                              "operator": "and",
                              "type": "value_check",
                              "value": "30"
                            }
                          ],
                          "confirmation": {
                            "mode": "sequence",
                            "sequence": {
                              "value": 3
                            }
                          },
                          "notifications": [
                            {
                              "id": "ops_email",
                              "type": "endpoint"
                            }
                          ]
                        },
                        "check_interval": {
                          "magnitude": "minute",
                          "value": 5
                        },
                        "data": {
                          "sources": [
                            {
                              "bucket": {
                                "aggregation": {
                                  "period": "5m",
                                  "type": "mean"
                                },
                                "group_by": [
                                  "device"
                                ],
                                "id": "greenhouse_climate",
                                "mapping": [
                                  "temperature"
                                ]
                              },
                              "name": "climate",
                              "source": "bucket"
                            }
                          ]
                        },
                        "normalization": {
                          "conditions": [
                            {
                              "comparison": "below",
                              "field": "climate.temperature",
                              "operator": "and",
                              "type": "value_check",
                              "value": "28"
                            }
                          ],
                          "confirmation": {
                            "mode": "timespan",
                            "timespan": {
                              "magnitude": "minute",
                              "value": 15
                            }
                          },
                          "notifications": [
                            {
                              "id": "ops_email",
                              "type": "endpoint"
                            }
                          ]
                        },
                        "reminder": {
                          "interval": {
                            "magnitude": "day",
                            "value": 1
                          },
                          "notifications": [
                            {
                              "id": "ops_email",
                              "type": "endpoint"
                            }
                          ],
                          "type": "interval"
                        },
                        "severity": 3
                      },
                      "created": 1792263090787,
                      "description": "Mean temperature above 30 for 3 checks in a row, per device",
                      "enabled": true,
                      "modified": 1792263090787,
                      "name": "Greenhouse too hot",
                      "rule": "greenhouse_hot"
                    }
                  },
                  "Device offline": {
                    "value": {
                      "config": {
                        "activation": {
                          "conditions": [
                            {
                              "comparison": "equal",
                              "field": "status.connection.active",
                              "operator": "and",
                              "type": "value_check",
                              "value": "0"
                            }
                          ],
                          "confirmation": {
                            "mode": "timespan",
                            "timespan": {
                              "magnitude": "minute",
                              "value": 10
                            }
                          },
                          "notifications": [
                            {
                              "id": "support_webhook",
                              "type": "endpoint"
                            }
                          ]
                        },
                        "check_interval": {
                          "magnitude": "minute",
                          "value": 1
                        },
                        "data": {
                          "sources": [
                            {
                              "device_status": {
                                "fields": [
                                  "connection.active",
                                  "connection.ts"
                                ],
                                "product": "smart_meter"
                              },
                              "name": "status",
                              "source": "device_status"
                            }
                          ]
                        },
                        "normalization": {
                          "conditions": [
                            {
                              "comparison": "equal",
                              "field": "status.connection.active",
                              "operator": "and",
                              "type": "value_check",
                              "value": "1"
                            }
                          ],
                          "confirmation": {
                            "mode": "immediate"
                          },
                          "notifications": []
                        },
                        "reminder": {
                          "notifications": [],
                          "type": "none"
                        },
                        "severity": 2
                      },
                      "created": 1792263090787,
                      "description": "Any device of the smart_meter product disconnected",
                      "enabled": true,
                      "modified": 1792263090787,
                      "name": "Meter offline",
                      "rule": "meter_offline"
                    }
                  },
                  "Per-device threshold": {
                    "value": {
                      "config": {
                        "activation": {
                          "conditions": [
                            {
                              "comparison": "above",
                              "field": "well.depth_m",
                              "operator": "and",
                              "type": "value_check",
                              "value": "limits.value.max_depth_m"
                            }
                          ],
                          "confirmation": {
                            "mode": "immediate"
                          },
                          "notifications": [
                            {
                              "id": "ops_email",
                              "type": "endpoint"
                            }
                          ]
                        },
                        "check_interval": {
                          "magnitude": "minute",
                          "value": 15
                        },
                        "data": {
                          "sources": [
                            {
                              "bucket": {
                                "aggregation": {
                                  "period": "1h",
                                  "type": "max"
                                },
                                "group_by": [
                                  "device"
                                ],
                                "id": "well_levels",
                                "mapping": [
                                  "depth_m"
                                ]
                              },
                              "name": "well",
                              "source": "bucket"
                            },
                            {
                              "device_property": {
                                "fields": [
                                  "value.max_depth_m"
                                ],
                                "product": "piezometer",
                                "property": "limits"
                              },
                              "name": "limits",
                              "source": "device_property"
                            }
                          ]
                        },
                        "normalization": {
                          "conditions": [
                            {
                              "comparison": "below",
                              "field": "well.depth_m",
                              "operator": "and",
                              "type": "value_check",
                              "value": "limits.value.max_depth_m * 0.9"
                            }
                          ],
                          "confirmation": {
                            "mode": "immediate"
                          },
                          "notifications": []
                        },
                        "reminder": {
                          "notifications": [],
                          "type": "none"
                        },
                        "severity": 2
                      },
                      "created": 1792263090787,
                      "description": "Hourly max depth of each well above its own limit: the 'limits' property of the device, or of its asset type, asset group or product when the device has none",
                      "enabled": true,
                      "modified": 1792263090787,
                      "name": "Water table too deep",
                      "rule": "well_too_deep"
                    }
                  },
                  "Property condition": {
                    "value": {
                      "config": {
                        "activation": {
                          "conditions": [
                            {
                              "comparison": "below",
                              "field": "battery.value.level",
                              "operator": "and",
                              "type": "value_check",
                              "value": "15"
                            }
                          ],
                          "confirmation": {
                            "mode": "immediate"
                          },
                          "notifications": [
                            {
                              "id": "ops_email",
                              "type": "endpoint"
                            }
                          ]
                        },
                        "check_interval": {
                          "magnitude": "hour",
                          "value": 1
                        },
                        "data": {
                          "sources": [
                            {
                              "device_property": {
                                "asset_group": "field_sensors",
                                "fields": [
                                  "value.level"
                                ],
                                "property": "battery"
                              },
                              "name": "battery",
                              "source": "device_property"
                            }
                          ]
                        },
                        "normalization": {
                          "conditions": [
                            {
                              "comparison": "above",
                              "field": "battery.value.level",
                              "operator": "and",
                              "type": "value_check",
                              "value": "50"
                            }
                          ],
                          "confirmation": {
                            "mode": "immediate"
                          },
                          "notifications": []
                        },
                        "reminder": {
                          "notifications": [],
                          "type": "none"
                        },
                        "severity": 1
                      },
                      "created": 1792263090787,
                      "description": "Battery level reported in the 'battery' property below 15%, devices of the 'field_sensors' group",
                      "enabled": true,
                      "modified": 1792263090787,
                      "name": "Low battery",
                      "rule": "low_battery"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAlarmRuleConfig",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Alarm_UpdateRule",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable the rule": {
                  "value": {
                    "enabled": false
                  }
                },
                "Rename": {
                  "value": {
                    "description": "Zone A sensors only",
                    "name": "Greenhouse too hot - zone A"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Fields sent replace the stored ones; config replaces the whole rule configuration (read it first to change part of it).",
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/alarm_rule"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateAlarmRule",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}/clone": {
      "get": {
        "operationId": "Alarm_CloneRuleConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneAlarmRuleConfig",
        "tags": [
          "Alarms"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_CloneRule",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "rule": "copy_of_rule"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "rule": "line_2_rule"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "rule": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "rule"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneAlarmRule",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Alarm_UpdateRuleProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateAlarmRuleProjects",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}/test-notification": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_TestRuleNotificationTest-notification",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Activation of a device": {
                  "value": {
                    "config": {
                      "activation": {
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "severity": 3
                    },
                    "description": "Mean temperature above 30",
                    "event": {
                      "origin": "greenhouse_01",
                      "type": "activation",
                      "values": {
                        "climate": {
                          "temperature": 31.2
                        }
                      }
                    },
                    "name": "Greenhouse too hot"
                  }
                }
              },
              "schema": {
                "description": "Simulates an alarm event of a device and SENDS the notifications configured for that event type (config.<type>.notifications) to their endpoints, so real emails or webhooks go out. Returns the notifications and the alarm payload they carried. Nothing is stored.",
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/alarm_rule"
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "event": {
                    "properties": {
                      "origin": {
                        "description": "Device id.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "type": {
                        "enum": [
                          "activation",
                          "normalization",
                          "reminder"
                        ],
                        "type": "string"
                      },
                      "values": {
                        "description": "Source values that triggered the event, by source name."
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "event"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "TestRuleNotification",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}/test-rule": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_TestRuleTest-rule",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Bucket threshold": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "climate.temperature",
                            "operator": "and",
                            "type": "value_check",
                            "value": "30"
                          }
                        ],
                        "confirmation": {
                          "mode": "sequence",
                          "sequence": {
                            "value": 3
                          }
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 5
                      },
                      "data": {
                        "sources": [
                          {
                            "bucket": {
                              "aggregation": {
                                "period": "5m",
                                "type": "mean"
                              },
                              "group_by": [
                                "device"
                              ],
                              "id": "greenhouse_climate",
                              "mapping": [
                                "temperature"
                              ]
                            },
                            "name": "climate",
                            "source": "bucket"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "climate.temperature",
                            "operator": "and",
                            "type": "value_check",
                            "value": "28"
                          }
                        ],
                        "confirmation": {
                          "mode": "timespan",
                          "timespan": {
                            "magnitude": "minute",
                            "value": 15
                          }
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "reminder": {
                        "interval": {
                          "magnitude": "day",
                          "value": 1
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ],
                        "type": "interval"
                      },
                      "severity": 3
                    },
                    "description": "Mean temperature above 30 for 3 checks in a row, per device",
                    "enabled": true,
                    "name": "Greenhouse too hot"
                  }
                },
                "Device offline": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "equal",
                            "field": "status.connection.active",
                            "operator": "and",
                            "type": "value_check",
                            "value": "0"
                          }
                        ],
                        "confirmation": {
                          "mode": "timespan",
                          "timespan": {
                            "magnitude": "minute",
                            "value": 10
                          }
                        },
                        "notifications": [
                          {
                            "id": "support_webhook",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 1
                      },
                      "data": {
                        "sources": [
                          {
                            "device_status": {
                              "fields": [
                                "connection.active",
                                "connection.ts"
                              ],
                              "product": "smart_meter"
                            },
                            "name": "status",
                            "source": "device_status"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "equal",
                            "field": "status.connection.active",
                            "operator": "and",
                            "type": "value_check",
                            "value": "1"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 2
                    },
                    "description": "Any device of the smart_meter product disconnected",
                    "enabled": true,
                    "name": "Meter offline"
                  }
                },
                "Per-device threshold": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "well.depth_m",
                            "operator": "and",
                            "type": "value_check",
                            "value": "limits.value.max_depth_m"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "minute",
                        "value": 15
                      },
                      "data": {
                        "sources": [
                          {
                            "bucket": {
                              "aggregation": {
                                "period": "1h",
                                "type": "max"
                              },
                              "group_by": [
                                "device"
                              ],
                              "id": "well_levels",
                              "mapping": [
                                "depth_m"
                              ]
                            },
                            "name": "well",
                            "source": "bucket"
                          },
                          {
                            "device_property": {
                              "fields": [
                                "value.max_depth_m"
                              ],
                              "product": "piezometer",
                              "property": "limits"
                            },
                            "name": "limits",
                            "source": "device_property"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "well.depth_m",
                            "operator": "and",
                            "type": "value_check",
                            "value": "limits.value.max_depth_m * 0.9"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 2
                    },
                    "description": "Hourly max depth of each well above its own limit: the 'limits' property of the device, or of its asset type, asset group or product when the device has none",
                    "enabled": true,
                    "name": "Water table too deep"
                  }
                },
                "Property condition": {
                  "value": {
                    "config": {
                      "activation": {
                        "conditions": [
                          {
                            "comparison": "below",
                            "field": "battery.value.level",
                            "operator": "and",
                            "type": "value_check",
                            "value": "15"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": [
                          {
                            "id": "ops_email",
                            "type": "endpoint"
                          }
                        ]
                      },
                      "check_interval": {
                        "magnitude": "hour",
                        "value": 1
                      },
                      "data": {
                        "sources": [
                          {
                            "device_property": {
                              "asset_group": "field_sensors",
                              "fields": [
                                "value.level"
                              ],
                              "property": "battery"
                            },
                            "name": "battery",
                            "source": "device_property"
                          }
                        ]
                      },
                      "normalization": {
                        "conditions": [
                          {
                            "comparison": "above",
                            "field": "battery.value.level",
                            "operator": "and",
                            "type": "value_check",
                            "value": "50"
                          }
                        ],
                        "confirmation": {
                          "mode": "immediate"
                        },
                        "notifications": []
                      },
                      "reminder": {
                        "notifications": [],
                        "type": "none"
                      },
                      "severity": 1
                    },
                    "description": "Battery level reported in the 'battery' property below 15%, devices of the 'field_sensors' group",
                    "enabled": true,
                    "name": "Low battery"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Fields sent replace the stored ones; config replaces the whole rule configuration (read it first to change part of it).",
                "examples": {
                  "Disable the rule": {
                    "value": {
                      "enabled": false
                    }
                  },
                  "Rename": {
                    "value": {
                      "description": "Zone A sensors only",
                      "name": "Greenhouse too hot - zone A"
                    }
                  }
                },
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/alarm_rule"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "TestRule",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/alarms/rules/{rule}/test-source": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "rule",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Alarm_TestRuleSourceTest-source",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Bucket source": {
                  "value": {
                    "bucket": {
                      "aggregation": {
                        "period": "5m",
                        "type": "mean"
                      },
                      "group_by": [
                        "device"
                      ],
                      "id": "greenhouse_climate",
                      "mapping": [
                        "temperature"
                      ]
                    },
                    "name": "climate",
                    "source": "bucket"
                  }
                },
                "Device property source": {
                  "value": {
                    "device_property": {
                      "asset_group": "field_sensors",
                      "fields": [
                        "value.level"
                      ],
                      "property": "battery"
                    },
                    "name": "battery",
                    "source": "device_property"
                  }
                },
                "Device status source": {
                  "value": {
                    "device_status": {
                      "fields": [
                        "connection.active",
                        "connection.ts"
                      ],
                      "product": "smart_meter"
                    },
                    "name": "status",
                    "source": "device_status"
                  }
                }
              },
              "schema": {
                "description": "One data source, as in config.data.sources: returns the data it produces now, per device. The rule id in the path does not need to exist yet.",
                "properties": {
                  "bucket": {
                    "type": "object"
                  },
                  "check_interval": {
                    "description": "Window read by a bucket source without aggregation, as in config.check_interval (default: the rule's, or 1 minute). The rule does not need to exist.",
                    "type": "object"
                  },
                  "device_property": {
                    "type": "object"
                  },
                  "device_status": {
                    "type": "object"
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "source": {
                    "enum": [
                      "bucket",
                      "device_property",
                      "device_status"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "source"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "TestRuleSource",
        "tags": [
          "Alarms"
        ]
      }
    },
    "/v1/users/{user}/assets/locations": {
      "get": {
        "operationId": "Asset_ReadLocations",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAssetsLocations",
        "tags": [
          "Assets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/buckets": {
      "get": {
        "operationId": "Bucket_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "bucket": "api_write",
                    "config": {
                      "source": "api"
                    },
                    "created": 1792263090784,
                    "description": "Bucket for API write",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "API Write"
                  },
                  {
                    "bucket": "mqtt_bucket",
                    "config": {
                      "source": "mqtt",
                      "topic": "house/+/temperature"
                    },
                    "created": 1792263090784,
                    "description": "Bucket for MQTT topic",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "MQTT Bucket"
                  },
                  {
                    "bucket": "device_bucket",
                    "config": {
                      "device": "macbook",
                      "interval": 300,
                      "resource": "data",
                      "source": "device",
                      "update": "interval"
                    },
                    "created": 1792263090784,
                    "description": "Bucket for Thinger.io device",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "Device Bucket"
                  },
                  {
                    "bucket": "device_write",
                    "config": {
                      "source": "write"
                    },
                    "created": 1792263090784,
                    "description": "Bucket dor device write",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "Device Write"
                  },
                  {
                    "backend": "influxdb",
                    "bucket": "vibration",
                    "config": {
                      "device": "vibration_01",
                      "interval": 10,
                      "resource": "accel",
                      "source": "device",
                      "update": "interval"
                    },
                    "created": 1792263090784,
                    "description": "Accelerometer read every 10 seconds",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "Vibration"
                  },
                  {
                    "bucket": "meter_readings",
                    "config": {
                      "source": "write",
                      "tags": [
                        "device",
                        "site"
                      ]
                    },
                    "created": 1792263090784,
                    "description": "Readings written by every meter, tagged by device and site",
                    "enabled": true,
                    "modified": 1792263090784,
                    "name": "Meter readings"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListBuckets",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Bucket_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "From API Call": {
                  "value": {
                    "bucket": "api_write",
                    "config": {
                      "source": "api"
                    },
                    "description": "Bucket for API write",
                    "enabled": true,
                    "name": "API Write"
                  }
                },
                "From MQTT Topic": {
                  "value": {
                    "bucket": "mqtt_bucket",
                    "config": {
                      "source": "mqtt",
                      "topic": "house/+/temperature"
                    },
                    "description": "Bucket for MQTT topic",
                    "enabled": true,
                    "name": "MQTT Bucket"
                  }
                },
                "From Thinger Device": {
                  "value": {
                    "bucket": "device_bucket",
                    "config": {
                      "device": "macbook",
                      "interval": 300,
                      "resource": "data",
                      "source": "device",
                      "update": "interval"
                    },
                    "description": "Bucket for Thinger.io device",
                    "enabled": true,
                    "name": "Device Bucket"
                  }
                },
                "From Thinger Device Write": {
                  "value": {
                    "bucket": "device_write",
                    "config": {
                      "source": "write"
                    },
                    "description": "Bucket dor device write",
                    "enabled": true,
                    "name": "Device Write"
                  }
                },
                "High rate on InfluxDB": {
                  "value": {
                    "backend": "influxdb",
                    "bucket": "vibration",
                    "config": {
                      "device": "vibration_01",
                      "interval": 10,
                      "resource": "accel",
                      "source": "device",
                      "update": "interval"
                    },
                    "description": "Accelerometer read every 10 seconds",
                    "enabled": true,
                    "name": "Vibration",
                    "retention": {
                      "period": 30,
                      "unit": "days"
                    }
                  }
                },
                "Tagged writes, kept 2 years": {
                  "value": {
                    "bucket": "meter_readings",
                    "config": {
                      "source": "write",
                      "tags": [
                        "device",
                        "site"
                      ]
                    },
                    "description": "Readings written by every meter, tagged by device and site",
                    "enabled": true,
                    "name": "Meter readings",
                    "retention": {
                      "period": 2,
                      "unit": "years"
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "asset_group": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "asset_type": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "backend": {
                    "$ref": "#/components/schemas/bucket_backend"
                  },
                  "bucket": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "config": {
                    "$ref": "#/components/schemas/bucket_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "product": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "retention": {
                    "$ref": "#/components/schemas/bucket_retention"
                  }
                },
                "required": [
                  "bucket",
                  "name",
                  "config",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateBucket",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}": {
      "delete": {
        "operationId": "Bucket_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteBucket",
        "tags": [
          "Buckets"
        ]
      },
      "get": {
        "operationId": "Bucket_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "From API Call": {
                    "value": {
                      "bucket": "api_write",
                      "config": {
                        "source": "api"
                      },
                      "created": 1792263090784,
                      "description": "Bucket for API write",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "API Write"
                    }
                  },
                  "From MQTT Topic": {
                    "value": {
                      "bucket": "mqtt_bucket",
                      "config": {
                        "source": "mqtt",
                        "topic": "house/+/temperature"
                      },
                      "created": 1792263090784,
                      "description": "Bucket for MQTT topic",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "MQTT Bucket"
                    }
                  },
                  "From Thinger Device": {
                    "value": {
                      "bucket": "device_bucket",
                      "config": {
                        "device": "macbook",
                        "interval": 300,
                        "resource": "data",
                        "source": "device",
                        "update": "interval"
                      },
                      "created": 1792263090784,
                      "description": "Bucket for Thinger.io device",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "Device Bucket"
                    }
                  },
                  "From Thinger Device Write": {
                    "value": {
                      "bucket": "device_write",
                      "config": {
                        "source": "write"
                      },
                      "created": 1792263090784,
                      "description": "Bucket dor device write",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "Device Write"
                    }
                  },
                  "High rate on InfluxDB": {
                    "value": {
                      "backend": "influxdb",
                      "bucket": "vibration",
                      "config": {
                        "device": "vibration_01",
                        "interval": 10,
                        "resource": "accel",
                        "source": "device",
                        "update": "interval"
                      },
                      "created": 1792263090784,
                      "description": "Accelerometer read every 10 seconds",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "Vibration",
                      "retention": {
                        "period": 30,
                        "unit": "days"
                      }
                    }
                  },
                  "Tagged writes, kept 2 years": {
                    "value": {
                      "bucket": "meter_readings",
                      "config": {
                        "source": "write",
                        "tags": [
                          "device",
                          "site"
                        ]
                      },
                      "created": 1792263090784,
                      "description": "Readings written by every meter, tagged by device and site",
                      "enabled": true,
                      "modified": 1792263090784,
                      "name": "Meter readings",
                      "retention": {
                        "period": 2,
                        "unit": "years"
                      }
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadBucketConfig",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Bucket_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "bucket": "api_write",
                    "config": {
                      "source": "api"
                    },
                    "description": "Bucket for API write",
                    "enabled": true,
                    "name": "API Write"
                  }
                },
                "Update 'config'": {
                  "value": {
                    "config": {
                      "source": "api"
                    }
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Bucket for API write"
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "API Write"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "asset_group": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  },
                  "asset_type": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  },
                  "backend": {
                    "$ref": "#/components/schemas/bucket_backend"
                  },
                  "config": {
                    "$ref": "#/components/schemas/bucket_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "product": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  },
                  "retention": {
                    "$ref": "#/components/schemas/bucket_retention"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateBucket",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/clone": {
      "get": {
        "operationId": "Bucket_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneBucketConfig",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Bucket_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "bucket": "copy_of_bucket"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "bucket": "line_2_bucket",
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "bucket": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "bucket"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneBucket",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/data": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Bucket_WriteData",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "One record": {
                  "value": {
                    "device": "greenhouse_01",
                    "humidity": 51,
                    "temperature": 23.4
                  }
                },
                "With its own timestamp": {
                  "value": {
                    "energy": 1532.8,
                    "power": 2.1,
                    "ts": 1791650000000
                  }
                }
              },
              "schema": {
                "description": "The JSON object becomes one record. ?ts=<epoch ms> sets its timestamp (MongoDB buckets also take a numeric 'ts' field). Fields listed in the bucket tags are indexed for filtering. The bucket must be enabled."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "WriteBucket",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/exports": {
      "get": {
        "operationId": "Bucket_ListExports",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListBucketExports",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Bucket_CreateExport",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Everything as JSON, call an endpoint": {
                  "value": {
                    "callback": "endpoint",
                    "data_type": "json",
                    "endpoint": "export_ready",
                    "timestamp_format": "milliseconds"
                  }
                },
                "Last month as CSV, email when ready": {
                  "value": {
                    "callback": "email",
                    "data_type": "csv",
                    "max_ts": 1791590400000,
                    "min_ts": 1788998400000,
                    "timestamp_format": "iso"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Generates a file with the bucket data between min_ts and max_ts (epoch ms; all data when missing), listed in GET .../exports when ready. callback: notify by email to the owner or call an endpoint when it finishes.",
                "properties": {
                  "callback": {
                    "enum": [
                      "email",
                      "endpoint"
                    ],
                    "type": "string"
                  },
                  "data_type": {
                    "enum": [
                      "csv",
                      "arff",
                      "json"
                    ],
                    "type": "string"
                  },
                  "endpoint": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "max_ts": {
                    "minimum": 0,
                    "type": "number"
                  },
                  "min_ts": {
                    "minimum": 0,
                    "type": "number"
                  },
                  "timestamp_format": {
                    "enum": [
                      "iso",
                      "seconds",
                      "milliseconds"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateBucketExport",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/exports/{file}": {
      "delete": {
        "operationId": "Bucket_DeleteExport",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteBucketExport",
        "tags": [
          "Buckets"
        ]
      },
      "get": {
        "operationId": "Bucket_ReadExport",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadBucketExport",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/buckets/{bucket}/imports": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Bucket_CreateImport",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "CSV from a storage": {
                  "value": {
                    "file": "meter_readings_2025.csv",
                    "source": "storage",
                    "storage": "imports"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Loads records into the bucket from a file already uploaded to a file storage (CSV with a header row, as produced by an export).",
                "properties": {
                  "file": {
                    "type": "string"
                  },
                  "source": {
                    "enum": [
                      "storage"
                    ],
                    "type": "string"
                  },
                  "storage": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "source",
                  "storage",
                  "file"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateBucketImport",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Bucket_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateBucketProjects",
        "tags": [
          "Buckets"
        ]
      }
    },
    "/v1/users/{user}/buckets/{bucket}/tags": {
      "get": {
        "operationId": "Bucket_ListTags",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListBucketTags",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/buckets/{bucket}/tags/{tag}": {
      "get": {
        "operationId": "Bucket_ReadTag",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadBucketTag",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "tag",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/claims": {
      "get": {
        "operationId": "Claim_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "claim": "kit_0042",
                    "created": 1792263090794,
                    "description": "Gateway, sensor and dashboard shipped in box 0042",
                    "enabled": true,
                    "modified": 1792263090794,
                    "name": "Starter kit 0042"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListClaims",
        "tags": [
          "Claims"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Claim_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Starter kit": {
                  "value": {
                    "claim": "kit_0042",
                    "config": {
                      "max_claims": 1,
                      "members": [
                        "support"
                      ],
                      "members_roles": [
                        "viewer"
                      ],
                      "resources": [
                        {
                          "identifiers": [
                            "kit_0042_gw",
                            "kit_0042_sensor"
                          ],
                          "type": "device"
                        },
                        {
                          "identifiers": [
                            "kit_dashboard"
                          ],
                          "type": "dashboard"
                        }
                      ]
                    },
                    "description": "Gateway, sensor and dashboard shipped in box 0042",
                    "enabled": true,
                    "name": "Starter kit 0042"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "A claim lets another account take some of your resources into one of the projects you share with it: it opens the claim URL (or posts the code to /v1/claims), and the listed resources join that project; 'members' are added to it with 'members_roles' (global roles). 'max_claims' limits how many times the code works (0 = unlimited).",
                "properties": {
                  "claim": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "config": {
                    "$ref": "#/components/schemas/claim_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "claim",
                  "name",
                  "enabled",
                  "config"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateClaim",
        "tags": [
          "Claims"
        ]
      }
    },
    "/v1/users/{user}/claims/{claim}": {
      "delete": {
        "operationId": "Claim_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteClaim",
        "tags": [
          "Claims"
        ]
      },
      "get": {
        "operationId": "Claim_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Starter kit": {
                    "value": {
                      "claim": "kit_0042",
                      "config": {
                        "max_claims": 1,
                        "members": [
                          "support"
                        ],
                        "members_roles": [
                          "viewer"
                        ],
                        "resources": [
                          {
                            "identifiers": [
                              "kit_0042_gw",
                              "kit_0042_sensor"
                            ],
                            "type": "device"
                          },
                          {
                            "identifiers": [
                              "kit_dashboard"
                            ],
                            "type": "dashboard"
                          }
                        ]
                      },
                      "created": 1792263090794,
                      "description": "Gateway, sensor and dashboard shipped in box 0042",
                      "enabled": true,
                      "modified": 1792263090794,
                      "name": "Starter kit 0042"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadClaimConfig",
        "tags": [
          "Claims"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "claim",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Claim_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable the code": {
                  "value": {
                    "enabled": false
                  }
                },
                "Rename": {
                  "value": {
                    "name": "Starter kit 0042 - returned"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "config replaces the whole claim configuration.",
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/claim_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateClaim",
        "tags": [
          "Claims"
        ]
      }
    },
    "/v1/users/{user}/claims/{claim}/clone": {
      "get": {
        "operationId": "Claim_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneClaimConfig",
        "tags": [
          "Claims"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "claim",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Claim_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "claim": "copy_of_claim"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "claim": "line_2_claim",
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "claim": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "claim"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneClaim",
        "tags": [
          "Claims"
        ]
      }
    },
    "/v1/users/{user}/claims/{claim}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "claim",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Claim_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateClaimProjects",
        "tags": [
          "Claims"
        ]
      }
    },
    "/v1/users/{user}/dashboards": {
      "get": {
        "operationId": "Dashboard_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090743,
                    "dashboard": "plant_overview",
                    "description": "Production KPIs",
                    "modified": 1792263090743,
                    "name": "Plant overview"
                  },
                  {
                    "created": 1792263090743,
                    "dashboard": "fleet",
                    "description": "Device list and detail app",
                    "modified": 1792263090743,
                    "name": "Fleet",
                    "source": "url"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDashboards",
        "tags": [
          "Dashboards"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Dashboard_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Empty widget dashboard": {
                  "value": {
                    "dashboard": "plant_overview",
                    "description": "Production KPIs",
                    "name": "Plant overview",
                    "tabs": [
                      {
                        "icon": "fas fa-tachometer-alt",
                        "name": "Main",
                        "widgets": []
                      }
                    ]
                  }
                },
                "Url dashboard (SDK app)": {
                  "value": {
                    "dashboard": "fleet",
                    "description": "Device list and detail app",
                    "name": "Fleet",
                    "source": "url",
                    "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "source": {
                          "const": "url"
                        }
                      },
                      "required": [
                        "source"
                      ]
                    },
                    "then": {
                      "required": [
                        "url"
                      ]
                    }
                  }
                ],
                "description": "Widget dashboards are designed in the console editor (tabs with widgets). Url dashboards (source: url) render a web page, usually an app in a public file storage that is built with the dashboard SDK (npm package @thinger-io/dashboard-sdk). To show a dashboard on a device, product, asset type, group or project page, store the same object as its 'dashboard' property instead.",
                "properties": {
                  "controls": {},
                  "dashboard": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "description": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "functions": {},
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "placeholders": {},
                  "properties": {},
                  "source": {
                    "enum": [
                      "widgets",
                      "url"
                    ],
                    "type": "string"
                  },
                  "tabs": {
                    "items": {},
                    "type": "array"
                  },
                  "url": {
                    "maxLength": 1024,
                    "pattern": "^(/[^/\\\\]|https://)",
                    "type": "string"
                  },
                  "widgets": {
                    "items": {},
                    "type": "array"
                  }
                },
                "required": [
                  "dashboard",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateDashboard",
        "tags": [
          "Dashboards"
        ]
      }
    },
    "/v1/users/{user}/dashboards/{dashboard}": {
      "delete": {
        "operationId": "Dashboard_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDashboard",
        "tags": [
          "Dashboards"
        ]
      },
      "get": {
        "operationId": "Dashboard_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Empty widget dashboard": {
                    "value": {
                      "created": 1792263090743,
                      "dashboard": "plant_overview",
                      "description": "Production KPIs",
                      "modified": 1792263090743,
                      "name": "Plant overview",
                      "tabs": [
                        {
                          "icon": "fas fa-tachometer-alt",
                          "name": "Main",
                          "widgets": []
                        }
                      ]
                    }
                  },
                  "Url dashboard (SDK app)": {
                    "value": {
                      "created": 1792263090743,
                      "dashboard": "fleet",
                      "description": "Device list and detail app",
                      "modified": 1792263090743,
                      "name": "Fleet",
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDashboardConfig",
        "tags": [
          "Dashboards"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "dashboard",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Dashboard_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Point to another entry file": {
                  "value": {
                    "source": "url",
                    "url": "/v1/users/YOUR_USER/storages/fleet_app/files/device.html"
                  }
                },
                "Rename": {
                  "value": {
                    "description": "Production KPIs",
                    "name": "Plant overview (2026)"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "source": {
                          "const": "url"
                        }
                      },
                      "required": [
                        "source"
                      ]
                    },
                    "then": {
                      "required": [
                        "url"
                      ]
                    }
                  }
                ],
                "properties": {
                  "controls": {},
                  "description": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "functions": {},
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "placeholders": {},
                  "properties": {},
                  "source": {
                    "enum": [
                      "widgets",
                      "url"
                    ],
                    "type": "string"
                  },
                  "tabs": {
                    "items": {},
                    "type": "array"
                  },
                  "url": {
                    "maxLength": 1024,
                    "pattern": "^(/[^/\\\\]|https://)",
                    "type": "string"
                  },
                  "widgets": {
                    "items": {},
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDashboard",
        "tags": [
          "Dashboards"
        ]
      }
    },
    "/v1/users/{user}/dashboards/{dashboard}/clone": {
      "get": {
        "operationId": "Dashboard_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDashboardConfig",
        "tags": [
          "Dashboards"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "dashboard",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Dashboard_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "dashboard": "copy_of_dashboard"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "dashboard": "line_2_dashboard",
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "dashboard": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "dashboard"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDashboard",
        "tags": [
          "Dashboards"
        ]
      }
    },
    "/v1/users/{user}/dashboards/{dashboard}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "dashboard",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Dashboard_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDashboardProjects",
        "tags": [
          "Dashboards"
        ]
      }
    },
    "/v1/users/{user}/devices": {
      "get": {
        "operationId": "Device_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "created": 1792263090700,
                    "description": "HTTP Device",
                    "device": "http_device",
                    "enabled": true,
                    "modified": 1792263090700,
                    "name": "SN0300301",
                    "type": "HTTP"
                  },
                  {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "created": 1792263090700,
                    "description": "MQTT Device",
                    "device": "mqtt_device",
                    "enabled": true,
                    "modified": 1792263090700,
                    "name": "SN0300301",
                    "type": "MQTT"
                  },
                  {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "created": 1792263090700,
                    "description": "Thinger Device",
                    "device": "thinger_device",
                    "enabled": true,
                    "modified": 1792263090700,
                    "name": "SN0300301",
                    "type": "Generic"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDevices",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "HTTP Device": {
                  "value": {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "description": "HTTP Device",
                    "device": "http_device",
                    "enabled": true,
                    "name": "SN0300301",
                    "type": "HTTP"
                  }
                },
                "MQTT Device": {
                  "value": {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "credentials": "YOUR_TOKEN",
                    "description": "MQTT Device",
                    "device": "mqtt_device",
                    "enabled": true,
                    "name": "SN0300301",
                    "type": "MQTT"
                  }
                },
                "Thinger Device": {
                  "value": {
                    "asset_group": "AssetGroup",
                    "asset_type": "AssetType",
                    "credentials": "YOUR_TOKEN",
                    "description": "Thinger Device",
                    "device": "thinger_device",
                    "enabled": true,
                    "name": "SN0300301",
                    "type": "Generic"
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "asset_group": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "asset_type": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "connection": {
                        "additionalProperties": false,
                        "properties": {
                          "timeouts": {
                            "additionalProperties": false,
                            "properties": {
                              "disconnect": {
                                "minimum": 60,
                                "type": "integer"
                              },
                              "sleep": {
                                "minimum": 0,
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      },
                      "credentials": {
                        "maxLength": 255,
                        "minLength": 6,
                        "type": "string"
                      },
                      "description": {
                        "maxLength": 255,
                        "minLength": 0,
                        "type": "string"
                      },
                      "device": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "enabled": {
                        "type": "boolean"
                      },
                      "labels": {
                        "additionalProperties": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "propertyNames": {
                          "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,62}$"
                        },
                        "type": "object"
                      },
                      "name": {
                        "maxLength": 255,
                        "minLength": 0,
                        "type": "string"
                      },
                      "product": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "type": {
                        "enum": [
                          "Generic",
                          "MQTT"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "device",
                      "credentials"
                    ],
                    "type": "object"
                  },
                  {
                    "additionalProperties": false,
                    "properties": {
                      "asset_group": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "asset_type": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "description": {
                        "maxLength": 255,
                        "minLength": 1,
                        "type": "string"
                      },
                      "device": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "enabled": {
                        "type": "boolean"
                      },
                      "labels": {
                        "additionalProperties": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "propertyNames": {
                          "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,62}$"
                        },
                        "type": "object"
                      },
                      "name": {
                        "maxLength": 255,
                        "minLength": 0,
                        "type": "string"
                      },
                      "parent": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "product": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "protocol": {
                        "maxLength": 50,
                        "minLength": 1,
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "HTTP",
                          "Virtual",
                          "Subdevice"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "device"
                    ],
                    "type": "object"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateDevice",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/devices/{device}": {
      "delete": {
        "operationId": "Device_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDevice",
        "tags": [
          "Devices"
        ]
      },
      "get": {
        "operationId": "Device_ReadStatus",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceStatus",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Device_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Update Asset Group": {
                  "value": {
                    "asset_group": "Farm 1"
                  }
                },
                "Update Asset Type": {
                  "value": {
                    "asset_type": "Truck"
                  }
                },
                "Update Credentials": {
                  "value": {
                    "credentials": "YOUR_TOKEN"
                  }
                },
                "Update Description": {
                  "value": {
                    "description": "Updated Description"
                  }
                },
                "Update Enabled": {
                  "value": {
                    "enabled": false
                  }
                },
                "Update Labels": {
                  "value": {
                    "labels": {
                      "region": "europe",
                      "type": "small"
                    }
                  }
                },
                "Update Name": {
                  "value": {
                    "name": "SN0300301"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "asset_group": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  },
                  "asset_type": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  },
                  "connection": {
                    "additionalProperties": false,
                    "properties": {
                      "timeout": {
                        "minimum": 1,
                        "type": "integer"
                      },
                      "timeouts": {
                        "additionalProperties": false,
                        "properties": {
                          "disconnect": {
                            "minimum": 60,
                            "type": "integer"
                          },
                          "sleep": {
                            "minimum": 0,
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  },
                  "credentials": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "description": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "labels": {
                    "additionalProperties": {
                      "maxLength": 255,
                      "type": "string"
                    },
                    "propertyNames": {
                      "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,62}$"
                    },
                    "type": "object"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  },
                  "product": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      {
                        "maxLength": 0,
                        "type": "string"
                      }
                    ]
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDevice",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/devices/{device}/clone": {
      "get": {
        "operationId": "Device_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDeviceConfig",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "device": "copy_of_device"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "device": "line_2_device",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "device": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "device"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDevice",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/devices/{device}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Device_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDeviceProjects",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/devices/{device}/stats": {
      "get": {
        "deprecated": true,
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceStatistics",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/devices/{device}/tokens": {
      "get": {
        "operationId": "Device_ListTokens",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceTokens",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_CreateToken",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "All resources until a date": {
                  "value": {
                    "token_expiration": 1798761600,
                    "token_name": "Installer"
                  }
                },
                "Read two resources": {
                  "value": {
                    "token_name": "Display panel",
                    "token_resources": [
                      "temperature",
                      "humidity"
                    ]
                  }
                }
              },
              "schema": {
                "description": "A token limited to this device: it can only call the listed device resources (all of them when token_resources is missing). Useful to let a third party read or control one device.",
                "properties": {
                  "token_expiration": {
                    "description": "Unix timestamp when the token stops working.",
                    "type": "number"
                  },
                  "token_name": {
                    "type": "string"
                  },
                  "token_resources": {
                    "description": "Resource names the token can call.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "token_name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateDeviceToken",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/devices/{device}/tokens/{token}": {
      "delete": {
        "operationId": "Device_DeleteToken",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDeviceToken",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "token",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,50}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/devices/{device}/{resource}": {
      "get": {
        "deprecated": true,
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^(?:.{1,32}\\/?+)",
            "type": "string"
          }
        }
      ],
      "post": {
        "deprecated": true,
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v1/users/{user}/email": {
      "get": {
        "operationId": "User_ReadEmail",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserEmail",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/endpoints": {
      "get": {
        "operationId": "Endpoint_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090703,
                    "description": "Email Endpoint",
                    "enabled": true,
                    "endpoint": "email_endpoint",
                    "modified": 1792263090703,
                    "name": "Email",
                    "type": "email"
                  },
                  {
                    "created": 1792263090703,
                    "description": "HTTP Request",
                    "enabled": true,
                    "endpoint": "http_request",
                    "modified": 1792263090703,
                    "name": "HTTP",
                    "type": "http_request"
                  },
                  {
                    "created": 1792263090703,
                    "description": "HTTP request",
                    "enabled": true,
                    "endpoint": "http_request",
                    "modified": 1792263090703,
                    "name": "HTTP",
                    "type": "http_request"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListEndpoints",
        "tags": [
          "Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Endpoint_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Email": {
                  "description": "Creates an endpoint that sends an email when called. The calling data can be used in the body or the subject using placeholders like {{temperature}}.",
                  "value": {
                    "config": {
                      "body": "<p>The current temperature and humidity are: {{temperature}}, {{humidity}}</p>",
                      "body_type": "html",
                      "recipient": "user@example.com",
                      "reply_to": "user@example.com",
                      "subject": "Endpoint Testing"
                    },
                    "description": "Email Endpoint",
                    "enabled": true,
                    "endpoint": "email_endpoint",
                    "name": "Email",
                    "type": "email"
                  }
                },
                "HTTP Request": {
                  "description": "Creates an endpoint that resend the call JSON data to the target endpoint, both from api or device calls. The calling data can be used in the url or headers using placeholders like {{temperature}}.",
                  "value": {
                    "config": {
                      "body": "",
                      "body_type": "json",
                      "headers": [
                        {
                          "key": "Authorization",
                          "value": "Bearer xyz"
                        }
                      ],
                      "method": "POST",
                      "url": "https://api.acme.com/sensor"
                    },
                    "description": "HTTP Request",
                    "enabled": true,
                    "endpoint": "http_request",
                    "name": "HTTP",
                    "type": "http_request"
                  }
                },
                "HTTP Request Custom Body": {
                  "description": "Creates an endpoint that composes a new paylaod with the source variables passed to the call, both from api or device calls. The calling data can be used in the body, url, or headers using placeholders like {{temperature}}.",
                  "value": {
                    "config": {
                      "body": "{\n    \"val1\" : {{temperature}},\n    \"val2\": {{humidity}}\n}",
                      "body_type": "custom",
                      "headers": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "method": "POST",
                      "url": "https://api.acme.com/sensor"
                    },
                    "description": "HTTP request",
                    "enabled": true,
                    "endpoint": "http_request",
                    "name": "HTTP",
                    "type": "http_request"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "type": {
                          "not": {
                            "const": "virtual"
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    "then": {
                      "required": [
                        "config"
                      ]
                    }
                  }
                ],
                "description": "An endpoint is an outgoing action: type 'email', 'http_request' (webhooks, REST APIs), 'virtual' (no-op, for testing) or the id of an endpoint template (GET /v1/endpoints/templates lists them with their parameters; config is then {template, parameters}). Templates in config use {{payload}} (the data of the call) and its fields, e.g. {{payload.temperature}}. Called from the API (POST .../call), devices, product flows and alarm notifications.",
                "properties": {
                  "config": {
                    "description": "Settings of the endpoint type; not needed for 'virtual'.",
                    "type": "object"
                  },
                  "description": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "endpoint": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "type": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "endpoint",
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateEndpoint",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/users/{user}/endpoints/{endpoint}": {
      "delete": {
        "operationId": "Endpoint_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteEndpoint",
        "tags": [
          "Endpoints"
        ]
      },
      "get": {
        "operationId": "Endpoint_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Email": {
                    "description": "Creates an endpoint that sends an email when called. The calling data can be used in the body or the subject using placeholders like {{temperature}}.",
                    "value": {
                      "config": {
                        "body": "<p>The current temperature and humidity are: {{temperature}}, {{humidity}}</p>",
                        "body_type": "html",
                        "recipient": "user@example.com",
                        "reply_to": "user@example.com",
                        "subject": "Endpoint Testing"
                      },
                      "created": 1792263090703,
                      "description": "Email Endpoint",
                      "enabled": true,
                      "endpoint": "email_endpoint",
                      "modified": 1792263090703,
                      "name": "Email",
                      "type": "email"
                    }
                  },
                  "HTTP Request": {
                    "description": "Creates an endpoint that resend the call JSON data to the target endpoint, both from api or device calls. The calling data can be used in the url or headers using placeholders like {{temperature}}.",
                    "value": {
                      "config": {
                        "body": "",
                        "body_type": "json",
                        "headers": [
                          {
                            "key": "Authorization",
                            "value": "Bearer xyz"
                          }
                        ],
                        "method": "POST",
                        "url": "https://api.acme.com/sensor"
                      },
                      "created": 1792263090703,
                      "description": "HTTP Request",
                      "enabled": true,
                      "endpoint": "http_request",
                      "modified": 1792263090703,
                      "name": "HTTP",
                      "type": "http_request"
                    }
                  },
                  "HTTP Request Custom Body": {
                    "description": "Creates an endpoint that composes a new paylaod with the source variables passed to the call, both from api or device calls. The calling data can be used in the body, url, or headers using placeholders like {{temperature}}.",
                    "value": {
                      "config": {
                        "body": "{\n    \"val1\" : {{temperature}},\n    \"val2\": {{humidity}}\n}",
                        "body_type": "custom",
                        "headers": [
                          {
                            "key": "Content-Type",
                            "value": "application/json"
                          }
                        ],
                        "method": "POST",
                        "url": "https://api.acme.com/sensor"
                      },
                      "created": 1792263090703,
                      "description": "HTTP request",
                      "enabled": true,
                      "endpoint": "http_request",
                      "modified": 1792263090703,
                      "name": "HTTP",
                      "type": "http_request"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadEndpointConfig",
        "tags": [
          "Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "endpoint",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Endpoint_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "config": {
                      "body": "<p>The current temperature and humidity are: {{temperature}}, {{humidity}}</p>",
                      "body_type": "html",
                      "recipient": "user@example.com",
                      "reply_to": "user@example.com",
                      "subject": "Endpoint Testing"
                    },
                    "description": "Email Endpoint",
                    "enabled": true,
                    "endpoint": "email_endpoint",
                    "name": "Email",
                    "type": "email"
                  }
                },
                "Update 'config'": {
                  "value": {
                    "config": {
                      "body": "<p>The current temperature and humidity are: {{temperature}}, {{humidity}}</p>",
                      "body_type": "html",
                      "recipient": "user@example.com",
                      "reply_to": "user@example.com",
                      "subject": "Endpoint Testing"
                    }
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Email Endpoint"
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Email"
                  }
                },
                "Update 'type'": {
                  "value": {
                    "type": "email"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "type": "object"
                  },
                  "description": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "type": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateEndpoint",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/users/{user}/endpoints/{endpoint}/call": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "endpoint",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Endpoint_Call",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Alert payload": {
                  "value": {
                    "device": "greenhouse_01",
                    "message": "Temperature above 30",
                    "temperature": 31.2
                  }
                }
              },
              "schema": {
                "description": "Optional JSON payload, available to the endpoint templates as {{payload}} (e.g. the body of a webhook or the content of an email). The response is what the endpoint answered."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallEndpoint",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/users/{user}/endpoints/{endpoint}/clone": {
      "get": {
        "operationId": "Endpoint_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneEndpointConfig",
        "tags": [
          "Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "endpoint",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Endpoint_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "endpoint": "copy_of_endpoint"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "endpoint": "line_2_endpoint",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "endpoint": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "endpoint"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneEndpoint",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/users/{user}/endpoints/{endpoint}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "endpoint",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Endpoint_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateEndpointProjects",
        "tags": [
          "Endpoints"
        ]
      }
    },
    "/v1/users/{user}/events": {
      "get": {
        "deprecated": true,
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "SubscribeUserEvents",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/federated_identities/{identity_provider}": {
      "delete": {
        "operationId": "User_DeleteFederatedIdentity",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteUserFederatedIdentity",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "identity_provider",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/groups": {
      "get": {
        "operationId": "Group_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "group": "madrid_line_2",
                    "name": "Line 2",
                    "parent": "madrid_plant"
                  },
                  {
                    "description": "Devices installed in the Madrid plant",
                    "group": "madrid_plant",
                    "name": "Madrid plant"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListGroups",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Group_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Area inside a site": {
                  "value": {
                    "group": "madrid_line_2",
                    "name": "Line 2",
                    "parent": "madrid_plant"
                  }
                },
                "Site": {
                  "value": {
                    "description": "Devices installed in the Madrid plant",
                    "group": "madrid_plant",
                    "name": "Madrid plant"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "An asset group is where or whose a device is (a site, a customer, a building). Groups nest through 'parent'; devices join one with their asset_group field and inherit its properties. Project members can be limited to some groups.",
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "group": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "type": "string"
                  },
                  "parent": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "group"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateGroup",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}": {
      "delete": {
        "operationId": "Group_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteGroup",
        "tags": [
          "Groups"
        ]
      },
      "get": {
        "operationId": "Group_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Area inside a site": {
                    "value": {
                      "group": "madrid_line_2",
                      "name": "Line 2",
                      "parent": "madrid_plant"
                    }
                  },
                  "Site": {
                    "value": {
                      "description": "Devices installed in the Madrid plant",
                      "group": "madrid_plant",
                      "name": "Madrid plant"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadGroupConfig",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Group_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Rename": {
                  "value": {
                    "description": "North building",
                    "name": "Madrid plant - north"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateGroup",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}/clone": {
      "get": {
        "operationId": "Group_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneGroupConfig",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Group_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "group": "copy_of_group"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "group": "line_2_group",
                    "name": "Line 2 copy"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "group": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "required": [
                  "group"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneGroup",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}/locations": {
      "get": {
        "operationId": "Group_ReadAssetsLocations",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAssetsLocations",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/groups/{group}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Group_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateGroupProjects",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}/properties": {
      "get": {
        "operationId": "Group_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090708,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090708,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090708,
                    "modified": 1792263090708,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090708,
                    "modified": 1792263090708,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090708,
                    "modified": 1792263090708,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListGroupProperties",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Group_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateGroupProperty",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}/properties/{property}": {
      "delete": {
        "operationId": "Group_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteGroupProperty",
        "tags": [
          "Groups"
        ]
      },
      "get": {
        "operationId": "Group_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadGroupProperty",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Group_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateGroupProperty",
        "tags": [
          "Groups"
        ]
      },
      "put": {
        "operationId": "Group_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateGroupProperty",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/groups/{group}/properties/{property}/clone": {
      "get": {
        "operationId": "Group_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneGroupPropertyConfig",
        "tags": [
          "Groups"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "group",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Group_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneGroupProperty",
        "tags": [
          "Groups"
        ]
      }
    },
    "/v1/users/{user}/info/device_locations": {
      "get": {
        "operationId": "User_ListDeviceLocationsDevice_location",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceLocations",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/info/devices/locations": {
      "get": {
        "operationId": "User_ListDeviceLocations",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceLocations",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/info/devices/stats": {
      "get": {
        "operationId": "Device_ReadDevicesStatistics",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceStatistics",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/limits": {
      "get": {
        "operationId": "User_ReadLimits",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserLimits",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/limits/{resource}": {
      "get": {
        "operationId": "User_ReadResourceLimits",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserLimits",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/membership/{project_owner}/{project_id}/permissions": {
      "get": {
        "operationId": "User_ReadProjectPermissions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProjectPermissions",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project_owner",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project_id",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/mfa": {
      "get": {
        "operationId": "User_ReadMFAMfa",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserMFA",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/mfa/totp": {
      "delete": {
        "operationId": "User_DeleteTOTPTotp",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteUserTOTP",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/mfa/totp/backup-codes": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_CreateTOTPBackupCodesBackup-code",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateUserTOTPBackupCodes",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/mfa/totp/setup": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_SetupTOTP",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "SetupUserTOTP",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/mfa/totp/verify": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_VerifyTOTP",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "VerifyUserTOTP",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/mfa/webauthn/credentials/{credential}": {
      "delete": {
        "operationId": "User_DeleteWebAuthnCredential",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteWebAuthnCredential",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "credential",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_=-]{1,512}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_UpdateWebAuthnCredential",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateWebAuthnCredential",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/mfa/webauthn/register/options": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_WebAuthnRegisterOptions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "WebAuthnRegisterOptions",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/mfa/webauthn/register/verify": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_WebAuthnRegisterVerify",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "WebAuthnRegisterVerify",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/oauth/authorize": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_AuthorizeOauth",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "login_hint": {
                    "type": "string"
                  },
                  "nonce": {
                    "type": "string"
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string"
                  },
                  "response_mode": {
                    "type": "string"
                  },
                  "response_type": {
                    "enum": [
                      "code"
                    ]
                  },
                  "scope": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "ui_locales": {
                    "type": "string"
                  }
                },
                "required": [
                  "client_id",
                  "response_type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AuthorizeOauth",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/passkeys": {
      "get": {
        "operationId": "User_ReadPasskeys",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserPasskeys",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/passkeys/register/options": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_PasskeyRegisterOptions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "PasskeyRegisterOptions",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/passkeys/register/verify": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "User_PasskeyRegisterVerify",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "PasskeyRegisterVerify",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/passkeys/{credential}": {
      "delete": {
        "operationId": "User_DeletePasskey",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteUserPasskey",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "credential",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_=-]{1,512}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_UpdatePasskey",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateUserPasskey",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/password": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_UpdatePassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateUserPassword",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/plugins": {
      "get": {
        "operationId": "Plugin_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListPlugins",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/plugins/{plugin}": {
      "get": {
        "operationId": "Plugin_ReadInfo",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadPluginInfo",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Plugin_ManageState",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ManagePluginState",
        "tags": [
          "Plugins"
        ]
      }
    },
    "/v1/users/{user}/plugins/{plugin}/files/{file}": {
      "get": {
        "operationId": "Plugin_ReadFiles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadPluginFiles",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/plugins/{plugin}/properties": {
      "get": {
        "operationId": "Plugin_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090796,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090796,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090796,
                    "modified": 1792263090796,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090796,
                    "modified": 1792263090796,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090796,
                    "modified": 1792263090796,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListPluginProperties",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Plugin_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreatePluginProperty",
        "tags": [
          "Plugins"
        ]
      }
    },
    "/v1/users/{user}/plugins/{plugin}/properties/{property}": {
      "delete": {
        "operationId": "Plugin_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeletePluginProperty",
        "tags": [
          "Plugins"
        ]
      },
      "get": {
        "operationId": "Plugin_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadPluginProperty",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Plugin_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdatePluginProperty",
        "tags": [
          "Plugins"
        ]
      },
      "put": {
        "operationId": "Plugin_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdatePluginProperty",
        "tags": [
          "Plugins"
        ]
      }
    },
    "/v1/users/{user}/plugins/{plugin}/properties/{property}/clone": {
      "get": {
        "operationId": "Plugin_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ClonePluginPropertyConfig",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Plugin_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ClonePluginProperty",
        "tags": [
          "Plugins"
        ]
      }
    },
    "/v1/users/{user}/plugins/{plugin}/terminal": {
      "get": {
        "operationId": "Plugin_RunCommandTerminal",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RunPluginCommand",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/plugins/{plugin}/terminal/logs": {
      "get": {
        "operationId": "Plugin_ReadLogs",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadPluginLogs",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/plugins/{plugin}/terminal/shell": {
      "get": {
        "operationId": "Plugin_RunShell",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RunPluginShell",
        "tags": [
          "Plugins"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "plugin",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_\\-\\:]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products": {
      "get": {
        "operationId": "Product_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProducts",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Product_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/product_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "product": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "profile": {
                    "type": "object"
                  },
                  "services": {
                    "type": "object"
                  }
                },
                "required": [
                  "product",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProduct",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}": {
      "delete": {
        "operationId": "Product_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProduct",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "operationId": "Product_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductConfig",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Product_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/product_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProduct",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/clone": {
      "get": {
        "operationId": "Product_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProductConfig",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Product_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "product": "copy_of_product"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "product": "line_2_product"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "product": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "product"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProduct",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/export": {
      "get": {
        "operationId": "Product_Export",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ExportProduct",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/firmwares": {
      "get": {
        "operationId": "Product_ListFirmwares",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProductFirmwares",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Product_CreateFirmware",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "firmware": {
                    "pattern": "^[a-zA-Z0-9_]{1,25}$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "version": {
                    "pattern": "(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?",
                    "type": "string"
                  }
                },
                "required": [
                  "firmware",
                  "version"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProductFirmware",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/firmwares/{firmware}/{firmware_version}": {
      "delete": {
        "operationId": "Product_DeleteFirmware",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProductFirmware",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "operationId": "Product_ReadFirmwareConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductFirmwareConfig",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware_version",
          "required": true,
          "schema": {
            "pattern": "^(?:0|[1-9]\\d*\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?)",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Product_UpdateFirmware",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductFirmware",
        "tags": [
          "Products"
        ],
        "x-internal": true
      }
    },
    "/v1/users/{user}/products/{product}/firmwares/{firmware}/{firmware_version}/flash": {
      "get": {
        "operationId": "Product_FlashFirmware",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "FlashProductFirmware",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware_version",
          "required": true,
          "schema": {
            "pattern": "^(?:0|[1-9]\\d*\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?)",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/firmwares/{firmware}/{firmware_version}/stream": {
      "get": {
        "operationId": "Product_UpdateFirmwareStream",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductFirmware",
        "tags": [
          "Products"
        ],
        "x-internal": true
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware_version",
          "required": true,
          "schema": {
            "pattern": "^(?:0|[1-9]\\d*\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?)",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/firmwares/{firmware}/{firmware_version}/toolchain": {
      "get": {
        "operationId": "Product_UpdateFirmwareToolchain",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductFirmware",
        "tags": [
          "Products"
        ],
        "x-internal": true
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "firmware_version",
          "required": true,
          "schema": {
            "pattern": "^(?:0|[1-9]\\d*\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?)",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/profile/code": {
      "get": {
        "operationId": "Product_ReadProfileCode",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductProfile",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Product_UpdateProfileCode",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Code from a file storage": {
                  "value": {
                    "storage": "meter_product_code"
                  }
                },
                "Code from a folder of an application storage": {
                  "value": {
                    "path": "code/meter",
                    "storage": "fleet_app"
                  }
                },
                "Inline code": {
                  "value": {
                    "code": "function resolveDevice(payload) {\n  // device id from the serial sent by the caller\n  return 'meter_' + payload.serial;\n}\n\nfunction toCelsius(payload) {\n  return { temperature: (payload.temperature_f - 32) * 5 / 9 };\n}\n"
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/product_profile_code"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProfile",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/profile/console": {
      "get": {
        "operationId": "Product_ReadProfileConsole",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductProfile",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/profile/{category}": {
      "get": {
        "operationId": "Product_ReadProfile",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductProfile",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "category",
          "required": true,
          "schema": {
            "pattern": "^properties|buckets|flows|endpoints|api|autoprovisions",
            "type": "string"
          }
        }
      ],
      "put": {
        "description": "Replace every entry of a profile category. Entries missing from the body are removed; to change one entry use PUT .../profile/{category}/{resource}.",
        "operationId": "Product_UpdateProfile",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "All buckets of the product, one of them per device (PUT …/profile/buckets)": {
                  "value": {
                    "telemetry": {
                      "data": {
                        "interval": 60,
                        "magnitude": "second",
                        "payload_type": "source_payload",
                        "resource": "telemetry",
                        "source": "resource",
                        "update": "interval"
                      },
                      "description": "One shared bucket, tagged with each device",
                      "enabled": true,
                      "name": "Telemetry",
                      "retention": {
                        "period": 6,
                        "unit": "months"
                      }
                    },
                    "{{device}}_readings": {
                      "data": {
                        "payload_type": "source_payload",
                        "source": "topic",
                        "topic": "plant/{{line}}/{{device}}/{{field}}"
                      },
                      "enabled": true,
                      "name": "Readings",
                      "tags": [
                        "line"
                      ]
                    }
                  }
                },
                "Remove every flow (PUT …/profile/flows)": {
                  "value": {}
                }
              },
              "schema": {
                "$ref": "#/components/schemas/product_profile_category"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProfile",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/profile/{category}/{resource}": {
      "delete": {
        "operationId": "Product_DeleteProductProfileResource",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProfile",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "operationId": "Product_ReadProductProfileResource",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductProfile",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "category",
          "required": true,
          "schema": {
            "pattern": "^properties|buckets|flows|endpoints|api|autoprovisions",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "description": "Create or replace one entry of a profile category (properties, buckets, flows, api, autoprovisions; endpoints is deprecated). The product is reinitialized, so the change applies at once to its devices.",
        "operationId": "Product_UpdateProductProfileResource",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "API resource that calls an endpoint (PUT …/profile/api/notify)": {
                  "value": {
                    "description": "Sends a notification from the device",
                    "enabled": true,
                    "name": "Notify",
                    "request": {
                      "data": {
                        "endpoint": "notify_email",
                        "payload": "{\"device\": \"{{device}}\", \"message\": \"{{payload.message}}\"}",
                        "payload_type": "template_payload",
                        "target": "endpoint_call"
                      }
                    },
                    "response": {
                      "data": {
                        "source": "request_response"
                      }
                    }
                  }
                },
                "API resource to configure a device by serial, with device_id_resolver (PUT …/profile/api/configure)": {
                  "value": {
                    "device_id_resolver": "resolveDevice",
                    "enabled": true,
                    "name": "Configure",
                    "request": {
                      "data": {
                        "payload": "{{payload.settings}}",
                        "property": "settings",
                        "target": "property"
                      }
                    },
                    "response": {
                      "data": {
                        "source": "request_response"
                      }
                    }
                  }
                },
                "Autoprovision devices by id pattern (PUT …/profile/autoprovisions/meters)": {
                  "value": {
                    "config": {
                      "group": "plant_a",
                      "mode": "pattern",
                      "pattern": "^meter_[0-9]{6}$",
                      "type": "meter"
                    },
                    "description": "Creates meter_XXXXXX devices on their first connection",
                    "enabled": true,
                    "name": "Meters"
                  }
                },
                "Bucket fed from a device resource every 60 s (PUT …/profile/buckets/telemetry)": {
                  "value": {
                    "data": {
                      "interval": 60,
                      "magnitude": "second",
                      "payload_type": "source_payload",
                      "resource": "telemetry",
                      "source": "resource",
                      "update": "interval"
                    },
                    "description": "One shared bucket, tagged with each device",
                    "enabled": true,
                    "name": "Telemetry",
                    "retention": {
                      "period": 6,
                      "unit": "months"
                    }
                  }
                },
                "Bucket from MQTT topics with tags (PUT …/profile/buckets/readings)": {
                  "value": {
                    "data": {
                      "payload_type": "source_payload",
                      "source": "topic",
                      "topic": "plant/{{line}}/{{device}}/{{field}}"
                    },
                    "enabled": true,
                    "name": "Readings",
                    "tags": [
                      "line"
                    ]
                  }
                },
                "Configuration property with a default (PUT …/profile/properties/settings)": {
                  "value": {
                    "default": {
                      "value": {
                        "report_interval": 60,
                        "threshold": 25.5
                      }
                    },
                    "enabled": true,
                    "name": "Settings",
                    "perm": {
                      "hidden": [],
                      "readOnly": [
                        "member"
                      ]
                    },
                    "type": "configuration"
                  }
                },
                "Flow: email when a device disconnects (PUT …/profile/flows/offline_alert)": {
                  "value": {
                    "data": {
                      "event": "device_state_change",
                      "filter": {
                        "state": "disconnected"
                      },
                      "payload_type": "source_event",
                      "source": "event"
                    },
                    "enabled": true,
                    "name": "Offline alert",
                    "sink": {
                      "endpoint": "notify_email",
                      "payload": "{\"text\": \"{{device}} is offline\"}",
                      "target": "endpoint_call"
                    }
                  }
                },
                "Property set from an MQTT topic (PUT …/profile/properties/status)": {
                  "value": {
                    "data": {
                      "payload_type": "source_payload",
                      "source": "topic",
                      "topic": "devices/{{device}}/status"
                    },
                    "default": {
                      "value": {
                        "state": "unknown"
                      }
                    },
                    "description": "Last status message",
                    "enabled": true,
                    "name": "Status"
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/product_profile_entry"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProfile",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Product_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProjects",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/properties": {
      "get": {
        "operationId": "Product_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090737,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090737,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090737,
                    "modified": 1792263090737,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090737,
                    "modified": 1792263090737,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090737,
                    "modified": 1792263090737,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProductProperties",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Product_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProductProperty",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/properties/{property}": {
      "delete": {
        "operationId": "Product_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProductProperty",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "operationId": "Product_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductProperty",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Product_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProperty",
        "tags": [
          "Products"
        ]
      },
      "put": {
        "operationId": "Product_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductProperty",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/properties/{property}/clone": {
      "get": {
        "operationId": "Product_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProductPropertyConfig",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Product_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProductProperty",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/resources/{resource}": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^(?:.{1,32}\\/?+)",
            "type": "string"
          }
        }
      ],
      "post": {
        "description": "Call an API resource of the product (profile api) without naming a device. The body is free (any JSON, or an array to call it once per element) and is the {{payload}} of the resource. A device is only reached when the resource defines device_id_resolver, a product code function that returns the device id from the payload.",
        "operationId": "Product_AccessResources",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessProductResources",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/products/{product}/services": {
      "get": {
        "operationId": "Product_ReadServices",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductServices",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/products/{product}/services/{service}": {
      "delete": {
        "operationId": "Product_DeleteServices",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProductServices",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "operationId": "Product_ReadServices",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProductServices",
        "tags": [
          "Products"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "product",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "service",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Product_UpdateServices",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Remote desktop (PUT …/services/desktop)": {
                  "value": {
                    "enabled": true,
                    "name": "Desktop",
                    "target": {
                      "address": "127.0.0.1",
                      "port": 5900
                    },
                    "type": "vnc",
                    "vnc": {
                      "compression": 2,
                      "quality": 6,
                      "scale": true,
                      "shared": true,
                      "viewonly": false
                    }
                  }
                },
                "Web interface of the device (PUT …/services/web_ui)": {
                  "value": {
                    "description": "Device configuration page",
                    "enabled": true,
                    "name": "Web UI",
                    "security": {
                      "ip_filtering": false,
                      "timeout_minutes": 60
                    },
                    "target": {
                      "address": "127.0.0.1",
                      "port": 8080,
                      "secure": false
                    },
                    "type": "web"
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/product_service"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProductServices",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/users/{user}/profile": {
      "get": {
        "operationId": "User_ReadProfile",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserProfile",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_UpdateProfile",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Public profile": {
                  "value": {
                    "company": "Acme Farms",
                    "location": "Madrid, Spain",
                    "name": "Jane Doe",
                    "url": "https://acme.example"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "company": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  },
                  "location": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  },
                  "picture": {
                    "maxLength": 50000,
                    "pattern": "^$|^data:image/(?:png|jpeg|webp);base64,(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$",
                    "type": "string"
                  },
                  "url": {
                    "maxLength": 255,
                    "minLength": 0,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateUserProfile",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/projects": {
      "get": {
        "operationId": "Project_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090704,
                    "description": "Description",
                    "modified": 1792263090704,
                    "name": "Project",
                    "project": "project"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProjects",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Create Project": {
                  "description": "Creates a new project.",
                  "value": {
                    "description": "Description",
                    "name": "Project",
                    "project": "project"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "properties": {
                      "limit_bucket_access": {
                        "description": "Bucket reads made over the project only return the records of the project's devices (the bucket needs a device tag). Default true for new projects.",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "project": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "project",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProject",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}": {
      "delete": {
        "operationId": "Project_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProject",
        "tags": [
          "Projects"
        ]
      },
      "get": {
        "operationId": "Project_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Create Project": {
                    "description": "Creates a new project.",
                    "value": {
                      "created": 1792263090704,
                      "description": "Description",
                      "modified": 1792263090704,
                      "name": "Project",
                      "project": "project"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProjectConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Project_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "description": "Description",
                    "name": "Project",
                    "project": "project"
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Description"
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Project"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "properties": {
                      "limit_bucket_access": {
                        "description": "Bucket reads made over the project only return the records of the project's devices (the bucket needs a device tag). Default true for new projects.",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProject",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/clone": {
      "get": {
        "operationId": "Project_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProjectConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "project": "copy_of_project"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "project": "line_2_project"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "project": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "project"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProject",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/members": {
      "get": {
        "operationId": "Project_ListMembers",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090706,
                    "enabled": true,
                    "member": "jane",
                    "modified": 1792263090706
                  },
                  {
                    "created": 1792263090706,
                    "enabled": true,
                    "member": "tech_madrid",
                    "modified": 1792263090706
                  },
                  {
                    "created": 1792263090706,
                    "enabled": true,
                    "member": "acme_viewer",
                    "modified": 1792263090706
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProjectMembers",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_CreateMember",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Existing account with a role": {
                  "value": {
                    "enabled": true,
                    "member": "jane",
                    "roles": [
                      "operator"
                    ]
                  }
                },
                "Limited to a site": {
                  "value": {
                    "enabled": true,
                    "groups": [
                      "madrid_plant"
                    ],
                    "hide_menu": true,
                    "member": "tech_madrid",
                    "roles": [
                      "operator"
                    ]
                  }
                },
                "New account": {
                  "value": {
                    "account": {
                      "email": "viewer@acme.example",
                      "password": "a-long-random-password"
                    },
                    "enabled": true,
                    "member": "acme_viewer",
                    "roles": [
                      "viewer"
                    ]
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Shares the project with an account (member = its username). Effective permissions: its own allow / deny plus its project roles and global roles. 'groups' limits it to devices of those asset groups. With 'account' the server first creates that account (verified, role member, this project as default).",
                "properties": {
                  "account": {
                    "properties": {
                      "email": {
                        "format": "email",
                        "type": "string"
                      },
                      "password": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "global_roles": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "groups": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "hide_menu": {
                    "type": "boolean"
                  },
                  "member": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "roles": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  }
                },
                "required": [
                  "member",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProjectMember",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/members/{member}": {
      "delete": {
        "operationId": "Project_DeleteMember",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProjectMember",
        "tags": [
          "Projects"
        ]
      },
      "get": {
        "operationId": "Project_ReadMemberConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Existing account with a role": {
                    "value": {
                      "created": 1792263090706,
                      "enabled": true,
                      "member": "jane",
                      "modified": 1792263090706,
                      "roles": [
                        "operator"
                      ]
                    }
                  },
                  "Limited to a site": {
                    "value": {
                      "created": 1792263090706,
                      "enabled": true,
                      "groups": [
                        "madrid_plant"
                      ],
                      "hide_menu": true,
                      "member": "tech_madrid",
                      "modified": 1792263090706,
                      "roles": [
                        "operator"
                      ]
                    }
                  },
                  "New account": {
                    "value": {
                      "account": {
                        "email": "viewer@acme.example",
                        "password": "a-long-random-password"
                      },
                      "created": 1792263090706,
                      "enabled": true,
                      "member": "acme_viewer",
                      "modified": 1792263090706,
                      "roles": [
                        "viewer"
                      ]
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProjectMemberConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "member",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Project_UpdateMember",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change roles": {
                  "value": {
                    "roles": [
                      "viewer"
                    ]
                  }
                },
                "Suspend": {
                  "value": {
                    "enabled": false
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "global_roles": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "groups": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "hide_menu": {
                    "type": "boolean"
                  },
                  "roles": {
                    "items": {
                      "$ref": "#/components/schemas/resource_id"
                    },
                    "maxItems": 10,
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProjectMember",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/properties": {
      "get": {
        "operationId": "Project_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090705,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090705,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090705,
                    "modified": 1792263090705,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090705,
                    "modified": 1792263090705,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090705,
                    "modified": 1792263090705,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProjectProperties",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProjectProperty",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/properties/{property}": {
      "delete": {
        "operationId": "Project_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProjectProperty",
        "tags": [
          "Projects"
        ]
      },
      "get": {
        "operationId": "Project_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProjectProperty",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Project_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProjectProperty",
        "tags": [
          "Projects"
        ]
      },
      "put": {
        "operationId": "Project_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProjectProperty",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/properties/{property}/clone": {
      "get": {
        "operationId": "Project_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProjectPropertyConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProjectProperty",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/roles": {
      "get": {
        "operationId": "Project_ListRoles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "allow": {
                      "Alarm": {
                        "*": [
                          "List*",
                          "Read*",
                          "UpdateAlarmInstance"
                        ]
                      },
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*",
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "created": 1792263090706,
                    "enabled": true,
                    "modified": 1792263090706,
                    "role": "operator"
                  },
                  {
                    "allow": {
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    },
                    "created": 1792263090706,
                    "enabled": true,
                    "modified": 1792263090706,
                    "role": "viewer"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProjectRoles",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_CreateRole",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Operator": {
                  "value": {
                    "allow": {
                      "Alarm": {
                        "*": [
                          "List*",
                          "Read*",
                          "UpdateAlarmInstance"
                        ]
                      },
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*",
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "enabled": true,
                    "role": "operator"
                  }
                },
                "Viewer": {
                  "value": {
                    "allow": {
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    },
                    "enabled": true,
                    "role": "viewer"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "A project role is a named set of permissions for members of this project (members.roles). Permissions: {<resource type>: {<resource id or *>: action | [actions]}}; actions accept a trailing * (Read*, List*).",
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "role": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "role",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProjectRole",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/roles/{role}": {
      "delete": {
        "operationId": "Project_DeleteRole",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProjectRole",
        "tags": [
          "Projects"
        ]
      },
      "get": {
        "operationId": "Project_ReadRoleConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Operator": {
                    "value": {
                      "allow": {
                        "Alarm": {
                          "*": [
                            "List*",
                            "Read*",
                            "UpdateAlarmInstance"
                          ]
                        },
                        "Bucket": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Dashboard": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Device": {
                          "*": [
                            "List*",
                            "Read*",
                            "AccessDeviceResources"
                          ]
                        }
                      },
                      "created": 1792263090706,
                      "enabled": true,
                      "modified": 1792263090706,
                      "role": "operator"
                    }
                  },
                  "Viewer": {
                    "value": {
                      "allow": {
                        "Bucket": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Dashboard": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Device": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        }
                      },
                      "created": 1792263090706,
                      "enabled": true,
                      "modified": 1792263090706,
                      "role": "viewer"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProjectRoleConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "role",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Project_UpdateRole",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable the role": {
                  "value": {
                    "enabled": false
                  }
                },
                "Replace its permissions": {
                  "value": {
                    "allow": {
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProjectRole",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/projects/{project}/roles/{role}/clone": {
      "get": {
        "operationId": "Project_CloneRoleConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProjectRoleConfig",
        "tags": [
          "Projects"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "project",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "role",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Project_CloneRole",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "role": "copy_of_role"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "role": "line_2_role"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "role": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "role"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProjectRole",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/users/{user}/properties": {
      "get": {
        "operationId": "Property_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090745,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090745,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090745,
                    "modified": 1792263090745,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090745,
                    "modified": 1792263090745,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090745,
                    "modified": 1792263090745,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListProperties",
        "tags": [
          "Properties"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Property_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateProperty",
        "tags": [
          "Properties"
        ]
      }
    },
    "/v1/users/{user}/properties/{property}": {
      "delete": {
        "operationId": "Property_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteProperty",
        "tags": [
          "Properties"
        ]
      },
      "get": {
        "operationId": "Property_Read",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadProperty",
        "tags": [
          "Properties"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Property_Patch",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProperty",
        "tags": [
          "Properties"
        ]
      },
      "put": {
        "operationId": "Property_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateProperty",
        "tags": [
          "Properties"
        ]
      }
    },
    "/v1/users/{user}/properties/{property}/clone": {
      "get": {
        "operationId": "Property_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ClonePropertyConfig",
        "tags": [
          "Properties"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Property_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneProperty",
        "tags": [
          "Properties"
        ]
      }
    },
    "/v1/users/{user}/roles": {
      "get": {
        "operationId": "Role_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "allow": {
                      "Alarm": {
                        "*": [
                          "List*",
                          "Read*",
                          "UpdateAlarmInstance"
                        ]
                      },
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*",
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "created": 1792263090707,
                    "enabled": true,
                    "modified": 1792263090707,
                    "role": "operator"
                  },
                  {
                    "allow": {
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    },
                    "created": 1792263090707,
                    "enabled": true,
                    "modified": 1792263090707,
                    "role": "viewer"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListRoles",
        "tags": [
          "Roles"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Role_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Operator": {
                  "value": {
                    "allow": {
                      "Alarm": {
                        "*": [
                          "List*",
                          "Read*",
                          "UpdateAlarmInstance"
                        ]
                      },
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*",
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "enabled": true,
                    "role": "operator"
                  }
                },
                "Viewer": {
                  "value": {
                    "allow": {
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    },
                    "enabled": true,
                    "role": "viewer"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "A global role is a named set of permissions of the account, reusable by members of any of its projects (members.global_roles). Permissions: {<resource type>: {<resource id or *>: action | [actions]}}; actions accept a trailing * (Read*, List*).",
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "role": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "role",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateRole",
        "tags": [
          "Roles"
        ]
      }
    },
    "/v1/users/{user}/roles/{role}": {
      "delete": {
        "operationId": "Role_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteRole",
        "tags": [
          "Roles"
        ]
      },
      "get": {
        "operationId": "Role_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Operator": {
                    "value": {
                      "allow": {
                        "Alarm": {
                          "*": [
                            "List*",
                            "Read*",
                            "UpdateAlarmInstance"
                          ]
                        },
                        "Bucket": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Dashboard": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Device": {
                          "*": [
                            "List*",
                            "Read*",
                            "AccessDeviceResources"
                          ]
                        }
                      },
                      "created": 1792263090707,
                      "enabled": true,
                      "modified": 1792263090707,
                      "role": "operator"
                    }
                  },
                  "Viewer": {
                    "value": {
                      "allow": {
                        "Bucket": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Dashboard": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Device": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        }
                      },
                      "created": 1792263090707,
                      "enabled": true,
                      "modified": 1792263090707,
                      "role": "viewer"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadRoleConfig",
        "tags": [
          "Roles"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "role",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Role_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable the role": {
                  "value": {
                    "enabled": false
                  }
                },
                "Replace its permissions": {
                  "value": {
                    "allow": {
                      "Dashboard": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateRole",
        "tags": [
          "Roles"
        ]
      }
    },
    "/v1/users/{user}/roles/{role}/clone": {
      "get": {
        "operationId": "Role_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneRoleConfig",
        "tags": [
          "Roles"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "role",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Role_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "role": "copy_of_role"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "role": "line_2_role"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "role": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "role"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneRole",
        "tags": [
          "Roles"
        ]
      }
    },
    "/v1/users/{user}/stats": {
      "get": {
        "operationId": "User_ReadStatistics",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserStatistics",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/storages": {
      "get": {
        "operationId": "Storage_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090742,
                    "description": "Storages",
                    "index": "index.html",
                    "modified": 1792263090742,
                    "name": "File Storage",
                    "public": true,
                    "storage": "file_storage"
                  },
                  {
                    "created": 1792263090742,
                    "description": "Manuals and reports; only readable with a token",
                    "modified": 1792263090742,
                    "name": "Documents",
                    "public": false,
                    "storage": "documents"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListStorages",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Storage_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Create Storage": {
                  "description": "Creates a new file storage with public access. It can act as a web server and it is possible to serve a default file, i.e., index.html",
                  "value": {
                    "description": "Storages",
                    "index": "index.html",
                    "name": "File Storage",
                    "public": true,
                    "storage": "file_storage"
                  }
                },
                "Private storage": {
                  "value": {
                    "description": "Manuals and reports; only readable with a token",
                    "name": "Documents",
                    "public": false,
                    "storage": "documents"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "index": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "public": {
                    "type": "boolean"
                  },
                  "storage": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "terminal_image": {
                    "maxLength": 255,
                    "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._/-]*:[a-zA-Z0-9._-]+$",
                    "type": "string"
                  }
                },
                "required": [
                  "storage",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateStorage",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/storages/{storage}": {
      "delete": {
        "operationId": "Storage_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteStorage",
        "tags": [
          "Storages"
        ]
      },
      "get": {
        "operationId": "Storage_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Create Storage": {
                    "description": "Creates a new file storage with public access. It can act as a web server and it is possible to serve a default file, i.e., index.html",
                    "value": {
                      "created": 1792263090742,
                      "description": "Storages",
                      "index": "index.html",
                      "modified": 1792263090742,
                      "name": "File Storage",
                      "public": true,
                      "storage": "file_storage"
                    }
                  },
                  "Private storage": {
                    "value": {
                      "created": 1792263090742,
                      "description": "Manuals and reports; only readable with a token",
                      "modified": 1792263090742,
                      "name": "Documents",
                      "public": false,
                      "storage": "documents"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadStorageConfig",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Storage_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "description": "Storages",
                    "index": "index.html",
                    "name": "File Storage",
                    "public": true,
                    "storage": "file_storage"
                  }
                },
                "Update 'description'": {
                  "value": {
                    "description": "Storages"
                  }
                },
                "Update 'index'": {
                  "value": {
                    "index": "index.html"
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "File Storage"
                  }
                },
                "Update 'public'": {
                  "value": {
                    "public": true
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "index": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "public": {
                    "type": "boolean"
                  },
                  "terminal_image": {
                    "maxLength": 255,
                    "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._/-]*:[a-zA-Z0-9._-]+$",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateStorage",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/storages/{storage}/clone": {
      "get": {
        "operationId": "Storage_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneStorageConfig",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Storage_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "storage": "copy_of_storage"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "storage": "line_2_storage"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "storage": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "storage"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneStorage",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/storages/{storage}/files": {
      "get": {
        "operationId": "Storage_ListFiles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/storages/{storage}/files/{file}": {
      "delete": {
        "operationId": "Storage_DeleteFiles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "get": {
        "operationId": "Storage_ReadFiles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ],
      "put": {
        "description": "Creates or overwrites the file with the raw request body (any content type); folders on the path are created. For large or binary files prefer PUT /v2/users/{user}/storages/{storage}/files/{path}, which streams the upload.",
        "operationId": "Storage_UpdateFiles",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateStorageFiles",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/storages/{storage}/files{path}": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "path",
          "required": true,
          "schema": {
            "pattern": "^(?:\\/.+?)",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Storage_RenameFiles.+)?)",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Move into a folder": {
                  "value": {
                    "path": "archive/2025/report.csv"
                  }
                },
                "Rename a file": {
                  "value": {
                    "path": "docs/manual-v2.pdf"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Moves or renames the file or folder of the URL to 'path', inside the same storage.",
                "properties": {
                  "path": {
                    "maxLength": 255,
                    "type": "string"
                  }
                },
                "required": [
                  "path"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RenameStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "post": {
        "description": "Uploads files into the folder of the path: multipart/form-data with one or more files, or JSON {\"files\": [names], \"folders\": [names]} to create empty files and folders.",
        "operationId": "Storage_CreateFiles.+)?)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateStorageFiles",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/storages/{storage}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Storage_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateStorageProjects",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v1/users/{user}/syncs": {
      "get": {
        "operationId": "Sync_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090740,
                    "enabled": true,
                    "modified": 1792263090740,
                    "name": "Firmware uploads",
                    "sync": "firmware_uploads"
                  },
                  {
                    "created": 1792263090740,
                    "description": "Only one controller can dose at a time",
                    "enabled": true,
                    "modified": 1792263090740,
                    "name": "Dosing pump",
                    "sync": "dosing_pump"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListSyncs",
        "tags": [
          "Syncs"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Sync_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Limit concurrent uploads": {
                  "value": {
                    "config": {
                      "available": 5,
                      "timeout": 600
                    },
                    "enabled": true,
                    "name": "Firmware uploads",
                    "sync": "firmware_uploads"
                  }
                },
                "One device at a time": {
                  "value": {
                    "config": {
                      "available": 1,
                      "timeout": 120
                    },
                    "description": "Only one controller can dose at a time",
                    "enabled": true,
                    "name": "Dosing pump",
                    "sync": "dosing_pump"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "A sync is a shared semaphore: 'available' slots that devices or scripts take with locks (POST .../syncs/{sync}/locks) and release, e.g. to let only N devices use a resource at the same time. 'timeout' (seconds) is the default lock lifetime; 0 = until released.",
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/sync_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "sync": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "sync",
                  "name",
                  "enabled",
                  "config"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateSync",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/syncs/{sync}": {
      "delete": {
        "operationId": "Sync_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteSync",
        "tags": [
          "Syncs"
        ]
      },
      "get": {
        "operationId": "Sync_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Limit concurrent uploads": {
                    "value": {
                      "config": {
                        "available": 5,
                        "timeout": 600
                      },
                      "created": 1792263090740,
                      "enabled": true,
                      "modified": 1792263090740,
                      "name": "Firmware uploads",
                      "sync": "firmware_uploads"
                    }
                  },
                  "One device at a time": {
                    "value": {
                      "config": {
                        "available": 1,
                        "timeout": 120
                      },
                      "created": 1792263090740,
                      "description": "Only one controller can dose at a time",
                      "enabled": true,
                      "modified": 1792263090740,
                      "name": "Dosing pump",
                      "sync": "dosing_pump"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadSyncConfig",
        "tags": [
          "Syncs"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "sync",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Sync_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Disable": {
                  "value": {
                    "enabled": false
                  }
                },
                "More slots": {
                  "value": {
                    "config": {
                      "available": 10,
                      "timeout": 600
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/sync_config"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateSync",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/syncs/{sync}/clone": {
      "get": {
        "operationId": "Sync_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneSyncConfig",
        "tags": [
          "Syncs"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "sync",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Sync_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "sync": "copy_of_sync"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "sync": "line_2_sync"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "sync": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "sync"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneSync",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/syncs/{sync}/locks": {
      "get": {
        "operationId": "Sync_ListLocks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090741,
                    "lock": "pump_controller_1",
                    "modified": 1792263090741,
                    "name": "Controller 1"
                  },
                  {
                    "created": 1792263090741,
                    "lock": "bulk_job",
                    "modified": 1792263090741,
                    "slots": 2
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListSyncLocks",
        "tags": [
          "Syncs"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "sync",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Sync_CreateLock",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Take one slot": {
                  "value": {
                    "lock": "pump_controller_1",
                    "name": "Controller 1"
                  }
                },
                "Two slots for 60 seconds": {
                  "value": {
                    "lock": "bulk_job",
                    "slots": 2,
                    "timeout": 60
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "Takes 'slots' (default 1) of the sync. Fails when not enough slots are free. 'timeout' (seconds) overrides the sync default; without lock id a random one is assigned. Delete the lock to release it.",
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "lock": {
                    "$ref": "#/components/schemas/resource_id"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "slots": {
                    "type": "number"
                  },
                  "timeout": {
                    "type": "number"
                  }
                },
                "required": [],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateSyncLock",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/syncs/{sync}/locks/{lock}": {
      "delete": {
        "operationId": "Sync_DeleteLock",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteSyncLock",
        "tags": [
          "Syncs"
        ]
      },
      "get": {
        "operationId": "Sync_ReadLockConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Take one slot": {
                    "value": {
                      "created": 1792263090741,
                      "lock": "pump_controller_1",
                      "modified": 1792263090741,
                      "name": "Controller 1"
                    }
                  },
                  "Two slots for 60 seconds": {
                    "value": {
                      "created": 1792263090741,
                      "lock": "bulk_job",
                      "modified": 1792263090741,
                      "slots": 2,
                      "timeout": 60
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadSyncLockConfig",
        "tags": [
          "Syncs"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "sync",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "lock",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Sync_UpdateLock",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Rename": {
                  "value": {
                    "name": "Controller 1 - night shift"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateSyncLock",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/syncs/{sync}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "sync",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Sync_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateSyncProjects",
        "tags": [
          "Syncs"
        ]
      }
    },
    "/v1/users/{user}/timezone": {
      "get": {
        "operationId": "User_ReadTimezone",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadUserTimezone",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "User_UpdateTimezone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Madrid": {
                  "value": {
                    "timezone": "Europe/Madrid"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "timezone": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "timezone"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateUserTimezone",
        "tags": [
          "Users"
        ]
      }
    },
    "/v1/users/{user}/tokens": {
      "get": {
        "operationId": "Token_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090744,
                    "enabled": true,
                    "modified": 1792263090744,
                    "name": "Admin Access",
                    "token": "admin_access"
                  },
                  {
                    "created": 1792263090744,
                    "enabled": true,
                    "modified": 1792263090744,
                    "name": "Shared Access",
                    "token": "shared_access"
                  },
                  {
                    "created": 1792263090744,
                    "enabled": true,
                    "modified": 1792263090744,
                    "name": "Greenhouse 01",
                    "token": "greenhouse_01_access"
                  },
                  {
                    "created": 1792263090744,
                    "enabled": true,
                    "modified": 1792263090744,
                    "name": "Read-only dashboard",
                    "token": "readonly_dashboard"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListTokens",
        "tags": [
          "Tokens"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Token_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Admin Access": {
                  "description": "Creates a token with admin access. (For every resource, with any name, execute any action).",
                  "value": {
                    "allow": {
                      "*": {
                        "*": "*"
                      }
                    },
                    "enabled": true,
                    "name": "Admin Access",
                    "token": "admin_access"
                  }
                },
                "Custom Access": {
                  "description": "Creates a token with permissions for reading an specific bucket 'mqtt_bucket', and to access any device resource.",
                  "value": {
                    "allow": {
                      "Bucket": {
                        "mqtt_bucket": [
                          "ReadBucket"
                        ]
                      },
                      "Device": {
                        "*": [
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "enabled": true,
                    "name": "Shared Access",
                    "token": "shared_access"
                  }
                },
                "One device": {
                  "description": "Access to a single device and its data bucket. To scope a token to a project instead, create it with ?project=<project>: it then only works with that project.",
                  "value": {
                    "allow": {
                      "Bucket": {
                        "greenhouse_climate": [
                          "ReadBucket"
                        ]
                      },
                      "Device": {
                        "greenhouse_01": [
                          "Read*",
                          "AccessDeviceResources"
                        ]
                      }
                    },
                    "enabled": true,
                    "name": "Greenhouse 01",
                    "token": "greenhouse_01_access"
                  }
                },
                "Read-only devices and buckets": {
                  "description": "Lists and reads devices and bucket data, without changing anything (e.g. for an external dashboard).",
                  "value": {
                    "allow": {
                      "Bucket": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      },
                      "Device": {
                        "*": [
                          "List*",
                          "Read*"
                        ]
                      }
                    },
                    "enabled": true,
                    "name": "Read-only dashboard",
                    "token": "readonly_dashboard"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "expire": {
                    "description": "Expiration as a unix timestamp in milliseconds: the token stops working then, and is deleted shortly after. Without it the token does not expire. Set when the token is created; it cannot be changed later.",
                    "type": "number"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "token": {
                    "pattern": "^[a-zA-Z0-9_]{1,50}$",
                    "type": "string"
                  }
                },
                "required": [
                  "token",
                  "name",
                  "enabled"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateToken",
        "tags": [
          "Tokens"
        ]
      }
    },
    "/v1/users/{user}/tokens/{token}": {
      "delete": {
        "operationId": "Token_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteToken",
        "tags": [
          "Tokens"
        ]
      },
      "get": {
        "operationId": "Token_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Admin Access": {
                    "description": "Creates a token with admin access. (For every resource, with any name, execute any action).",
                    "value": {
                      "allow": {
                        "*": {
                          "*": "*"
                        }
                      },
                      "created": 1792263090744,
                      "enabled": true,
                      "modified": 1792263090744,
                      "name": "Admin Access",
                      "token": "admin_access"
                    }
                  },
                  "Custom Access": {
                    "description": "Creates a token with permissions for reading an specific bucket 'mqtt_bucket', and to access any device resource.",
                    "value": {
                      "allow": {
                        "Bucket": {
                          "mqtt_bucket": [
                            "ReadBucket"
                          ]
                        },
                        "Device": {
                          "*": [
                            "AccessDeviceResources"
                          ]
                        }
                      },
                      "created": 1792263090744,
                      "enabled": true,
                      "modified": 1792263090744,
                      "name": "Shared Access",
                      "token": "shared_access"
                    }
                  },
                  "One device": {
                    "description": "Access to a single device and its data bucket. To scope a token to a project instead, create it with ?project=<project>: it then only works with that project.",
                    "value": {
                      "allow": {
                        "Bucket": {
                          "greenhouse_climate": [
                            "ReadBucket"
                          ]
                        },
                        "Device": {
                          "greenhouse_01": [
                            "Read*",
                            "AccessDeviceResources"
                          ]
                        }
                      },
                      "created": 1792263090744,
                      "enabled": true,
                      "modified": 1792263090744,
                      "name": "Greenhouse 01",
                      "token": "greenhouse_01_access"
                    }
                  },
                  "Read-only devices and buckets": {
                    "description": "Lists and reads devices and bucket data, without changing anything (e.g. for an external dashboard).",
                    "value": {
                      "allow": {
                        "Bucket": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        },
                        "Device": {
                          "*": [
                            "List*",
                            "Read*"
                          ]
                        }
                      },
                      "created": 1792263090744,
                      "enabled": true,
                      "modified": 1792263090744,
                      "name": "Read-only dashboard",
                      "token": "readonly_dashboard"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadTokenConfig",
        "tags": [
          "Tokens"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "token",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,50}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Token_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Full Update": {
                  "value": {
                    "allow": {
                      "*": {
                        "*": "*"
                      }
                    },
                    "enabled": true,
                    "name": "Admin Access",
                    "token": "admin_access"
                  }
                },
                "Update 'allow'": {
                  "value": {
                    "allow": {
                      "*": {
                        "*": "*"
                      }
                    }
                  }
                },
                "Update 'enabled'": {
                  "value": {
                    "enabled": true
                  }
                },
                "Update 'name'": {
                  "value": {
                    "name": "Admin Access"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "allow": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "deny": {
                    "$ref": "#/components/schemas/permission"
                  },
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "expire": {
                    "description": "Cannot be changed: the expiration is signed into the token when it is created. Create a new token instead.",
                    "type": "number"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateToken",
        "tags": [
          "Tokens"
        ]
      }
    },
    "/v1/users/{user}/tokens/{token}/clone": {
      "get": {
        "operationId": "Token_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneTokenConfig",
        "tags": [
          "Tokens"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "token",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,50}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Token_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "token": "copy_of_token"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "token": "line_2_token"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "token": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "token"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneToken",
        "tags": [
          "Tokens"
        ]
      }
    },
    "/v1/users/{user}/tokens/{token}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "token",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,50}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Token_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateTokenProjects",
        "tags": [
          "Tokens"
        ]
      }
    },
    "/v1/users/{user}/types": {
      "get": {
        "operationId": "Type_List",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "description": "Gas boilers with remote control",
                    "name": "Boiler",
                    "type": "boiler"
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListTypes",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Type_Create",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Boiler": {
                  "value": {
                    "description": "Gas boilers with remote control",
                    "name": "Boiler",
                    "type": "boiler"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "An asset type is what a device is (boiler, meter, gateway). Devices join one with their asset_type field and inherit its properties.",
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateType",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}": {
      "delete": {
        "operationId": "Type_Delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteType",
        "tags": [
          "Types"
        ]
      },
      "get": {
        "operationId": "Type_ReadConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Boiler": {
                    "value": {
                      "description": "Gas boilers with remote control",
                      "name": "Boiler",
                      "type": "boiler"
                    }
                  }
                },
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadTypeConfig",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Type_Update",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Rename": {
                  "value": {
                    "description": "Condensing gas boilers",
                    "name": "Gas boiler"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateType",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}/clone": {
      "get": {
        "operationId": "Type_CloneConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneTypeConfig",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Type_Clone",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "type": "copy_of_type"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "type": "line_2_type"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "type": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneType",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}/locations": {
      "get": {
        "operationId": "Type_ReadAssetsLocations",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadAssetsLocations",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v1/users/{user}/types/{type}/projects": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Type_UpdateProjects",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "No projects": {
                  "value": []
                },
                "One project": {
                  "value": [
                    "YOUR_USER@greenhouse"
                  ]
                },
                "Two projects": {
                  "value": [
                    "YOUR_USER@greenhouse",
                    "YOUR_USER@maintenance"
                  ]
                }
              },
              "schema": {
                "description": "Projects the resource belongs to, as <owner>@<project> ids. Replaces the whole list: read the current one first to add or remove a single project; [] removes it from every project.",
                "items": {
                  "pattern": "^[a-zA-Z0-9_]{1,32}@[a-zA-Z0-9_]{1,32}$",
                  "type": "string"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateTypeProjects",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}/properties": {
      "get": {
        "operationId": "Type_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090710,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090710,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090710,
                    "modified": 1792263090710,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090710,
                    "modified": 1792263090710,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090710,
                    "modified": 1792263090710,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListTypeProperties",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Type_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateTypeProperty",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}/properties/{property}": {
      "delete": {
        "operationId": "Type_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteTypeProperty",
        "tags": [
          "Types"
        ]
      },
      "get": {
        "operationId": "Type_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadTypeProperty",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Type_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateTypeProperty",
        "tags": [
          "Types"
        ]
      },
      "put": {
        "operationId": "Type_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateTypeProperty",
        "tags": [
          "Types"
        ]
      }
    },
    "/v1/users/{user}/types/{type}/properties/{property}/clone": {
      "get": {
        "operationId": "Type_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneTypePropertyConfig",
        "tags": [
          "Types"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "type",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Type_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneTypeProperty",
        "tags": [
          "Types"
        ]
      }
    },
    "/v2/users/{user}/devices/{device}/{resource}": {
      "get": {
        "deprecated": true,
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^(?:.{1,32}\\/?+)",
            "type": "string"
          }
        }
      ],
      "post": {
        "deprecated": true,
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v2/users/{user}/events": {
      "get": {
        "operationId": "User_SubscribeEvents",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "SubscribeUserEvents",
        "tags": [
          "Users"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v2/users/{user}/storages/{storage}/files{file}": {
      "delete": {
        "operationId": "Storage_DeleteFilesFiles(?<file>.*$)",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "get": {
        "operationId": "Storage_ReadFilesFiles(?<file>.*$)",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Storage_RenameFilesFiles(?<file>.*$)",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Rename a file": {
                  "value": {
                    "path": "/docs/manual-v2.pdf"
                  }
                }
              },
              "schema": {
                "description": "Moves or renames the file or folder of the URL to 'path', inside the same storage.",
                "properties": {
                  "path": {
                    "type": "string"
                  }
                },
                "required": [
                  "path"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RenameStorageFiles",
        "tags": [
          "Storages"
        ]
      },
      "put": {
        "description": "Streams the raw request body (any content type, e.g. application/octet-stream) into the file; folders are created. A path ending in / creates a folder (empty body). ?overwrite=false fails if it exists.",
        "operationId": "Storage_UpdateFilesFiles(?<file>.*$)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateStorageFiles",
        "tags": [
          "Storages"
        ]
      }
    },
    "/v2/users/{user}/storages/{storage}/terminal": {
      "get": {
        "operationId": "Storage_AccessTerminal",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessStorageTerminal",
        "tags": [
          "Storages"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "storage",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/buckets": {
      "get": {
        "operationId": "Device_ListBuckets",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceBuckets",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/buckets/{bucket}/tags": {
      "get": {
        "operationId": "Device_ListBucketTags",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceBucketTags",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/buckets/{bucket}/tags/{tag}": {
      "get": {
        "operationId": "Device_ReadBucketTag",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceBucketTag",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "tag",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/callback": {
      "get": {
        "operationId": "Device_ReadCallbackConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceCallbackConfig",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "put": {
        "operationId": "Device_UpdateCallback",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Store the data in a bucket": {
                  "value": {
                    "actions": {
                      "write_bucket": "meter_readings"
                    },
                    "properties": {
                      "timeout": 10
                    }
                  }
                },
                "Store, notify and reply with a property": {
                  "value": {
                    "actions": {
                      "call_endpoint": "readings_webhook",
                      "send_property": "settings",
                      "write_bucket": "meter_readings"
                    }
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "description": "What the server does with the JSON an HTTP device posts to its callback (POST /v3/users/{user}/devices/{device}/callback/data): write_bucket stores it in a bucket, call_endpoint forwards it to an endpoint, set_property saves it as a device property, send_property returns a property as the response (e.g. its configuration). properties.timeout: minutes without data before the device is shown as disconnected.",
                "properties": {
                  "actions": {
                    "additionalProperties": false,
                    "properties": {
                      "call_endpoint": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "send_property": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "set_property": {
                        "$ref": "#/components/schemas/resource_id"
                      },
                      "write_bucket": {
                        "$ref": "#/components/schemas/resource_id"
                      }
                    },
                    "type": "object"
                  },
                  "properties": {
                    "additionalProperties": false,
                    "properties": {
                      "timeout": {
                        "type": "integer"
                      }
                    },
                    "type": "object"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDeviceCallback",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/callback/data": {
      "get": {
        "operationId": "Device_ReadCallbackResponseData",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceCallbackResponse",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_CallCallbackData",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Meter reading": {
                  "value": {
                    "energy": 1532.8,
                    "power": 2.1,
                    "voltage": 229.7
                  }
                }
              },
              "schema": {
                "description": "Data an HTTP device sends: any JSON. The device callback settings (PUT .../callback) decide what happens with it (bucket, endpoint, property, response). ?ts=<epoch ms> sets the timestamp."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CallDeviceCallback",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/files{file}": {
      "delete": {
        "operationId": "Device_DeleteFilesFiles(?<file>.*$)",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDeviceFiles",
        "tags": [
          "Devices"
        ]
      },
      "get": {
        "operationId": "Device_ReadFilesFiles(?<file>.*$)",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceFiles",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "file",
          "required": true,
          "schema": {
            "pattern": "^.*$",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Device_RenameFilesFiles(?<file>.*$)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "RenameDeviceFiles",
        "tags": [
          "Devices"
        ]
      },
      "put": {
        "operationId": "Device_UpdateFilesFiles(?<file>.*$)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDeviceFiles",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/properties": {
      "get": {
        "operationId": "Device_ListProperties",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": [
                  {
                    "created": 1792263090701,
                    "description": "Sampling and alert thresholds",
                    "modified": 1792263090701,
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  },
                  {
                    "created": 1792263090701,
                    "modified": 1792263090701,
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  },
                  {
                    "created": 1792263090701,
                    "modified": 1792263090701,
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  },
                  {
                    "created": 1792263090701,
                    "modified": 1792263090701,
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                ],
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceProperties",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_CreateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Configuration value": {
                  "value": {
                    "description": "Sampling and alert thresholds",
                    "name": "Settings",
                    "property": "settings",
                    "type": "configuration",
                    "value": {
                      "alerts": true,
                      "interval": 60,
                      "max_temperature": 28.5
                    }
                  }
                },
                "Location": {
                  "value": {
                    "name": "Location",
                    "property": "location",
                    "value": {
                      "lat": 40.4168,
                      "lon": -3.7038
                    }
                  }
                },
                "Read-only for project members": {
                  "value": {
                    "name": "Calibration",
                    "perm": {
                      "readOnly": [
                        "member"
                      ]
                    },
                    "property": "calibration",
                    "value": {
                      "gain": 1.02,
                      "offset": -0.4
                    }
                  }
                },
                "Url dashboard of the resource": {
                  "value": {
                    "name": "Dashboard",
                    "property": "dashboard",
                    "value": {
                      "source": "url",
                      "url": "/v1/users/YOUR_USER/storages/fleet_app/files/"
                    }
                  }
                }
              },
              "schema": {
                "description": "A property is a JSON value stored on its resource (device, asset type, asset group, project, product, plugin or account). Devices inherit the properties of their asset type, asset group and product. 'type: configuration' marks values the device reads; 'perm' hides or locks a property for the account owner or project members. An array of these objects creates several at once.",
                "oneOf": [
                  {
                    "items": {
                      "$ref": "#/components/schemas/property_create"
                    },
                    "type": "array"
                  },
                  {
                    "$ref": "#/components/schemas/property_create"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CreateDeviceProperty",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/properties/{property}": {
      "delete": {
        "operationId": "Device_DeleteProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "DeleteDeviceProperty",
        "tags": [
          "Devices"
        ]
      },
      "get": {
        "operationId": "Device_ReadProperty",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceProperty",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "Device_PatchProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Change some fields of the value": {
                  "value": {
                    "value": {
                      "interval": 30
                    }
                  }
                },
                "Flattened fields": {
                  "value": {
                    "value.alerts": false,
                    "value.max_temperature": 27
                  }
                }
              },
              "schema": {
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "value": {}
                    },
                    "required": [
                      "value"
                    ]
                  },
                  {
                    "additionalProperties": false,
                    "minProperties": 1,
                    "patternProperties": {
                      "^value(\\.[^.]+)+$": {}
                    }
                  }
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDeviceProperty",
        "tags": [
          "Devices"
        ]
      },
      "put": {
        "operationId": "Device_UpdateProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Hide from project members": {
                  "value": {
                    "perm": {
                      "hidden": [
                        "member"
                      ]
                    },
                    "value": "internal note"
                  }
                },
                "Replace the value": {
                  "value": {
                    "value": {
                      "alerts": true,
                      "interval": 30,
                      "max_temperature": 27
                    }
                  }
                },
                "Value, name and description": {
                  "value": {
                    "description": "Faster sampling during commissioning",
                    "name": "Settings",
                    "value": {
                      "alerts": false,
                      "interval": 10,
                      "max_temperature": 28.5
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/property_update"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "UpdateDeviceProperty",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/properties/{property}/clone": {
      "get": {
        "operationId": "Device_ClonePropertyConfig",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDevicePropertyConfig",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "property",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_CloneProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Copy with a new id": {
                  "value": {
                    "property": "copy_of_property"
                  }
                },
                "Copy with name and description": {
                  "value": {
                    "description": "Same configuration as the original, for production line 2",
                    "name": "Line 2 copy",
                    "property": "line_2_property"
                  }
                }
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "description": {
                    "$ref": "#/components/schemas/resource_description"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "name": {
                    "$ref": "#/components/schemas/resource_name"
                  },
                  "property": {
                    "$ref": "#/components/schemas/resource_id"
                  }
                },
                "required": [
                  "property"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "CloneDeviceProperty",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/resources": {
      "get": {
        "operationId": "Device_AccessResources",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/resources/{resource}": {
      "get": {
        "operationId": "Device_AccessOutputResources",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "resource",
          "required": true,
          "schema": {
            "pattern": "^(?:.{1,32}\\/?+)",
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "Device_AccessInputResources",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "Set a target": {
                  "value": {
                    "mode": "auto",
                    "setpoint": 21.5
                  }
                },
                "Switch a relay": {
                  "value": {
                    "in": true
                  }
                }
              },
              "schema": {
                "description": "Input of the device resource: whatever JSON the resource expects (see GET .../resources for its description). Resources without input take no body."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceResources",
        "tags": [
          "Devices"
        ]
      }
    },
    "/v3/users/{user}/devices/{device}/services": {
      "get": {
        "operationId": "Device_ListServices",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ListDeviceServices",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/services/{service}": {
      "get": {
        "operationId": "Device_ReadService",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceService",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "service",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/services/{service}/vnc": {
      "get": {
        "operationId": "Device_AccessRemoteDesktopVnc",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceRemoteDesktop",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "service",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/services/{service}/web": {
      "get": {
        "operationId": "Device_AccessWebServices",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "AccessDeviceWebServices",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "service",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/stats": {
      "get": {
        "operationId": "Device_ReadStatistics",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceStatistics",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/v3/users/{user}/devices/{device}/ws_proxy": {
      "parameters": [
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/{version}/users/{user}/buckets/{bucket}/data": {
      "get": {
        "operationId": "Bucket_ReadData",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadBucket",
        "tags": [
          "Buckets"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "version",
          "required": true,
          "schema": {
            "pattern": "^(?:v1|v2)",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    },
    "/{version}/users/{user}/devices/{device}/buckets/{bucket}/data": {
      "get": {
        "operationId": "Device_ReadBucketData",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "ok"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": [],
            "oauth": [
              "basic"
            ]
          }
        ],
        "summary": "ReadDeviceBucket",
        "tags": [
          "Devices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "version",
          "required": true,
          "schema": {
            "pattern": "^(?:v1|v2|v3)",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "user",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "device",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "bucket",
          "required": true,
          "schema": {
            "pattern": "^[a-zA-Z0-9_-]{1,32}",
            "type": "string"
          }
        }
      ]
    }
  },
  "servers": [
    {
      "url": "https://YOUR_SERVER"
    }
  ]
}
