{
  "openapi": "3.1.0",
  "info": {
    "title": "WeGuard Developer API",
    "version": "v1",
    "summary": "Read-only REST API for the devices, device status, installed apps, locations, screen time and app usage, policies, account details, users and audit log of your WeGuard account.",
    "description": "Read-only REST API for the data in your WeGuard account. Resources: Identity, Account, Devices, Installed apps, Location history, Screen time and app usage, Policies, Users, Audit logs.\n\n- **Authentication:** Send an API key as `Authorization: Bearer wgk_<keyId>_<secret>`. Account admins create keys in the WeGuard console under Settings → Developer API. See [Authentication](https://weguard.ai/docs/authentication).\n- **Scopes:** Each operation lists the scopes it needs in `x-required-scopes`. See [Authorization & scopes](https://weguard.ai/docs/authorization).\n- **Errors:** The API reports errors as RFC 9457 problem details (`application/problem+json`) with a stable `code`. See [Errors](https://weguard.ai/docs/errors).\n- **Pagination:** Lists are cursor-based. Pass `nextCursor` back as `cursor`. See [Pagination](https://weguard.ai/docs/pagination).\n- **Rate limits:** 600 requests per minute per key. The `RateLimit-*` headers report the key's current budget. See [Rate limits](https://weguard.ai/docs/rate-limits).\n- **Compatibility:** Fields, endpoints, error codes and scopes may be added within `v1`, so ignore fields you do not recognize. See [Conventions & versioning](https://weguard.ai/docs/conventions).\n\nGuides, examples and the changelog: https://weguard.ai/docs",
    "contact": {
      "name": "WeGuard support",
      "url": "https://support.weguard.com"
    }
  },
  "externalDocs": {
    "description": "WeGuard Developer API documentation",
    "url": "https://weguard.ai/docs"
  },
  "servers": [
    {
      "url": "https://api-gw.weguard.ai/core/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Identity",
      "description": "Verify an API key and see which account and scopes it carries.\n\nCall `GET /v1/me` first when you set up an integration or rotate a key. It confirms that the key works and tells you which account it belongs to and which scopes it holds. The endpoint itself needs no scope.\n\nFor the account’s plan, license usage and tag labels, use [Retrieve the account](https://weguard.ai/docs/api/account), which requires `account:read`.",
      "externalDocs": {
        "description": "Identity API reference",
        "url": "https://weguard.ai/docs/api/me"
      }
    },
    {
      "name": "Account",
      "description": "Your WeGuard account: plan, license usage, enabled platforms and the labels of the device tag slots.\n\nEvery API key belongs to exactly one account, so this endpoint always returns the account that owns the calling key. If you only need to know which account a key belongs to, call [`GET /v1/me`](https://weguard.ai/docs/api/me). It needs no scope.",
      "externalDocs": {
        "description": "Account API reference",
        "url": "https://weguard.ai/docs/api/account"
      }
    },
    {
      "name": "Devices",
      "description": "Inventory, enrollment, policy, compliance, security state, connectivity and status of your managed Android, Apple (iOS, iPadOS, macOS, tvOS) and Windows devices.\n\nA device is any phone, tablet, computer or other hardware managed in your WeGuard account. This includes devices whose enrollment is pending and devices that were unenrolled (see `enrollment.status`). Common attributes are normalized across platforms and always present. When a platform does not report one, its value is `null`. Platform-specific attributes are in `details`.\n\nWindows Update compliance, hardware health and disk encryption are not part of the device object, so device lists stay fast. Call [Retrieve a device’s status](https://weguard.ai/docs/api/devices#retrieve-device-status) to read them for one device. The status also gives the battery as a percentage on every platform, while `details.batteryLevel` keeps the form each platform reports.\n\nFor the apps on a device, its past positions and how it is used, see [Installed apps](https://weguard.ai/docs/api/installed-apps), [Location history](https://weguard.ai/docs/api/location-history) and [Screen time and app usage](https://weguard.ai/docs/api/usage).",
      "externalDocs": {
        "description": "Devices API reference",
        "url": "https://weguard.ai/docs/api/devices"
      }
    },
    {
      "name": "Installed apps",
      "description": "The apps installed on a device, as the device last reported them.\n\nEach device reports its own app inventory, so the list is only as current as the device’s last report. There is no per-app timestamp. Android, Apple and Windows devices report different details, and fields a platform does not report are `null`.\n\nOn Android, the list also contains apps that the device’s policy requires but that failed to install (`installed: false`). Use them to spot failed deployments.",
      "externalDocs": {
        "description": "Installed apps API reference",
        "url": "https://weguard.ai/docs/api/installed-apps"
      }
    },
    {
      "name": "Location history",
      "description": "The locations a device reported over time, newest first.\n\nWeGuard records history only while the device’s policy has location tracking turned on. History is kept for about 65 days on Android and 60 days on Apple devices. Windows history does not expire automatically. On Windows, you get only the points recorded since the device’s current enrollment, not points from an earlier enrollment, even one in your own account. On Android, history follows the physical device within your account, so it can include points from an earlier enrollment of the same device, within the retention period.\n\nIf you only need the most recent position, use [Retrieve a device’s location](https://weguard.ai/docs/api/devices#retrieve-device-location).",
      "externalDocs": {
        "description": "Location history API reference",
        "url": "https://weguard.ai/docs/api/location-history"
      }
    },
    {
      "name": "Screen time and app usage",
      "description": "Daily screen time, up time and per-app foreground time of Windows devices, per UTC day.\n\nThese endpoints show how a Windows device was used, one UTC day at a time: how long a user was signed in with the session unlocked (screen time), how long the device was on and awake (up time), and how long each app was in the foreground (app usage). The WeGuard agent measures them on the device. They need the `usage:read` scope. Keep the following points in mind when you use the numbers.\n\n**Foreground time, not active use.** The agent records which window is in front. It has no idle detection, so a window left in front counts until another app, a lock, sign-out, sleep or shutdown takes over.\n\n**UTC days.** Each entry covers one calendar day in UTC, from midnight to midnight. A local day in another time zone spans two UTC dates. For example, in UTC-08:00, work done at 17:00 local time falls on the next UTC date.\n\n**Sessions count on the day they start.** An app session that runs past midnight counts in full on the day it started. Screen time and up time are split at midnight instead.\n\n**Windows only today.** Devices on other platforms return [422 unsupported_platform](https://weguard.ai/docs/errors#unsupported_platform).\n\n**About 60 days of history.** Older days return no entries, so store the data you want to keep.\n\n**Collection depends on the policy.** WeGuard stores usage only while the device’s policy has Screen Time turned on. Days without data are left out. While `collection.enabled` is `false`, a missing day was not collected. It reflects the current policy only, so with `true` a missing day most likely means that the device was not used, but it can also be a day when the policy did not collect usage, or a day the device has not uploaded yet. History starts at the device’s current enrollment and is not filtered by policy, so it survives a policy change.\n\n**Known measurement limits.** Time in an app that runs with administrator rights is not counted. Switching between windows of the same app can drop the time before the switch. After a crash or hard power-off, screen time and up time can read 86400 for the days the device was off. Two users signed in at the same time count twice in screen time, up to the 86400 cap.",
      "externalDocs": {
        "description": "Screen time and app usage API reference",
        "url": "https://weguard.ai/docs/api/usage"
      }
    },
    {
      "name": "Policies",
      "description": "Device policies across platforms, how many devices each one manages, and which devices are assigned to it.\n\nA policy is the configuration WeGuard applies to the devices assigned to it. Each device has at most one policy, shown in `policy` on the [device object](https://weguard.ai/docs/api/devices#the-device-object).",
      "externalDocs": {
        "description": "Policies API reference",
        "url": "https://weguard.ai/docs/api/policies"
      }
    },
    {
      "name": "Users",
      "description": "The admins and operators who sign in to your account’s console, with their roles and the policies they can access.\n\nUsers are the people who sign in to the WeGuard console, not the people using managed devices. The API never returns passwords, MFA secrets, recovery codes, tokens or billing data.",
      "externalDocs": {
        "description": "Users API reference",
        "url": "https://weguard.ai/docs/api/users"
      }
    },
    {
      "name": "Audit logs",
      "description": "The console activity log of your WeGuard account: who did what and when, newest first.\n\nUse the audit log to feed a SIEM or to review administrative changes. It is the activity log of the whole account, the same one an account admin (`customer_admin`) sees in the console.\n\nThe console records the entries, so `event`, `message` and `level` are free-form text, not a fixed set. The API never returns the request and response payloads recorded internally, and it replaces credentials in a message, such as API keys, with `[redacted]`.",
      "externalDocs": {
        "description": "Audit logs API reference",
        "url": "https://weguard.ai/docs/api/audit-logs"
      }
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "retrieveMe",
        "summary": "Retrieve the calling key",
        "description": "Returns the API key used for the request and the account that owns it. Any valid key can call this endpoint. No scope is required, and the endpoint takes no parameters.\n\n**Required scopes:** none. Any valid API key can call this endpoint. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Identity"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/me#retrieve-me"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [me object](https://weguard.ai/docs/api/me#the-me-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                },
                "example": {
                  "object": "me",
                  "account": {
                    "id": "5f1d7c0e9b1e8a3f2c4d6e8a",
                    "name": "Acme Logistics"
                  },
                  "apiKey": {
                    "id": "6701a2b3c4d5e6f708192a3b",
                    "name": "CMDB sync",
                    "prefix": "wgk_1a2b3c4d5e6f7a8b",
                    "scopes": [
                      "devices:read"
                    ],
                    "createdAt": "2026-10-01T10:00:00Z",
                    "expiresAt": "2026-12-30T10:00:00Z"
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/me",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": []
      }
    },
    "/account": {
      "get": {
        "operationId": "retrieveAccount",
        "summary": "Retrieve the account",
        "description": "Returns the account that owns the API key. This endpoint takes no parameters.\n\n**Required scope:** `account:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Account"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/account#retrieve-account"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an [account object](https://weguard.ai/docs/api/account#the-account-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "example": {
                  "id": "5f1d7c0e9b1e8a3f2c4d6e8a",
                  "object": "account",
                  "name": "Acme Logistics",
                  "state": "live",
                  "plan": "Enterprise",
                  "licenses": {
                    "purchased": 500,
                    "provisionedDevices": 312,
                    "unprovisionedDevices": 14
                  },
                  "licenseValidFrom": "2026-01-01T00:00:00Z",
                  "licenseValidUntil": "2026-12-31T23:59:59Z",
                  "trialEndsAt": null,
                  "platforms": [
                    "android",
                    "ios",
                    "windows"
                  ],
                  "mfaRequired": true,
                  "tagLabels": {
                    "tag6": "Region",
                    "tag7": "Cost centre"
                  },
                  "createdAt": "2024-05-02T10:11:12Z"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/account",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `account:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks account:read.",
                      "instance": "/core/v1/account",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/account",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "account:read"
        ]
      }
    },
    "/devices": {
      "get": {
        "operationId": "listDevices",
        "summary": "List devices",
        "description": "Returns the devices in your account, ordered by `id` (creation order), as a [paginated list](https://weguard.ai/docs/pagination).\n\n**Required scope:** `devices:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Devices"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/devices#list-devices"
        },
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "description": "Only return items for these platforms. Pass a comma-separated list, for example `android,ios`. Values are case-insensitive. `ios` covers iPhone, iPad and iPod touch. Default: all platforms.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "android",
                  "ios",
                  "macos",
                  "tvos",
                  "windows"
                ]
              }
            },
            "style": "form",
            "explode": false,
            "example": [
              "android"
            ]
          },
          {
            "name": "policyId",
            "in": "query",
            "required": false,
            "description": "Only return devices assigned to this policy. Case-insensitive. A well-formed id that matches no policy returns an empty list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `100`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [device objects](https://weguard.ai/docs/api/devices#the-device-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "6523f1c2a7b9d40012345678",
                      "object": "device",
                      "platform": "android",
                      "name": "Warehouse Scanner 12",
                      "model": "SM-T505",
                      "manufacturer": "samsung",
                      "osVersion": "13",
                      "serialNumber": "R9JN30ABCDE",
                      "imei": "356938035643809",
                      "phoneNumber": null,
                      "agentVersion": "6.4.2",
                      "policy": {
                        "id": "64ff0a1b2c3d4e5f60718293",
                        "name": "Kiosk: Scanners"
                      },
                      "enrollment": {
                        "status": "enrolled",
                        "enrolledAt": "2026-03-14T08:12:44Z"
                      },
                      "state": {
                        "lost": false,
                        "compromised": false,
                        "locked": false
                      },
                      "compliance": {
                        "policyCompliant": true,
                        "appsCompliant": false
                      },
                      "tags": {
                        "tag1": "Dock 4",
                        "tag3": "Night shift"
                      },
                      "lastSeenAt": "2026-10-07T09:29:51Z",
                      "connectivity": {
                        "status": "online",
                        "thresholdMinutes": 1440
                      },
                      "createdAt": "2026-03-14T08:10:02Z",
                      "details": {
                        "deviceIdType": "IMEI",
                        "suspended": false,
                        "wiped": false,
                        "enterpriseEnrolled": true,
                        "appliedPolicyVersion": 42,
                        "mobileDataUsageBytes": 1288490188,
                        "wifiDataUsageBytes": 9663676416,
                        "batteryLevel": 87
                      }
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "YzE6NjUyM2YxYzJhN2I5ZDQwMDEyMzQ1Njc4"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `platform` has an unsupported value, `policyId` is malformed, `limit` or `includeTotal` is invalid, or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed or was issued for different filters.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "platform has an unsupported value, policyId is malformed, limit or includeTotal is invalid, or a parameter was sent twice.",
                      "instance": "/core/v1/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed or was issued for different filters.",
                      "instance": "/core/v1/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `devices:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks devices:read.",
                      "instance": "/core/v1/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "devices:read"
        ]
      }
    },
    "/devices/{deviceId}": {
      "get": {
        "operationId": "retrieveDevice",
        "summary": "Retrieve a device",
        "description": "Returns a single device by id.\n\n**Required scope:** `devices:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Devices"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/devices#retrieve-device"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d40012345678"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [device object](https://weguard.ai/docs/api/devices#the-device-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Device"
                },
                "example": {
                  "id": "6523f1c2a7b9d40012345678",
                  "object": "device",
                  "platform": "android",
                  "name": "Warehouse Scanner 12",
                  "model": "SM-T505",
                  "manufacturer": "samsung",
                  "osVersion": "13",
                  "serialNumber": "R9JN30ABCDE",
                  "imei": "356938035643809",
                  "phoneNumber": null,
                  "agentVersion": "6.4.2",
                  "policy": {
                    "id": "64ff0a1b2c3d4e5f60718293",
                    "name": "Kiosk: Scanners"
                  },
                  "enrollment": {
                    "status": "enrolled",
                    "enrolledAt": "2026-03-14T08:12:44Z"
                  },
                  "state": {
                    "lost": false,
                    "compromised": false,
                    "locked": false
                  },
                  "compliance": {
                    "policyCompliant": true,
                    "appsCompliant": false
                  },
                  "tags": {
                    "tag1": "Dock 4",
                    "tag3": "Night shift"
                  },
                  "lastSeenAt": "2026-10-07T09:29:51Z",
                  "connectivity": {
                    "status": "online",
                    "thresholdMinutes": 1440
                  },
                  "createdAt": "2026-03-14T08:10:02Z",
                  "details": {
                    "deviceIdType": "IMEI",
                    "suspended": false,
                    "wiped": false,
                    "enterpriseEnrolled": true,
                    "appliedPolicyVersion": 42,
                    "mobileDataUsageBytes": 1288490188,
                    "wifiDataUsageBytes": 9663676416,
                    "batteryLevel": 87
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `devices:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks devices:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "devices:read"
        ]
      }
    },
    "/devices/{deviceId}/status": {
      "get": {
        "operationId": "retrieveDeviceStatus",
        "summary": "Retrieve a device’s status",
        "description": "Returns the operational status of a device: connectivity and battery, and for Windows devices also Windows Update compliance, the latest hardware health sample, BitLocker and TPM state, and Secure Boot. The API reads what WeGuard has stored and does not contact the device.\n\n**Required scope:** `devices:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> The `hardware` and `encryption` sections are reported by the device and not verified by WeGuard. Use them for inventory and monitoring, not as proof of compliance.",
        "tags": [
          "Devices"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/devices#retrieve-device-status"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d4001234567a"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [device status object](https://weguard.ai/docs/api/devices#the-device-status-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceStatus"
                },
                "example": {
                  "object": "device_status",
                  "deviceId": "6523f1c2a7b9d4001234567a",
                  "platform": "windows",
                  "lastSeenAt": "2026-10-07T09:29:51Z",
                  "connectivity": {
                    "status": "online",
                    "thresholdMinutes": 1440
                  },
                  "battery": {
                    "level": 87,
                    "charging": true,
                    "reportedAt": "2026-10-07T09:29:51Z"
                  },
                  "updates": {
                    "complianceState": "non_compliant",
                    "missingCriticalCount": 1,
                    "missingImportantCount": 0,
                    "missingOtherCount": 3,
                    "failedCount": 0,
                    "pendingRebootCount": 1,
                    "pendingRebootSince": "2026-09-28T06:10:00Z",
                    "lastScanAt": "2026-10-07T03:12:44Z",
                    "osBuild": "26200.9445",
                    "osDisplayVersion": "25H2"
                  },
                  "hardware": {
                    "sampledAt": "2026-10-07T09:15:00Z",
                    "cpuUtilizationPercent": 7,
                    "memory": {
                      "totalBytes": 25555055411,
                      "availableBytes": 18253611008
                    },
                    "drives": [
                      {
                        "name": "C:",
                        "type": "fixed",
                        "totalBytes": 254476812288,
                        "freeBytes": 179314884608
                      },
                      {
                        "name": "F:",
                        "type": "removable",
                        "totalBytes": 61203283968,
                        "freeBytes": 0
                      }
                    ]
                  },
                  "encryption": {
                    "reportedAt": "2026-10-01T08:15:00Z",
                    "drives": [
                      {
                        "mountPoint": "C:",
                        "protectionStatus": "on",
                        "encryptionStatus": "fully_encrypted",
                        "encryptionPercentage": 100,
                        "lockStatus": "unlocked"
                      }
                    ],
                    "tpm": {
                      "present": true,
                      "enabled": true,
                      "activated": true,
                      "specVersion": "2.0"
                    }
                  },
                  "secureBoot": null
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/status",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `devices:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks devices:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/status",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/status",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/status",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "devices:read"
        ]
      }
    },
    "/devices/{deviceId}/location": {
      "get": {
        "operationId": "retrieveDeviceLocation",
        "summary": "Retrieve a device’s location",
        "description": "Returns the last location the device reported. The API reads the stored location and does not ask the device for a new fix. Only `locations:read` is required. For earlier positions, use [location history](https://weguard.ai/docs/api/location-history).\n\n**Required scope:** `locations:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> Locations are personal data about the people who use your devices. Grant `locations:read` only to integrations that need it, and handle the data according to your privacy obligations.",
        "tags": [
          "Devices"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/devices#retrieve-device-location"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d40012345679"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [device location object](https://weguard.ai/docs/api/devices#the-device-location-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLocation"
                },
                "example": {
                  "object": "device_location",
                  "deviceId": "6523f1c2a7b9d40012345679",
                  "latitude": 17.4474,
                  "longitude": 78.3762,
                  "accuracyMeters": 12.5,
                  "recordedAt": "2026-10-07T09:20:00Z"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345679/location",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `locations:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks locations:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345679/location",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345679/location",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.\n- `location_unavailable`: The device has never reported a valid location.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found",
                            "location_unavailable"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345679/location",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "location_unavailable": {
                    "summary": "Location unavailable",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#location_unavailable",
                      "title": "Location unavailable",
                      "status": 404,
                      "code": "location_unavailable",
                      "detail": "The device has never reported a valid location.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345679/location",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "locations:read"
        ]
      }
    },
    "/devices/{deviceId}/apps": {
      "get": {
        "operationId": "listInstalledApps",
        "summary": "List a device’s installed apps",
        "description": "Returns the apps installed on the device, plus apps its policy requires that failed to install (`installed: false`). This list is not paginated. The whole inventory comes back in one list object, with `hasMore` always `false` and `nextCursor` always `null`. Items are sorted by `name`, then `identifier`, case-insensitively, with missing names last.\n\n**Required scope:** `apps:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Installed apps"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/installed-apps#list-installed-apps"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d40012345678"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only return apps of these types. Pass a comma-separated list, for example `store,private`. Values are case-insensitive. Sending this filter leaves out apps whose `type` is `null`. `system` also needs `includeSystem=true`. Without it, `system` matches nothing. Default: all types.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "store",
                  "private",
                  "system",
                  "msi",
                  "exe"
                ]
              }
            },
            "style": "form",
            "explode": false,
            "example": [
              "store",
              "private"
            ]
          },
          {
            "name": "includeSystem",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return apps bundled with the OS (`type` `system`): Android pre-installed apps and Windows system packages.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds every matching [installed app object](https://weguard.ai/docs/api/installed-apps#the-installed-app-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstalledAppList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "installed_app",
                      "identifier": "com.acme.scanner",
                      "name": null,
                      "type": "private",
                      "version": "3.2.0",
                      "versionCode": "320",
                      "installed": false,
                      "publisher": null,
                      "sizeBytes": null,
                      "installedAt": null,
                      "status": null,
                      "error": {
                        "code": "NOT_COMPATIBLE_WITH_DEVICE",
                        "message": "The app is not compatible with this device."
                      }
                    },
                    {
                      "object": "installed_app",
                      "identifier": "com.android.chrome",
                      "name": null,
                      "type": "store",
                      "version": "126.0.6478.71",
                      "versionCode": "647807131",
                      "installed": true,
                      "publisher": null,
                      "sizeBytes": null,
                      "installedAt": null,
                      "status": null,
                      "error": null
                    }
                  ],
                  "hasMore": false,
                  "nextCursor": null
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `type` contains an unsupported value, `includeSystem` is not `true`/`false`, or a parameter was sent twice.\n- `unknown_parameter`: The request includes another query parameter. This endpoint is not paginated, so it rejects `limit` and `cursor` too.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "type contains an unsupported value, includeSystem is not true/false, or a parameter was sent twice.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/apps",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes another query parameter. This endpoint is not paginated, so it rejects limit and cursor too.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/apps",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `apps:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks apps:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/apps",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/apps",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/apps",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "apps:read"
        ]
      }
    },
    "/devices/{deviceId}/locations": {
      "get": {
        "operationId": "listLocationHistory",
        "summary": "List a device’s location history",
        "description": "Returns the locations the device reported between `since` and `until`, newest first, as a [paginated list](https://weguard.ai/docs/pagination). If you omit both `since` and `until`, you get the last 24 hours. See [Time ranges](https://weguard.ai/docs/time-ranges).\n\n**Required scope:** `locations:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> Location history is personal data about the people who use your devices. Grant `locations:read` only to integrations that need it, request only the window you need, and handle the data according to your privacy obligations.",
        "tags": [
          "Location history"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/location-history#list-location-history"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d40012345678"
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Start of the time range (inclusive), as an ISO-8601 timestamp with a UTC offset, for example `2026-10-01T00:00:00Z`. Must be earlier than `until`. The range can span at most 31 days. See [Time ranges](https://weguard.ai/docs/time-ranges). Default: 24 hours before until.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-07T00:00:00Z"
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "End of the time range (exclusive), as an ISO-8601 timestamp with a UTC offset. If you omit it, the first page fixes “now” and every `nextCursor` carries that value, so all pages cover the same window. In that case the maximum span of 31 days allows 5 minutes of clock tolerance. Default: now.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-08T00:00:00Z"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `1000`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            },
            "example": 2
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [location point objects](https://weguard.ai/docs/api/location-history#the-location-point-object), newest first. An empty list with `hasMore: false` means there is no history in the window. The API skips points without valid coordinates. As a result, a page can hold fewer than `limit` points while `hasMore` is `true`, and `totalCount` (with `includeTotal=true`) can be higher than the number of points you receive across all pages.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationPointList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "6701c2e5f1a2b3c4d5e6f789",
                      "object": "location_point",
                      "latitude": 17.4474,
                      "longitude": 78.3762,
                      "accuracyMeters": 12.4,
                      "altitudeMeters": 512.3,
                      "speedMetersPerSecond": 0.3,
                      "headingDegrees": null,
                      "recordedAt": "2026-10-07T09:20:00Z"
                    },
                    {
                      "id": "6701c2b1f1a2b3c4d5e6f701",
                      "object": "location_point",
                      "latitude": 17.4452,
                      "longitude": 78.3791,
                      "accuracyMeters": 18.5,
                      "altitudeMeters": 498.7,
                      "speedMetersPerSecond": 1.4,
                      "headingDegrees": null,
                      "recordedAt": "2026-10-07T09:05:00Z"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "dDE6MTc5MTQxNDAwMDAwMDo2NzAxYzJlNWYxYTJiM2M0ZDVlNmY3ODk"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `since` or `until` is not an ISO-8601 timestamp with an offset, or is outside the range 1970-01-01T00:00:00Z to 9999-12-31T23:59:59.999Z; `since` is not earlier than `until`; the range is longer than 31 days; `limit` or `includeTotal` is invalid; or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed, or was issued for a different listing: another path, other filters, or another `since` / `until`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "since or until is not an ISO-8601 timestamp with an offset, or is outside the range 1970-01-01T00:00:00Z to 9999-12-31T23:59:59.999Z; since is not earlier than until; the range is longer than 31 days; limit or includeTotal is invalid; or a parameter was sent twice.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed, or was issued for a different listing: another path, other filters, or another since / until.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `locations:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks locations:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d40012345678/locations",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "locations:read"
        ]
      }
    },
    "/devices/{deviceId}/screen-time": {
      "get": {
        "operationId": "listScreenTime",
        "summary": "List a device’s daily screen time",
        "description": "Returns the screen time and up time of a Windows device, one entry per UTC day that has data, newest first. Days without data are left out. If you omit `since` and `until`, you get the last 7 days, today included. This list is not paginated: a range covers at most 31 days, so every entry comes back in one list object, with `hasMore` always `false` and `nextCursor` always `null`. See [Date ranges](https://weguard.ai/docs/time-ranges#date-ranges).\n\n**Required scope:** `usage:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> Screen time and app usage are personal data about the people who use your devices. WeGuard never returns the Windows user name, and each day covers every user of the device. Grant `usage:read` only to integrations that need it, and check local consent and works council requirements before you collect or export this data.",
        "tags": [
          "Screen time and app usage"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/usage#list-screen-time"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d4001234567a"
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "First day of the range (inclusive), as a UTC calendar date in the form `YYYY-MM-DD`, for example `2026-10-01`. Must not be after `until`. The range can cover at most 31 days, both ends included. See [Date ranges](https://weguard.ai/docs/time-ranges#date-ranges). Default: 6 days before until.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-05"
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "Last day of the range (inclusive), as a UTC calendar date in the form `YYYY-MM-DD`. Must not be later than today in UTC. Default: today (UTC).",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-07"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [screen time day objects](https://weguard.ai/docs/api/usage#the-screen-time-day-object), newest first, plus `collection`. An empty `data` means there is no data in the range. If `collection.enabled` is `false`, nothing was collected. If it is `true`, the device was most likely not used, but the policy may have been off on those days, or the device has not uploaded them yet.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreenTimeDayList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "screen_time_day",
                      "date": "2026-10-07",
                      "dayStart": "2026-10-07T00:00:00Z",
                      "dayEnd": "2026-10-08T00:00:00Z",
                      "screenTimeSeconds": 5640,
                      "upTimeSeconds": 5820,
                      "complete": false
                    },
                    {
                      "object": "screen_time_day",
                      "date": "2026-10-06",
                      "dayStart": "2026-10-06T00:00:00Z",
                      "dayEnd": "2026-10-07T00:00:00Z",
                      "screenTimeSeconds": 27315,
                      "upTimeSeconds": 33960,
                      "complete": true
                    },
                    {
                      "object": "screen_time_day",
                      "date": "2026-10-05",
                      "dayStart": "2026-10-05T00:00:00Z",
                      "dayEnd": "2026-10-06T00:00:00Z",
                      "screenTimeSeconds": 25480,
                      "upTimeSeconds": 31205,
                      "complete": true
                    }
                  ],
                  "hasMore": false,
                  "nextCursor": null,
                  "collection": {
                    "enabled": true
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `since` or `until` is not a date in the form `YYYY-MM-DD`, `since` is after `until`, `until` is later than today (UTC), or the range covers more than 31 days; or a parameter was sent twice.\n- `unknown_parameter`: The request includes another query parameter. This list is not paginated, so it rejects `limit`, `cursor` and `includeTotal` too.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "since or until is not a date in the form YYYY-MM-DD, since is after until, until is later than today (UTC), or the range covers more than 31 days; or a parameter was sent twice.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes another query parameter. This list is not paginated, so it rejects limit, cursor and includeTotal too.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `usage:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks usage:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "422": {
            "description": "Unprocessable Content. The `code` is one of:\n\n- `unsupported_platform`: The device is not a Windows device. Screen time and app usage are available for Windows devices only.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 422
                        },
                        "code": {
                          "enum": [
                            "unsupported_platform"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unsupported_platform": {
                    "summary": "Unsupported platform",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unsupported_platform",
                      "title": "Unsupported platform",
                      "status": 422,
                      "code": "unsupported_platform",
                      "detail": "The device is not a Windows device. Screen time and app usage are available for Windows devices only.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/screen-time",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "usage:read"
        ]
      }
    },
    "/devices/{deviceId}/app-usage": {
      "get": {
        "operationId": "listAppUsage",
        "summary": "List a device’s daily app usage",
        "description": "Returns the foreground time of each app on a Windows device, one entry per app and UTC day, as a [paginated list](https://weguard.ai/docs/pagination). Entries are ordered by `date`, newest first, then by `app.identifier`, ignoring case. Days and apps without data are left out. If you omit `since` and `until`, you get the last 7 days, today included. See [Date ranges](https://weguard.ai/docs/time-ranges#date-ranges).\n\n**Required scope:** `usage:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> Screen time and app usage are personal data about the people who use your devices. WeGuard never returns the Windows user name, and each day covers every user of the device. Grant `usage:read` only to integrations that need it, and check local consent and works council requirements before you collect or export this data.",
        "tags": [
          "Screen time and app usage"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/usage#list-app-usage"
        },
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "description": "Id of the device. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "6523f1c2a7b9d4001234567a"
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "First day of the range (inclusive), as a UTC calendar date in the form `YYYY-MM-DD`, for example `2026-10-01`. Must not be after `until`. The range can cover at most 31 days, both ends included. See [Date ranges](https://weguard.ai/docs/time-ranges#date-ranges). Default: 6 days before until.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-09-30"
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "Last day of the range (inclusive), as a UTC calendar date in the form `YYYY-MM-DD`. Must not be later than today in UTC. If you omit it, the first page fixes today’s date and every `nextCursor` carries it, so all pages cover the same days, even after midnight UTC. Default: today (UTC).",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-06"
          },
          {
            "name": "apps",
            "in": "query",
            "required": false,
            "description": "Only return these apps. Pass a comma-separated list of identifiers, for example `chrome,WINWORD`. Matching ignores the case of ASCII letters. At most 50 apps, each 1 to 256 characters long. Default: all apps.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 256
              },
              "minItems": 1,
              "maxItems": 50
            },
            "style": "form",
            "explode": false
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `1000`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            },
            "example": 4
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [app usage day objects](https://weguard.ai/docs/api/usage#the-app-usage-day-object), plus `collection`. An empty list with `hasMore: false` means there is no data in the range. If `collection.enabled` is `false`, nothing was collected. If it is `true`, the device was most likely not used, but the policy may have been off on those days, or the device has not uploaded them yet.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppUsageDayList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "app_usage_day",
                      "date": "2026-10-06",
                      "app": {
                        "identifier": "chrome"
                      },
                      "foregroundSeconds": 9842,
                      "sessionCount": 57,
                      "lastUsedAt": "2026-10-06T15:21:09Z",
                      "complete": true
                    },
                    {
                      "object": "app_usage_day",
                      "date": "2026-10-06",
                      "app": {
                        "identifier": "explorer"
                      },
                      "foregroundSeconds": 1263,
                      "sessionCount": 41,
                      "lastUsedAt": "2026-10-06T15:18:52Z",
                      "complete": true
                    },
                    {
                      "object": "app_usage_day",
                      "date": "2026-10-06",
                      "app": {
                        "identifier": "ms-teams"
                      },
                      "foregroundSeconds": 6127,
                      "sessionCount": 33,
                      "lastUsedAt": "2026-10-06T14:02:15Z",
                      "complete": true
                    },
                    {
                      "object": "app_usage_day",
                      "date": "2026-10-06",
                      "app": {
                        "identifier": "OUTLOOK"
                      },
                      "foregroundSeconds": 4410,
                      "sessionCount": 29,
                      "lastUsedAt": "2026-10-06T15:25:30Z",
                      "complete": true
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "ZDE6MjAyNi0xMC0wNjpvdXRsb29r",
                  "collection": {
                    "enabled": true
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `since` or `until` is not a date in the form `YYYY-MM-DD`, `since` is after `until`, `until` is later than today (UTC), or the range covers more than 31 days; `apps` has an empty item, an item longer than 256 characters or more than 50 apps; `limit` or `includeTotal` is invalid; or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed, or was issued for a different listing: another device, other `apps`, or another `since` / `until`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "since or until is not a date in the form YYYY-MM-DD, since is after until, until is later than today (UTC), or the range covers more than 31 days; apps has an empty item, an item longer than 256 characters or more than 50 apps; limit or includeTotal is invalid; or a parameter was sent twice.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed, or was issued for a different listing: another device, other apps, or another since / until.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `usage:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks usage:read.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No device with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No device with this id exists in your account.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "422": {
            "description": "Unprocessable Content. The `code` is one of:\n\n- `unsupported_platform`: The device is not a Windows device. Screen time and app usage are available for Windows devices only.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 422
                        },
                        "code": {
                          "enum": [
                            "unsupported_platform"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unsupported_platform": {
                    "summary": "Unsupported platform",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unsupported_platform",
                      "title": "Unsupported platform",
                      "status": 422,
                      "code": "unsupported_platform",
                      "detail": "The device is not a Windows device. Screen time and app usage are available for Windows devices only.",
                      "instance": "/core/v1/devices/6523f1c2a7b9d4001234567a/app-usage",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "usage:read"
        ]
      }
    },
    "/policies": {
      "get": {
        "operationId": "listPolicies",
        "summary": "List policies",
        "description": "Returns the policies in your account, ordered by `id` (creation order), as a [paginated list](https://weguard.ai/docs/pagination).\n\n**Required scope:** `policies:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Policies"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/policies#list-policies"
        },
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "description": "Only return items for these platforms. Pass a comma-separated list, for example `android,ios`. Values are case-insensitive. `ios` covers iPhone, iPad and iPod touch. Default: all platforms.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "android",
                  "ios",
                  "macos",
                  "tvos",
                  "windows"
                ]
              }
            },
            "style": "form",
            "explode": false,
            "example": [
              "android"
            ]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `100`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [policy objects](https://weguard.ai/docs/api/policies#the-policy-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "64ff0a1b2c3d4e5f60718293",
                      "object": "policy",
                      "platform": "android",
                      "name": "Kiosk: Scanners",
                      "description": "Locked-down scanner devices",
                      "type": "ANDROID_KIOSK",
                      "deviceCount": 128,
                      "createdAt": "2026-01-09T11:00:00Z",
                      "updatedAt": "2026-09-30T16:42:10Z"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "YzE6NjUyM2YxYzJhN2I5ZDQwMDEyMzQ1Njc4"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `limit`, `includeTotal` or a filter has an invalid value, or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed or was issued for different filters.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "limit, includeTotal or a filter has an invalid value, or a parameter was sent twice.",
                      "instance": "/core/v1/policies",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/policies",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed or was issued for different filters.",
                      "instance": "/core/v1/policies",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `policies:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks policies:read.",
                      "instance": "/core/v1/policies",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/policies",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "policies:read"
        ]
      }
    },
    "/policies/{policyId}": {
      "get": {
        "operationId": "retrievePolicy",
        "summary": "Retrieve a policy",
        "description": "Returns a single policy by id.\n\n**Required scope:** `policies:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Policies"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/policies#retrieve-policy"
        },
        "parameters": [
          {
            "name": "policyId",
            "in": "path",
            "required": true,
            "description": "Id of the policy. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "64ff0a1b2c3d4e5f60718293"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [policy object](https://weguard.ai/docs/api/policies#the-policy-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                },
                "example": {
                  "id": "64ff0a1b2c3d4e5f60718293",
                  "object": "policy",
                  "platform": "android",
                  "name": "Kiosk: Scanners",
                  "description": "Locked-down scanner devices",
                  "type": "ANDROID_KIOSK",
                  "deviceCount": 128,
                  "createdAt": "2026-01-09T11:00:00Z",
                  "updatedAt": "2026-09-30T16:42:10Z"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `policies:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks policies:read.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No policy with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No policy with this id exists in your account.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "policies:read"
        ]
      }
    },
    "/policies/{policyId}/devices": {
      "get": {
        "operationId": "listPolicyDevices",
        "summary": "List a policy’s devices",
        "description": "Returns the devices assigned to a policy, ordered by `id`, as a [paginated list](https://weguard.ai/docs/pagination). Requires both `policies:read` and `devices:read`.\n\n**Required scopes:** all of `policies:read`, `devices:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Policies"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/policies#list-policy-devices"
        },
        "parameters": [
          {
            "name": "policyId",
            "in": "path",
            "required": true,
            "description": "Id of the policy. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "64ff0a1b2c3d4e5f60718293"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `100`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [device objects](https://weguard.ai/docs/api/devices#the-device-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "6523f1c2a7b9d40012345678",
                      "object": "device",
                      "platform": "android",
                      "name": "Warehouse Scanner 12",
                      "model": "SM-T505",
                      "manufacturer": "samsung",
                      "osVersion": "13",
                      "serialNumber": "R9JN30ABCDE",
                      "imei": "356938035643809",
                      "phoneNumber": null,
                      "agentVersion": "6.4.2",
                      "policy": {
                        "id": "64ff0a1b2c3d4e5f60718293",
                        "name": "Kiosk: Scanners"
                      },
                      "enrollment": {
                        "status": "enrolled",
                        "enrolledAt": "2026-03-14T08:12:44Z"
                      },
                      "state": {
                        "lost": false,
                        "compromised": false,
                        "locked": false
                      },
                      "compliance": {
                        "policyCompliant": true,
                        "appsCompliant": false
                      },
                      "tags": {
                        "tag1": "Dock 4",
                        "tag3": "Night shift"
                      },
                      "lastSeenAt": "2026-10-07T09:29:51Z",
                      "connectivity": {
                        "status": "online",
                        "thresholdMinutes": 1440
                      },
                      "createdAt": "2026-03-14T08:10:02Z",
                      "details": {
                        "deviceIdType": "IMEI",
                        "suspended": false,
                        "wiped": false,
                        "enterpriseEnrolled": true,
                        "appliedPolicyVersion": 42,
                        "mobileDataUsageBytes": 1288490188,
                        "wifiDataUsageBytes": 9663676416,
                        "batteryLevel": 87
                      }
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "YzE6NjUyM2YxYzJhN2I5ZDQwMDEyMzQ1Njc4"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `limit`, `includeTotal` or a filter has an invalid value, or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed or was issued for different filters.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "limit, includeTotal or a filter has an invalid value, or a parameter was sent twice.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed or was issued for different filters.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `policies:read` or `devices:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks policies:read or devices:read.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No policy with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No policy with this id exists in your account.",
                      "instance": "/core/v1/policies/64ff0a1b2c3d4e5f60718293/devices",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "policies:read",
          "devices:read"
        ]
      }
    },
    "/users": {
      "get": {
        "operationId": "listUsers",
        "summary": "List users",
        "description": "Returns the console users of your account, ordered by `id` (creation order), as a [paginated list](https://weguard.ai/docs/pagination).\n\n**Required scope:** `users:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Users"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/users#list-users"
        },
        "parameters": [
          {
            "name": "role",
            "in": "query",
            "required": false,
            "description": "Only return users with this role, for example `observer`. Matches a lowercase role name exactly: letters and `_`, at most 64 characters. `customer_admin` also matches users without a stored role.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z_]{1,64}$",
              "minLength": 1,
              "maxLength": 64
            },
            "example": "group_admin"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `100`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [user objects](https://weguard.ai/docs/api/users#the-user-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "5f2a9c3e1b7d4a6f8e0c2b41",
                      "object": "user",
                      "email": "jane@acme.example",
                      "firstName": "Jane",
                      "lastName": "Doe",
                      "role": "group_admin",
                      "mfaEnabled": true,
                      "emailVerified": true,
                      "ssoLinked": false,
                      "lastLoginAt": "2026-10-06T14:02:11Z",
                      "createdAt": "2025-02-11T09:00:00Z",
                      "policyScope": {
                        "allPolicies": false,
                        "policyIds": [
                          "64ff0a1b2c3d4e5f60718293"
                        ]
                      }
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "YzE6NjUyM2YxYzJhN2I5ZDQwMDEyMzQ1Njc4"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `role` is not a lowercase role name, `limit` or `includeTotal` is invalid, or a parameter was sent twice.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed or was issued for different filters.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "role is not a lowercase role name, limit or includeTotal is invalid, or a parameter was sent twice.",
                      "instance": "/core/v1/users",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/users",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed or was issued for different filters.",
                      "instance": "/core/v1/users",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `users:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks users:read.",
                      "instance": "/core/v1/users",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/users",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "users:read"
        ]
      }
    },
    "/users/{userId}": {
      "get": {
        "operationId": "retrieveUser",
        "summary": "Retrieve a user",
        "description": "Returns a single console user by id.\n\n**Required scope:** `users:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).",
        "tags": [
          "Users"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/users#retrieve-user"
        },
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "Id of the user. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "5f2a9c3e1b7d4a6f8e0c2b41"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a [user object](https://weguard.ai/docs/api/users#the-user-object).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "id": "5f2a9c3e1b7d4a6f8e0c2b41",
                  "object": "user",
                  "email": "jane@acme.example",
                  "firstName": "Jane",
                  "lastName": "Doe",
                  "role": "group_admin",
                  "mfaEnabled": true,
                  "emailVerified": true,
                  "ssoLinked": false,
                  "lastLoginAt": "2026-10-06T14:02:11Z",
                  "createdAt": "2025-02-11T09:00:00Z",
                  "policyScope": {
                    "allPolicies": false,
                    "policyIds": [
                      "64ff0a1b2c3d4e5f60718293"
                    ]
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `unknown_parameter`: The request includes a query parameter. This endpoint takes none.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "unknown_parameter"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter. This endpoint takes none.",
                      "instance": "/core/v1/users/5f2a9c3e1b7d4a6f8e0c2b41",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `users:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks users:read.",
                      "instance": "/core/v1/users/5f2a9c3e1b7d4a6f8e0c2b41",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/users/5f2a9c3e1b7d4a6f8e0c2b41",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. The `code` is one of:\n\n- `resource_not_found`: No user with this id exists in your account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 404
                        },
                        "code": {
                          "enum": [
                            "resource_not_found"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource not found",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#resource_not_found",
                      "title": "Resource not found",
                      "status": 404,
                      "code": "resource_not_found",
                      "detail": "No user with this id exists in your account.",
                      "instance": "/core/v1/users/5f2a9c3e1b7d4a6f8e0c2b41",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "users:read"
        ]
      }
    },
    "/audit-logs": {
      "get": {
        "operationId": "listAuditLogs",
        "summary": "List audit log entries",
        "description": "Returns audit log entries between `since` and `until`, newest first, as a [paginated list](https://weguard.ai/docs/pagination). If you omit both `since` and `until`, you get the last 7 days. See [Time ranges](https://weguard.ai/docs/time-ranges).\n\n**Required scope:** `audit_logs:read`. See [Authorization & scopes](https://weguard.ai/docs/authorization#scopes).\n\n> Audit log entries contain email addresses and IP addresses of your console users. Grant `audit_logs:read` only to systems that need it.",
        "tags": [
          "Audit logs"
        ],
        "externalDocs": {
          "description": "API reference",
          "url": "https://weguard.ai/docs/api/audit-logs#list-audit-logs"
        },
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Start of the time range (inclusive), as an ISO-8601 timestamp with a UTC offset, for example `2026-10-01T00:00:00Z`. Must be earlier than `until`. The range can span at most 93 days. See [Time ranges](https://weguard.ai/docs/time-ranges). Default: 7 days before until.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "End of the time range (exclusive), as an ISO-8601 timestamp with a UTC offset. If you omit it, the first page fixes “now” and every `nextCursor` carries that value, so all pages cover the same window. In that case the maximum span of 93 days allows 5 minutes of clock tolerance. Default: now.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-08T00:00:00Z"
          },
          {
            "name": "actor",
            "in": "query",
            "required": false,
            "description": "Only return entries by this console user. Pass an email address of at most 254 characters. The match is exact and case-sensitive, and a value that is not an email address is rejected.",
            "schema": {
              "type": "string",
              "pattern": "^[^@]+@[^@]+$",
              "maxLength": 254
            },
            "example": "admin@acme.example"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, from `1` to `100`.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` from the previous page. Send it unchanged, together with the same filters. See [Pagination](https://weguard.ai/docs/pagination).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTotal",
            "in": "query",
            "required": false,
            "description": "Set to `true` to also return `totalCount`. It runs an extra count, so request it only when you need it.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A list object whose `data` holds [audit log objects](https://weguard.ai/docs/api/audit-logs#the-audit-log-object), newest first.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "6702a4b8c9d0e1f2a3b4c5d6",
                      "object": "audit_log",
                      "occurredAt": "2026-10-07T08:15:02Z",
                      "actor": {
                        "email": "admin@acme.example"
                      },
                      "event": "Policy",
                      "message": "Kiosk: Scanners updated",
                      "level": "info",
                      "sourceIp": "203.0.113.7",
                      "policyId": "64ff0a1b2c3d4e5f60718293"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "dDE6MTc5MTQxNDAwMDAwMDo2NzAxYzJlNWYxYTJiM2M0ZDVlNmY3ODk"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. The resource has not changed since the `ETag` you sent in `If-None-Match`. The body is empty.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              }
            }
          },
          "400": {
            "description": "Bad Request. The `code` is one of:\n\n- `invalid_parameter`: `since` or `until` is not an ISO-8601 timestamp with an offset, or is outside the range 1970-01-01T00:00:00Z to 9999-12-31T23:59:59.999Z; `since` is not earlier than `until`; the range is longer than 93 days; `limit` or `includeTotal` is invalid; or a parameter was sent twice. Also returned when `actor` is not an email address.\n- `unknown_parameter`: The request includes a query parameter this endpoint does not accept.\n- `invalid_cursor`: The cursor is malformed, or was issued for a different listing: another path, other filters, or another `since` / `until`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 400
                        },
                        "code": {
                          "enum": [
                            "invalid_parameter",
                            "unknown_parameter",
                            "invalid_cursor"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid_parameter": {
                    "summary": "Invalid parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_parameter",
                      "title": "Invalid parameter",
                      "status": 400,
                      "code": "invalid_parameter",
                      "detail": "since or until is not an ISO-8601 timestamp with an offset, or is outside the range 1970-01-01T00:00:00Z to 9999-12-31T23:59:59.999Z; since is not earlier than until; the range is longer than 93 days; limit or includeTotal is invalid; or a parameter was sent twice. Also returned when actor is not an email address.",
                      "instance": "/core/v1/audit-logs",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "unknown_parameter": {
                    "summary": "Unknown parameter",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#unknown_parameter",
                      "title": "Unknown parameter",
                      "status": 400,
                      "code": "unknown_parameter",
                      "detail": "The request includes a query parameter this endpoint does not accept.",
                      "instance": "/core/v1/audit-logs",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "invalid_cursor": {
                    "summary": "Invalid pagination cursor",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#invalid_cursor",
                      "title": "Invalid pagination cursor",
                      "status": 400,
                      "code": "invalid_cursor",
                      "detail": "The cursor is malformed, or was issued for a different listing: another path, other filters, or another since / until.",
                      "instance": "/core/v1/audit-logs",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Forbidden. The `code` is one of:\n\n- `insufficient_scope`: The key lacks `audit_logs:read`.\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWW-Authenticate"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control-Problem"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "properties": {
                        "status": {
                          "const": 403
                        },
                        "code": {
                          "enum": [
                            "insufficient_scope",
                            "account_inactive"
                          ]
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "Insufficient scope",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#insufficient_scope",
                      "title": "Insufficient scope",
                      "status": 403,
                      "code": "insufficient_scope",
                      "detail": "The key lacks audit_logs:read.",
                      "instance": "/core/v1/audit-logs",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  },
                  "account_inactive": {
                    "summary": "Account inactive",
                    "value": {
                      "type": "https://weguard.ai/docs/errors#account_inactive",
                      "title": "Account inactive",
                      "status": 403,
                      "code": "account_inactive",
                      "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                      "instance": "/core/v1/audit-logs",
                      "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                    }
                  }
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/NotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "x-required-scopes": [
          "audit_logs:read"
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wgk_<keyId>_<secret>",
        "description": "API key created by an account admin in the WeGuard console (Settings → Developer API), sent as `Authorization: Bearer wgk_<keyId>_<secret>`. See [Authentication](https://weguard.ai/docs/authentication)."
      }
    },
    "parameters": {
      "IfNoneMatch": {
        "name": "If-None-Match",
        "in": "header",
        "required": false,
        "description": "An `ETag` from an earlier response. If the response would be unchanged, the API returns `304 Not Modified` with an empty body. See [Conditional requests](https://weguard.ai/docs/conventions#etags).",
        "schema": {
          "type": "string"
        }
      },
      "RequestId": {
        "name": "X-Request-Id",
        "in": "header",
        "required": false,
        "description": "Your own id for the request: 8 to 128 characters, using letters, digits, `.`, `_`, `:` and `-`. The API echoes it in the `X-Request-Id` response header. If you omit it or send an invalid value, WeGuard generates an id.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9._:-]+$"
        }
      }
    },
    "headers": {
      "RateLimit-Limit": {
        "description": "Size of the key's request bucket: 600 requests per minute, with bursts up to that size. See [Rate limits](https://weguard.ai/docs/rate-limits).",
        "schema": {
          "type": "integer",
          "minimum": 1
        },
        "example": 600
      },
      "RateLimit-Remaining": {
        "description": "Requests the key can make right now. See [Rate limits](https://weguard.ai/docs/rate-limits).",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "RateLimit-Reset": {
        "description": "Seconds until the bucket is completely full again. See [Rate limits](https://weguard.ai/docs/rate-limits).",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "X-Request-Id": {
        "description": "Id of the request: the `X-Request-Id` you sent, or one generated by WeGuard. Every error body repeats it as `requestId`. Quote it when you contact support.",
        "schema": {
          "type": "string"
        },
        "example": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
      },
      "Cache-Control": {
        "description": "Set to `private, no-cache`: clients may store the response but must revalidate it before reuse. See [Conditional requests](https://weguard.ai/docs/conventions#etags).",
        "schema": {
          "type": "string",
          "enum": [
            "private, no-cache"
          ]
        }
      },
      "Cache-Control-Problem": {
        "description": "`no-store` on every problem response: error responses must not be cached.",
        "schema": {
          "type": "string",
          "enum": [
            "no-store"
          ]
        }
      },
      "ETag": {
        "description": "Entity tag of the response. Send it in `If-None-Match` to get `304 Not Modified` while the response is unchanged. See [Conditional requests](https://weguard.ai/docs/conventions#etags).",
        "schema": {
          "type": "string"
        }
      },
      "WWW-Authenticate": {
        "description": "Bearer challenge (RFC 6750): `error=\"invalid_request\"` for a malformed `Authorization` header, `error=\"invalid_token\"` for an unknown, expired or revoked key, and `error=\"insufficient_scope\"` with the missing `scope` on 403. Sent only on `401` responses and on `403 insufficient_scope`, never on `403 account_inactive`.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Unauthorized. The `code` is one of:\n\n- `missing_credentials`: The request has no `Authorization` header.\n- `invalid_authorization_header`: The `Authorization` header does not use the `Bearer` scheme, or has no key after it. The `WWW-Authenticate` header carries `error=\"invalid_request\"`.\n- `invalid_api_key`: The key is malformed, does not exist, or its secret does not match. The `WWW-Authenticate` header carries `error=\"invalid_token\"`.\n- `api_key_expired`: The key is past its `expiresAt`.\n- `api_key_revoked`: An account admin revoked the key. Revocation takes effect immediately and cannot be undone.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "WWW-Authenticate": {
            "$ref": "#/components/headers/WWW-Authenticate"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 401
                    },
                    "code": {
                      "enum": [
                        "missing_credentials",
                        "invalid_authorization_header",
                        "invalid_api_key",
                        "api_key_expired",
                        "api_key_revoked"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "missing_credentials": {
                "summary": "Missing credentials",
                "value": {
                  "type": "https://weguard.ai/docs/errors#missing_credentials",
                  "title": "Missing credentials",
                  "status": 401,
                  "code": "missing_credentials",
                  "detail": "The request has no Authorization header.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              },
              "invalid_authorization_header": {
                "summary": "Invalid Authorization header",
                "value": {
                  "type": "https://weguard.ai/docs/errors#invalid_authorization_header",
                  "title": "Invalid Authorization header",
                  "status": 401,
                  "code": "invalid_authorization_header",
                  "detail": "The Authorization header does not use the Bearer scheme, or has no key after it. The WWW-Authenticate header carries error=\"invalid_request\".",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              },
              "invalid_api_key": {
                "summary": "Invalid API key",
                "value": {
                  "type": "https://weguard.ai/docs/errors#invalid_api_key",
                  "title": "Invalid API key",
                  "status": 401,
                  "code": "invalid_api_key",
                  "detail": "The key is malformed, does not exist, or its secret does not match. The WWW-Authenticate header carries error=\"invalid_token\".",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              },
              "api_key_expired": {
                "summary": "API key expired",
                "value": {
                  "type": "https://weguard.ai/docs/errors#api_key_expired",
                  "title": "API key expired",
                  "status": 401,
                  "code": "api_key_expired",
                  "detail": "The key is past its expiresAt.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              },
              "api_key_revoked": {
                "summary": "API key revoked",
                "value": {
                  "type": "https://weguard.ai/docs/errors#api_key_revoked",
                  "title": "API key revoked",
                  "status": 401,
                  "code": "api_key_revoked",
                  "detail": "An account admin revoked the key. Revocation takes effect immediately and cannot be undone.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden. The `code` is one of:\n\n- `account_inactive`: The WeGuard account that owns the key has been deleted or disabled.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 403
                    },
                    "code": {
                      "enum": [
                        "account_inactive"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "account_inactive": {
                "summary": "Account inactive",
                "value": {
                  "type": "https://weguard.ai/docs/errors#account_inactive",
                  "title": "Account inactive",
                  "status": 403,
                  "code": "account_inactive",
                  "detail": "The WeGuard account that owns the key has been deleted or disabled.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      },
      "NotAcceptable": {
        "description": "Not Acceptable. The `code` is one of:\n\n- `not_acceptable`: The `Accept` header excludes JSON.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimit-Limit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimit-Remaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimit-Reset"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 406
                    },
                    "code": {
                      "enum": [
                        "not_acceptable"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "not_acceptable": {
                "summary": "Not acceptable",
                "value": {
                  "type": "https://weguard.ai/docs/errors#not_acceptable",
                  "title": "Not acceptable",
                  "status": 406,
                  "code": "not_acceptable",
                  "detail": "The Accept header excludes JSON.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Too Many Requests. The `code` is one of:\n\n- `rate_limit_exceeded`: The key has used up its request budget. See [Rate limits](https://weguard.ai/docs/rate-limits).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimit-Limit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimit-Remaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimit-Reset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 429
                    },
                    "code": {
                      "enum": [
                        "rate_limit_exceeded"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "rate_limit_exceeded": {
                "summary": "Rate limit exceeded",
                "value": {
                  "type": "https://weguard.ai/docs/errors#rate_limit_exceeded",
                  "title": "Rate limit exceeded",
                  "status": 429,
                  "code": "rate_limit_exceeded",
                  "detail": "The key has used up its request budget. See Rate limits.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Internal Server Error. The `code` is one of:\n\n- `internal_error`: An unexpected error occurred on our side.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimit-Limit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimit-Remaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimit-Reset"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 500
                    },
                    "code": {
                      "enum": [
                        "internal_error"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "internal_error": {
                "summary": "Internal server error",
                "value": {
                  "type": "https://weguard.ai/docs/errors#internal_error",
                  "title": "Internal server error",
                  "status": 500,
                  "code": "internal_error",
                  "detail": "An unexpected error occurred on our side.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Service Unavailable. The `code` is one of:\n\n- `service_unavailable`: A service WeGuard depends on is temporarily unavailable, or reading the data took longer than the time WeGuard allows for it. This can also happen while your key is being checked, so it can be returned before authentication completes. The response carries `Retry-After`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimit-Limit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimit-Remaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimit-Reset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control-Problem"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                {
                  "properties": {
                    "status": {
                      "const": 503
                    },
                    "code": {
                      "enum": [
                        "service_unavailable"
                      ]
                    }
                  }
                }
              ]
            },
            "examples": {
              "service_unavailable": {
                "summary": "Service unavailable",
                "value": {
                  "type": "https://weguard.ai/docs/errors#service_unavailable",
                  "title": "Service unavailable",
                  "status": 503,
                  "code": "service_unavailable",
                  "detail": "A service WeGuard depends on is temporarily unavailable, or reading the data took longer than the time WeGuard allows for it. This can also happen while your key is being checked, so it can be returned before authentication completes. The response carries Retry-After.",
                  "instance": "/core/v1/me",
                  "requestId": "req_k3j2h1g0f9e8d7c6b5a4z3y2"
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Account": {
        "type": "object",
        "description": "Your WeGuard account: plan, license usage, enabled platforms and the labels of the device tag slots.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Account id."
          },
          "object": {
            "type": "string",
            "const": "account",
            "description": "Always `account`."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Company name of the account."
          },
          "state": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "live",
              "trial",
              "demo",
              null
            ],
            "description": "Subscription state. `null` for internal test accounts and states not listed here."
          },
          "plan": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name of the feature plan as shown in the console, for example `Enterprise`. This is free text, not a fixed set. `null` if no plan is assigned."
          },
          "licenses": {
            "type": "object",
            "properties": {
              "purchased": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int64",
                "description": "Number of device licenses purchased. `null` when no purchased count is recorded for the account."
              },
              "provisionedDevices": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int64",
                "description": "Number of enrolled devices. This counter is refreshed periodically, so it is not a live count."
              },
              "unprovisionedDevices": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int64",
                "description": "Number of device records created but not yet enrolled. This counter is refreshed periodically, so it is not a live count."
              }
            },
            "required": [
              "purchased",
              "provisionedDevices",
              "unprovisionedDevices"
            ],
            "description": "License usage."
          },
          "licenseValidFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Start of the license period."
          },
          "licenseValidUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "End of the license period."
          },
          "trialEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "End of the trial period. `null` unless `state` is `trial`."
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "android",
                "ios",
                "macos",
                "tvos",
                "windows"
              ]
            },
            "description": "Device platforms enabled for the account. `ios` means Apple device management is enabled, which also covers Macs (`macos`) and Apple TVs (`tvos`)."
          },
          "mfaRequired": {
            "type": "boolean",
            "description": "`true` when multi-factor sign-in is enforced for the account’s console users."
          },
          "tagLabels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The names the account gave its device tag slots in the console, for example `{\"tag6\": \"Region\"}`. Use them to label the values in a device’s [`tags`](https://weguard.ai/docs/api/devices#the-device-object). Admins can label slots `tag6` to `tag9` in the console. Slots without a label, or still showing the console’s “Tag N” placeholder, are omitted, so the object can be empty."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the account was created."
          }
        },
        "required": [
          "id",
          "object",
          "name",
          "state",
          "plan",
          "licenses",
          "licenseValidFrom",
          "licenseValidUntil",
          "trialEndsAt",
          "platforms",
          "mfaRequired",
          "tagLabels",
          "createdAt"
        ],
        "examples": [
          {
            "id": "5f1d7c0e9b1e8a3f2c4d6e8a",
            "object": "account",
            "name": "Acme Logistics",
            "state": "live",
            "plan": "Enterprise",
            "licenses": {
              "purchased": 500,
              "provisionedDevices": 312,
              "unprovisionedDevices": 14
            },
            "licenseValidFrom": "2026-01-01T00:00:00Z",
            "licenseValidUntil": "2026-12-31T23:59:59Z",
            "trialEndsAt": null,
            "platforms": [
              "android",
              "ios",
              "windows"
            ],
            "mfaRequired": true,
            "tagLabels": {
              "tag6": "Region",
              "tag7": "Cost centre"
            },
            "createdAt": "2024-05-02T10:11:12Z"
          }
        ],
        "externalDocs": {
          "description": "The account object",
          "url": "https://weguard.ai/docs/api/account#the-account-object"
        }
      },
      "AndroidDetails": {
        "type": "object",
        "description": "`details` when `platform` is `android`.",
        "properties": {
          "deviceIdType": {
            "type": [
              "string",
              "null"
            ],
            "description": "Kind of hardware identifier the agent reported as the device id."
          },
          "suspended": {
            "type": "boolean",
            "description": "`true` when the device is suspended."
          },
          "wiped": {
            "type": "boolean",
            "description": "`true` when the device has been wiped."
          },
          "enterpriseEnrolled": {
            "type": "boolean",
            "description": "`true` when the device is enrolled with Android Enterprise."
          },
          "appliedPolicyVersion": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Version of the policy last applied on the device."
          },
          "mobileDataUsageBytes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Mobile data used, in bytes, as reported by the agent."
          },
          "wifiDataUsageBytes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Wi-Fi data used, in bytes, as reported by the agent."
          },
          "batteryLevel": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Battery level in percent, exactly as the agent reports it. Not range-checked. The device status `battery` leaves out a value outside 0 to 100."
          }
        },
        "required": [
          "deviceIdType",
          "suspended",
          "wiped",
          "enterpriseEnrolled",
          "appliedPolicyVersion",
          "mobileDataUsageBytes",
          "wifiDataUsageBytes",
          "batteryLevel"
        ],
        "examples": [
          {
            "deviceIdType": "IMEI",
            "suspended": false,
            "wiped": false,
            "enterpriseEnrolled": true,
            "appliedPolicyVersion": 42,
            "mobileDataUsageBytes": 1288490188,
            "wifiDataUsageBytes": 9663676416,
            "batteryLevel": 87
          }
        ],
        "externalDocs": {
          "description": "Android details",
          "url": "https://weguard.ai/docs/api/devices#android-details"
        }
      },
      "AppUsageDay": {
        "type": "object",
        "description": "Foreground time of one app on one device, for the sessions that started on one UTC day.",
        "properties": {
          "object": {
            "type": "string",
            "const": "app_usage_day",
            "description": "Always `app_usage_day`."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The UTC calendar day the sessions started on, `YYYY-MM-DD`. A session that runs past midnight counts in full on the day it started."
          },
          "app": {
            "type": "object",
            "properties": {
              "identifier": {
                "type": "string",
                "description": "The Windows process name without `.exe`, as the device reports it, for example `chrome`, `WINWORD` or `explorer`. Store apps report their own process, for example `CalculatorApp`, or `ApplicationFrameHost` when the agent could not resolve it. Microsoft Management Console (`mmc.exe`) is the exception: it is reported by its window title, for example `Computer Management`, `Event Viewer` or the name of a saved console. That title is free text and can include a file or computer name. The identifier does not match the `identifier` of [installed apps](https://weguard.ai/docs/api/installed-apps), which names apps by package family name or product code."
              }
            },
            "required": [
              "identifier"
            ],
            "description": "The app, as the device identifies it."
          },
          "foregroundSeconds": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Seconds the app’s window was in the foreground, summed over the day’s sessions. This is foreground time, not active input: a window left in front counts until another app, a lock, sign-out, sleep or shutdown takes the foreground."
          },
          "sessionCount": {
            "type": "integer",
            "format": "int32",
            "minimum": 1,
            "description": "Foreground sessions. Each runs from the app gaining the foreground to losing it."
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the latest of the day’s sessions ended. Sessions are not split at midnight, so this can fall on the next day. `null` when the device reported no end time."
          },
          "complete": {
            "type": "boolean",
            "description": "`false` for today (UTC), `true` once the UTC day has ended. As with screen time, a device that was offline can still upload a completed day late. Unlike screen time, a completed day can also grow on a device that stays online. A session is recorded only when it ends, and then counts in full on the day it started. An app still in the foreground at midnight therefore adds to that earlier, `complete` day when it loses the foreground. On a kiosk that never locks, that can be days later. To sync incrementally, re-read a trailing window, for example the last 7 days, not only the days that are not yet `complete`."
          }
        },
        "required": [
          "object",
          "date",
          "app",
          "foregroundSeconds",
          "sessionCount",
          "lastUsedAt",
          "complete"
        ],
        "examples": [
          {
            "object": "app_usage_day",
            "date": "2026-10-06",
            "app": {
              "identifier": "chrome"
            },
            "foregroundSeconds": 9842,
            "sessionCount": 57,
            "lastUsedAt": "2026-10-06T15:21:09Z",
            "complete": true
          }
        ],
        "externalDocs": {
          "description": "The app usage day object",
          "url": "https://weguard.ai/docs/api/usage#the-app-usage-day-object"
        }
      },
      "AppUsageDayList": {
        "type": "object",
        "description": "A list object whose `data` holds `app_usage_day` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AppUsageDay"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          },
          "collection": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "`true` when the device’s policy has Screen Time turned on."
              }
            },
            "required": [
              "enabled"
            ],
            "description": "Whether the device’s current policy collects usage. Days without data are left out of `data`. While `enabled` is `false`, a missing day means that nothing was collected, not that the device was unused. It describes the policy now, not on each listed day. A device picks up a policy change at its next sync."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor",
          "collection"
        ]
      },
      "AppleDetails": {
        "type": "object",
        "description": "`details` when `platform` is `ios`, `macos` or `tvos`. Capacity and battery values are strings exactly as reported by the device.",
        "properties": {
          "udid": {
            "type": [
              "string",
              "null"
            ],
            "description": "Apple unique device identifier."
          },
          "supervised": {
            "type": "boolean",
            "description": "`true` when the device is supervised."
          },
          "modelName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model name, for example `iPad`."
          },
          "productName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Product identifier, for example `iPad13,18`."
          },
          "buildVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "OS build number."
          },
          "deviceCapacity": {
            "type": [
              "string",
              "null"
            ],
            "description": "Total storage capacity as reported by the device."
          },
          "availableDeviceCapacity": {
            "type": [
              "string",
              "null"
            ],
            "description": "Available storage as reported by the device."
          },
          "batteryLevel": {
            "type": [
              "string",
              "null"
            ],
            "description": "Battery level as the device reports it: a fraction from 0 to 1, as a string, for example `\"0.85\"`. The device status `battery.level` gives it as a percentage."
          },
          "wifiMac": {
            "type": [
              "string",
              "null"
            ],
            "description": "Wi-Fi MAC address."
          },
          "bluetoothMac": {
            "type": [
              "string",
              "null"
            ],
            "description": "Bluetooth MAC address."
          },
          "iccid": {
            "type": [
              "string",
              "null"
            ],
            "description": "ICCID of the SIM card."
          },
          "carrier": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current carrier network."
          },
          "roaming": {
            "type": "boolean",
            "description": "`true` when the device is roaming."
          },
          "deviceFamily": {
            "type": [
              "string",
              "null"
            ],
            "description": "Device family, for example `iPad`."
          }
        },
        "required": [
          "udid",
          "supervised",
          "modelName",
          "productName",
          "buildVersion",
          "deviceCapacity",
          "availableDeviceCapacity",
          "batteryLevel",
          "wifiMac",
          "bluetoothMac",
          "iccid",
          "carrier",
          "roaming",
          "deviceFamily"
        ],
        "examples": [
          {
            "udid": "00008103-001A2B3C4D5E6F70",
            "supervised": true,
            "modelName": "iPad",
            "productName": "iPad13,18",
            "buildVersion": "22A3354",
            "deviceCapacity": "64.0",
            "availableDeviceCapacity": "41.7",
            "batteryLevel": "0.85",
            "wifiMac": "a4:83:e7:12:34:56",
            "bluetoothMac": "a4:83:e7:12:34:57",
            "iccid": null,
            "carrier": null,
            "roaming": false,
            "deviceFamily": "iPad"
          }
        ],
        "externalDocs": {
          "description": "Apple details",
          "url": "https://weguard.ai/docs/api/devices#apple-details"
        }
      },
      "AuditLog": {
        "type": "object",
        "description": "The console activity log of your WeGuard account: who did what and when, newest first.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique id of the entry."
          },
          "object": {
            "type": "string",
            "const": "audit_log",
            "description": "Always `audit_log`."
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "description": "When WeGuard recorded the entry. `since` / `until` filter on this time."
          },
          "actor": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "email": {
                "type": "string",
                "description": "Login email of the console user at the time of the action."
              }
            },
            "required": [
              "email"
            ],
            "description": "The console user who performed the action. `null` when the recorded actor is not an email address."
          },
          "event": {
            "type": [
              "string",
              "null"
            ],
            "description": "Event category recorded by the console, for example `Policy`, `Roles and Permissions` or `SSO`. Free-form text, not a closed set."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable description of the action. Credentials in the text are replaced with `[redacted]`."
          },
          "level": {
            "type": [
              "string",
              "null"
            ],
            "description": "Severity in lowercase, for example `info`, `warn` or `error`. Free-form text, not a closed set."
          },
          "sourceIp": {
            "type": [
              "string",
              "null"
            ],
            "description": "The public IP address the action came from: the nearest public address in the recorded forwarding chain. Best effort and for information only. `null` when no valid public IP address was recorded."
          },
          "policyId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Id of the [policy](https://weguard.ai/docs/api/policies) the action concerns. `null` unless a valid policy id was recorded."
          }
        },
        "required": [
          "id",
          "object",
          "occurredAt",
          "actor",
          "event",
          "message",
          "level",
          "sourceIp",
          "policyId"
        ],
        "examples": [
          {
            "id": "6702a4b8c9d0e1f2a3b4c5d6",
            "object": "audit_log",
            "occurredAt": "2026-10-07T08:15:02Z",
            "actor": {
              "email": "admin@acme.example"
            },
            "event": "Policy",
            "message": "Kiosk: Scanners updated",
            "level": "info",
            "sourceIp": "203.0.113.7",
            "policyId": "64ff0a1b2c3d4e5f60718293"
          }
        ],
        "externalDocs": {
          "description": "The audit log object",
          "url": "https://weguard.ai/docs/api/audit-logs#the-audit-log-object"
        }
      },
      "AuditLogList": {
        "type": "object",
        "description": "A list object whose `data` holds `audit_log` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuditLog"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "Device": {
        "type": "object",
        "description": "Inventory, enrollment, policy, compliance, security state, connectivity and status of your managed Android, Apple (iOS, iPadOS, macOS, tvOS) and Windows devices.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique device id."
          },
          "object": {
            "type": "string",
            "const": "device",
            "description": "Always `device`."
          },
          "platform": {
            "type": "string",
            "enum": [
              "android",
              "ios",
              "macos",
              "tvos",
              "windows"
            ],
            "description": "Device platform. `ios` covers iPhone, iPad and iPod touch. Macs are `macos` and Apple TVs are `tvos`."
          },
          "name": {
            "type": "string",
            "description": "Display name of the device. WeGuard uses the first of these that is set: the name an admin assigned in the console, the name the device reports, its model (Android and Apple), or the device’s identifier. On Windows the order is the device name, the DNS computer name, then the device identifier."
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model as reported by the device, for example `SM-T505`."
          },
          "manufacturer": {
            "type": [
              "string",
              "null"
            ],
            "description": "Manufacturer as reported by the device, for example `samsung`. Always `Apple` for Apple devices."
          },
          "osVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Operating system version. On Windows it can lag behind an in-place upgrade. For the current Windows build, see `updates.osBuild` in the [device status](https://weguard.ai/docs/api/devices#the-device-status-object)."
          },
          "serialNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "Hardware serial number."
          },
          "imei": {
            "type": [
              "string",
              "null"
            ],
            "description": "IMEI of devices with a cellular modem. Always `null` on Windows."
          },
          "phoneNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "Phone number of the SIM, when known. On Windows, the number the device reads from its SIM, so `null` on devices without one."
          },
          "agentVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version of the WeGuard agent on the device. Reported by Android and Windows devices. Always `null` on Apple devices."
          },
          "policy": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Policy id."
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Policy name."
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "The policy assigned to the device, or `null` if it has none. For the full policy, call [Retrieve a policy](https://weguard.ai/docs/api/policies#retrieve-policy)."
          },
          "enrollment": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "enrolled",
                  "pending",
                  "unenrolled"
                ],
                "description": "Enrollment status. `pending` means the device record exists but enrollment has not completed."
              },
              "enrolledAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "When the device enrolled. On Windows, when WeGuard created the device record, which is the date the console shows. `null` when unknown."
              }
            },
            "required": [
              "status",
              "enrolledAt"
            ],
            "description": "Enrollment state of the device."
          },
          "state": {
            "type": "object",
            "properties": {
              "lost": {
                "type": "boolean",
                "description": "`true` when lost or stolen mode is on. Always `false` on Windows, which has no lost mode."
              },
              "compromised": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "`true` when root or a jailbreak was detected on the device. `null` when the device has not reported it. Always `null` on Windows."
              },
              "locked": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "`true` when an admin locked the device. Android only. `null` on other platforms or when not reported."
              }
            },
            "required": [
              "lost",
              "compromised",
              "locked"
            ],
            "description": "Security-relevant flags."
          },
          "compliance": {
            "type": "object",
            "properties": {
              "policyCompliant": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "`true` when the device complies with its policy. `null` when not evaluated."
              },
              "appsCompliant": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "`true` when all apps required by the policy are installed. `null` when not evaluated."
              }
            },
            "required": [
              "policyCompliant",
              "appsCompliant"
            ],
            "description": "Result of the last compliance evaluation. Only Android devices are evaluated today."
          },
          "tags": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Values of the console tag slots `tag1` to `tag9`, for example `{\"tag1\": \"Dock 4\"}`. Empty slots are omitted, so the object can be empty. For the name your account gave each slot, such as \"Region\" for `tag6`, read [`tagLabels`](https://weguard.ai/docs/api/account#the-account-object) on the account."
          },
          "lastSeenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last contacted WeGuard, on any channel. On Windows that is the agent’s sync (about once a minute), an MDM session, a health or location report, or an answer to a check from the console. The value does not tell these apart. `null` when the device has never checked in."
          },
          "connectivity": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "online",
                  "offline",
                  "unknown"
                ],
                "description": "`online` when `lastSeenAt` is at most `thresholdMinutes` old, `offline` when it is older, and `unknown` when the device has never checked in (`lastSeenAt` is `null`). A `lastSeenAt` in the future, caused by clock skew, counts as `online`."
              },
              "thresholdMinutes": {
                "type": "integer",
                "format": "int32",
                "minimum": 1,
                "description": "Minutes after `lastSeenAt` at which the device counts as offline. Currently `1440` (24 hours). Read it from the response instead of hard-coding it."
              }
            },
            "required": [
              "status",
              "thresholdMinutes"
            ],
            "description": "Whether the device checked in recently. WeGuard works it out from `lastSeenAt` when it builds the response, with the same rule on every platform."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the device record was created."
          },
          "details": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AndroidDetails"
              },
              {
                "$ref": "#/components/schemas/AppleDetails"
              },
              {
                "$ref": "#/components/schemas/WindowsDetails"
              }
            ],
            "description": "Platform-specific attributes. The keys depend on `platform`. Values are strings, numbers, booleans or `null`, never nested objects. See [Android](https://weguard.ai/docs/api/devices#android-details), [Apple](https://weguard.ai/docs/api/devices#apple-details) and [Windows](https://weguard.ai/docs/api/devices#windows-details) details."
          }
        },
        "required": [
          "id",
          "object",
          "platform",
          "name",
          "model",
          "manufacturer",
          "osVersion",
          "serialNumber",
          "imei",
          "phoneNumber",
          "agentVersion",
          "policy",
          "enrollment",
          "state",
          "compliance",
          "tags",
          "lastSeenAt",
          "connectivity",
          "createdAt",
          "details"
        ],
        "examples": [
          {
            "id": "6523f1c2a7b9d40012345678",
            "object": "device",
            "platform": "android",
            "name": "Warehouse Scanner 12",
            "model": "SM-T505",
            "manufacturer": "samsung",
            "osVersion": "13",
            "serialNumber": "R9JN30ABCDE",
            "imei": "356938035643809",
            "phoneNumber": null,
            "agentVersion": "6.4.2",
            "policy": {
              "id": "64ff0a1b2c3d4e5f60718293",
              "name": "Kiosk: Scanners"
            },
            "enrollment": {
              "status": "enrolled",
              "enrolledAt": "2026-03-14T08:12:44Z"
            },
            "state": {
              "lost": false,
              "compromised": false,
              "locked": false
            },
            "compliance": {
              "policyCompliant": true,
              "appsCompliant": false
            },
            "tags": {
              "tag1": "Dock 4",
              "tag3": "Night shift"
            },
            "lastSeenAt": "2026-10-07T09:29:51Z",
            "connectivity": {
              "status": "online",
              "thresholdMinutes": 1440
            },
            "createdAt": "2026-03-14T08:10:02Z",
            "details": {
              "deviceIdType": "IMEI",
              "suspended": false,
              "wiped": false,
              "enterpriseEnrolled": true,
              "appliedPolicyVersion": 42,
              "mobileDataUsageBytes": 1288490188,
              "wifiDataUsageBytes": 9663676416,
              "batteryLevel": 87
            }
          }
        ],
        "externalDocs": {
          "description": "The device object",
          "url": "https://weguard.ai/docs/api/devices#the-device-object"
        }
      },
      "DeviceList": {
        "type": "object",
        "description": "A list object whose `data` holds `device` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Device"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "DeviceLocation": {
        "type": "object",
        "description": "The last location a device reported, in WGS 84 decimal degrees.",
        "properties": {
          "object": {
            "type": "string",
            "const": "device_location",
            "description": "Always `device_location`."
          },
          "deviceId": {
            "type": "string",
            "description": "Id of the device."
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "Latitude in decimal degrees."
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "Longitude in decimal degrees."
          },
          "accuracyMeters": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Horizontal accuracy radius in meters. Reported by Apple devices. `null` on Android and Windows, or when not reported."
          },
          "recordedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device captured the location."
          }
        },
        "required": [
          "object",
          "deviceId",
          "latitude",
          "longitude",
          "accuracyMeters",
          "recordedAt"
        ],
        "examples": [
          {
            "object": "device_location",
            "deviceId": "6523f1c2a7b9d40012345679",
            "latitude": 17.4474,
            "longitude": 78.3762,
            "accuracyMeters": 12.5,
            "recordedAt": "2026-10-07T09:20:00Z"
          }
        ],
        "externalDocs": {
          "description": "The device location object",
          "url": "https://weguard.ai/docs/api/devices#the-device-location-object"
        }
      },
      "DeviceStatus": {
        "type": "object",
        "description": "Operational status of one device. Sections the platform does not report are `null`. Today `updates`, `hardware`, `encryption` and `secureBoot` are reported by Windows devices only. Antivirus, firewall and lock state are not reported.",
        "properties": {
          "object": {
            "type": "string",
            "const": "device_status",
            "description": "Always `device_status`."
          },
          "deviceId": {
            "type": "string",
            "description": "Id of the device."
          },
          "platform": {
            "type": "string",
            "enum": [
              "android",
              "ios",
              "macos",
              "tvos",
              "windows"
            ],
            "description": "Platform of the device."
          },
          "lastSeenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last contacted WeGuard. Always the same value as `lastSeenAt` on the [device object](https://weguard.ai/docs/api/devices#the-device-object)."
          },
          "connectivity": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "online",
                  "offline",
                  "unknown"
                ],
                "description": "`online` when `lastSeenAt` is at most `thresholdMinutes` old, `offline` when it is older, and `unknown` when the device has never checked in (`lastSeenAt` is `null`). A `lastSeenAt` in the future, caused by clock skew, counts as `online`."
              },
              "thresholdMinutes": {
                "type": "integer",
                "format": "int32",
                "minimum": 1,
                "description": "Minutes after `lastSeenAt` at which the device counts as offline. Currently `1440` (24 hours). Read it from the response instead of hard-coding it."
              }
            },
            "required": [
              "status",
              "thresholdMinutes"
            ],
            "description": "Whether the device checked in recently. WeGuard works it out from `lastSeenAt` when it builds the response, with the same rule on every platform. Always the same value as `connectivity` on the [device object](https://weguard.ai/docs/api/devices#the-device-object)."
          },
          "battery": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "level": {
                "type": "integer",
                "format": "int32",
                "minimum": 0,
                "maximum": 100,
                "description": "Charge in percent, from 0 to 100."
              },
              "charging": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "`true` when the device is on external power, whether or not the battery is still charging. Windows only. `null` on other platforms."
              },
              "reportedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "When WeGuard last received the level. `null` on Apple devices, which do not record it."
              }
            },
            "required": [
              "level",
              "charging",
              "reportedAt"
            ],
            "description": "The device’s last battery report. `null` when the device has not reported a level or has no battery, such as a Windows desktop or virtual machine. On Windows it matches `batteryLevel`, `batteryCharging` and `batteryReportedAt` in [Windows details](https://weguard.ai/docs/api/devices#windows-details). On Apple devices, `details.batteryLevel` stays the fraction the device reports, such as `\"0.56\"`, while `level` is the percentage, `56`. On Android, `details.batteryLevel` is passed through as reported, while `battery` is `null` for a value outside 0 to 100."
          },
          "updates": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "complianceState": {
                "type": "string",
                "enum": [
                  "compliant",
                  "non_compliant",
                  "stale",
                  "unknown"
                ],
                "description": "`stale`: the last scan is 7 or more days old. WeGuard checks this when it builds the response, whatever state it stored. `unknown`: the device has not scanned yet, or its last scan failed. `non_compliant`: a critical or important update that is missing or failed was released more than the account’s service level ago (14 days unless configured), or a restart has been pending for 7 or more days. For an update without a release date, WeGuard counts from when it first detected the update. `compliant`: none of the above. Apart from `stale`, this is the state WeGuard last computed: on every scan the device uploads, and every hour while the account has patch management on."
              },
              "missingCriticalCount": {
                "type": "integer",
                "format": "int32",
                "description": "Applicable critical updates that are not installed."
              },
              "missingImportantCount": {
                "type": "integer",
                "format": "int32",
                "description": "Applicable important updates that are not installed."
              },
              "missingOtherCount": {
                "type": "integer",
                "format": "int32",
                "description": "Other applicable updates that are not installed."
              },
              "failedCount": {
                "type": "integer",
                "format": "int32",
                "description": "Updates whose installation failed."
              },
              "pendingRebootCount": {
                "type": "integer",
                "format": "int32",
                "description": "Installed updates that wait for a restart."
              },
              "pendingRebootSince": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Since when a restart has been pending. `null` when none is."
              },
              "lastScanAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "When the device last scanned for updates."
              },
              "osBuild": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Windows build and update revision from the last scan, for example `26200.9445`. The agent scans about every 22 hours, so this is usually more current than `osVersion` on the device object."
              },
              "osDisplayVersion": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Windows feature release from the last scan, for example `25H2`."
              }
            },
            "required": [
              "complianceState",
              "missingCriticalCount",
              "missingImportantCount",
              "missingOtherCount",
              "failedCount",
              "pendingRebootCount",
              "pendingRebootSince",
              "lastScanAt",
              "osBuild",
              "osDisplayVersion"
            ],
            "description": "Windows Update compliance, as computed by WeGuard patch management. `null` unless patch management has produced data for the device, which needs patch management turned on for both the account and the device’s policy. If the account later turns patch management off, the data stays available with the state last computed."
          },
          "hardware": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "sampledAt": {
                "type": "string",
                "format": "date-time",
                "description": "When the device took the sample, by the device’s own clock. WeGuard ignores samples dated more than 5 minutes ahead of its own clock."
              },
              "cpuUtilizationPercent": {
                "type": [
                  "number",
                  "null"
                ],
                "format": "double",
                "minimum": 0,
                "maximum": 100,
                "description": "Total CPU use in percent, from 0 to 100."
              },
              "memory": {
                "type": "object",
                "properties": {
                  "totalBytes": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "format": "int64",
                    "description": "Installed memory, in bytes."
                  },
                  "availableBytes": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "format": "int64",
                    "description": "Memory available for use, in bytes."
                  }
                },
                "required": [
                  "totalBytes",
                  "availableBytes"
                ],
                "description": "Physical memory. The device reports it in steps of 0.1 GiB, which WeGuard converts to bytes."
              },
              "drives": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Drive letter, for example `C:`."
                    },
                    "type": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "fixed",
                        "removable",
                        "network",
                        "optical",
                        null
                      ],
                      "description": "Kind of volume. `null` when the device reported no type it could classify."
                    },
                    "totalBytes": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "format": "int64",
                      "description": "Size of the volume, in bytes."
                    },
                    "freeBytes": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "format": "int64",
                      "description": "Free space, in bytes. A removable drive without media reports `0`."
                    }
                  },
                  "required": [
                    "name",
                    "type",
                    "totalBytes",
                    "freeBytes"
                  ]
                },
                "description": "Volumes with a drive letter, in the order the device reported them. The device reports sizes in whole GiB, rounded down, which WeGuard converts to bytes."
              }
            },
            "required": [
              "sampledAt",
              "cpuUtilizationPercent",
              "memory",
              "drives"
            ],
            "description": "The newest hardware health sample, as the device reported it. WeGuard does not verify these values. The WeGuard agent takes a sample every 15 minutes by default while the device’s policy has health checks turned on. `null` when the device sent no sample in the last 60 days, which is how long samples are kept."
          },
          "encryption": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "reportedAt": {
                "type": "string",
                "format": "date-time",
                "description": "When the device last reported a change. The agent reports on change and after each restart, so this time does not tell you how current the data is. WeGuard ignores reports dated more than 5 minutes in the future."
              },
              "drives": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "mountPoint": {
                      "type": "string",
                      "description": "Drive letter, for example `C:`."
                    },
                    "protectionStatus": {
                      "type": "string",
                      "enum": [
                        "on",
                        "off",
                        "unknown"
                      ],
                      "description": "Whether BitLocker protection is on."
                    },
                    "encryptionStatus": {
                      "type": "string",
                      "enum": [
                        "fully_decrypted",
                        "fully_encrypted",
                        "encryption_in_progress",
                        "decryption_in_progress",
                        "encryption_paused",
                        "decryption_paused",
                        "unknown"
                      ],
                      "description": "Encryption state of the volume."
                    },
                    "encryptionPercentage": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "format": "int32",
                      "minimum": 0,
                      "maximum": 100,
                      "description": "Share of the volume that is encrypted, in percent. `null` when the device did not report it."
                    },
                    "lockStatus": {
                      "type": "string",
                      "enum": [
                        "locked",
                        "unlocked",
                        "unknown"
                      ],
                      "description": "Whether the volume is locked."
                    }
                  },
                  "required": [
                    "mountPoint",
                    "protectionStatus",
                    "encryptionStatus",
                    "encryptionPercentage",
                    "lockStatus"
                  ]
                },
                "description": "BitLocker state of each volume. A value the device did not report, or that WeGuard does not recognize, reads `unknown`."
              },
              "tpm": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "present": {
                    "type": "boolean",
                    "description": "`false` when the agent found no TPM. The other members are then `null`."
                  },
                  "enabled": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Whether the TPM is enabled."
                  },
                  "activated": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Whether the TPM is activated."
                  },
                  "specVersion": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Version of the TPM specification the chip implements, for example `2.0` or `1.2`."
                  }
                },
                "required": [
                  "present",
                  "enabled",
                  "activated",
                  "specVersion"
                ],
                "description": "The Trusted Platform Module. `null` when the report included no TPM data."
              }
            },
            "required": [
              "reportedAt",
              "drives",
              "tpm"
            ],
            "description": "BitLocker and TPM state as the WeGuard agent last reported it. WeGuard does not verify these values. The agent reports them only for devices whose policy configures BitLocker. `null` when the agent has never reported them. Recovery keys and key protectors are never returned."
          },
          "secureBoot": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "`true` when UEFI Secure Boot is on. Only Windows 10 devices that run the WeGuard agent with patch management on report it, as part of the Windows 11 readiness check. `null` otherwise."
          }
        },
        "required": [
          "object",
          "deviceId",
          "platform",
          "lastSeenAt",
          "connectivity",
          "battery",
          "updates",
          "hardware",
          "encryption",
          "secureBoot"
        ],
        "examples": [
          {
            "object": "device_status",
            "deviceId": "6523f1c2a7b9d4001234567a",
            "platform": "windows",
            "lastSeenAt": "2026-10-07T09:29:51Z",
            "connectivity": {
              "status": "online",
              "thresholdMinutes": 1440
            },
            "battery": {
              "level": 87,
              "charging": true,
              "reportedAt": "2026-10-07T09:29:51Z"
            },
            "updates": {
              "complianceState": "non_compliant",
              "missingCriticalCount": 1,
              "missingImportantCount": 0,
              "missingOtherCount": 3,
              "failedCount": 0,
              "pendingRebootCount": 1,
              "pendingRebootSince": "2026-09-28T06:10:00Z",
              "lastScanAt": "2026-10-07T03:12:44Z",
              "osBuild": "26200.9445",
              "osDisplayVersion": "25H2"
            },
            "hardware": {
              "sampledAt": "2026-10-07T09:15:00Z",
              "cpuUtilizationPercent": 7,
              "memory": {
                "totalBytes": 25555055411,
                "availableBytes": 18253611008
              },
              "drives": [
                {
                  "name": "C:",
                  "type": "fixed",
                  "totalBytes": 254476812288,
                  "freeBytes": 179314884608
                },
                {
                  "name": "F:",
                  "type": "removable",
                  "totalBytes": 61203283968,
                  "freeBytes": 0
                }
              ]
            },
            "encryption": {
              "reportedAt": "2026-10-01T08:15:00Z",
              "drives": [
                {
                  "mountPoint": "C:",
                  "protectionStatus": "on",
                  "encryptionStatus": "fully_encrypted",
                  "encryptionPercentage": 100,
                  "lockStatus": "unlocked"
                }
              ],
              "tpm": {
                "present": true,
                "enabled": true,
                "activated": true,
                "specVersion": "2.0"
              }
            },
            "secureBoot": null
          }
        ],
        "externalDocs": {
          "description": "The device status object",
          "url": "https://weguard.ai/docs/api/devices#the-device-status-object"
        }
      },
      "InstalledApp": {
        "type": "object",
        "description": "The apps installed on a device, as the device last reported them.",
        "properties": {
          "object": {
            "type": "string",
            "const": "installed_app",
            "description": "Always `installed_app`."
          },
          "identifier": {
            "type": "string",
            "description": "Android package name, Apple bundle id, Windows Store package family name, or MSI/EXE product code (falls back to the display name)."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name. `null` when the platform does not report it. Android user apps report only the package name."
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "store",
              "private",
              "system",
              "msi",
              "exe",
              null
            ],
            "description": "How the app reached the device. `store`: installed from Google Play, the App Store or the Microsoft Store. Apple apps are `store` only when the device reports them as App Store apps. `private`: distributed privately. This covers Android private apps, Apple apps not from the App Store, and sideloaded Windows packages. `system`: bundled with the OS, such as Android pre-installed apps and Windows system packages. Returned only with `includeSystem=true`. `msi` / `exe`: Windows desktop apps. `null`: a Windows package whose origin the device has not reported yet. These apps are returned only when no `type` filter is sent."
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display version."
          },
          "versionCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Android version code. Always `null` on other platforms."
          },
          "installed": {
            "type": "boolean",
            "description": "`false` for an app that the device’s policy requires but that failed to install (Android). See `error` for details. Otherwise `true`."
          },
          "publisher": {
            "type": [
              "string",
              "null"
            ],
            "description": "Publisher of Windows desktop (`msi` / `exe`) apps."
          },
          "sizeBytes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "App size in bytes (Apple). `null` when the device does not report it."
          },
          "installedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Install date (Windows), when the device reports one that can be read. Devices usually report a local date without a time. The API returns it as that date at `T00:00:00Z`."
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Install state of Windows `msi` / `exe` apps, as reported by the device."
          },
          "error": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Platform-specific failure code, as reported. For information only."
              },
              "message": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Human-readable failure description, as reported."
              }
            },
            "required": [
              "code",
              "message"
            ],
            "description": "Install failure details reported by the platform, for an Android policy app that failed to install or a Windows `msi` / `exe` app with a non-zero error code. Otherwise `null`."
          }
        },
        "required": [
          "object",
          "identifier",
          "name",
          "type",
          "version",
          "versionCode",
          "installed",
          "publisher",
          "sizeBytes",
          "installedAt",
          "status",
          "error"
        ],
        "examples": [
          {
            "object": "installed_app",
            "identifier": "{8A69D345-D564-463C-AFF1-A69D9E530F96}",
            "name": "Google Chrome",
            "type": "msi",
            "version": "126.0.6478.127",
            "versionCode": null,
            "installed": true,
            "publisher": "Google LLC",
            "sizeBytes": null,
            "installedAt": "2026-08-21T00:00:00Z",
            "status": "Installed",
            "error": null
          }
        ],
        "externalDocs": {
          "description": "The installed app object",
          "url": "https://weguard.ai/docs/api/installed-apps#the-installed-app-object"
        }
      },
      "InstalledAppList": {
        "type": "object",
        "description": "A list object whose `data` holds `installed_app` objects. Not paginated: every item comes back in one response.",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstalledApp"
            },
            "description": "Every matching item."
          },
          "hasMore": {
            "type": "boolean",
            "const": false,
            "description": "Always `false`: this list is not paginated and returns every matching item at once."
          },
          "nextCursor": {
            "type": "null",
            "const": null,
            "description": "Always `null`: this list is not paginated."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "LocationPoint": {
        "type": "object",
        "description": "One reported position, in WGS 84 decimal degrees. Optional measurements are `null` when the device did not report them or reported an invalid value. Points without valid coordinates are never returned.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique id of the location point."
          },
          "object": {
            "type": "string",
            "const": "location_point",
            "description": "Always `location_point`."
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "Latitude in decimal degrees."
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "Longitude in decimal degrees."
          },
          "accuracyMeters": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Horizontal accuracy radius in meters."
          },
          "altitudeMeters": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Altitude in meters, as reported by the device. Android and Windows devices report `0` when the altitude is unknown."
          },
          "speedMetersPerSecond": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Ground speed in meters per second. Android and Windows devices report `0` when the speed is unknown."
          },
          "headingDegrees": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Direction of travel in degrees (0 to 360), clockwise from true north. Reported by Apple devices only. Always `null` on Android and Windows."
          },
          "recordedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the device captured the location."
          }
        },
        "required": [
          "id",
          "object",
          "latitude",
          "longitude",
          "accuracyMeters",
          "altitudeMeters",
          "speedMetersPerSecond",
          "headingDegrees",
          "recordedAt"
        ],
        "examples": [
          {
            "id": "6701c2e5f1a2b3c4d5e6f789",
            "object": "location_point",
            "latitude": 17.4474,
            "longitude": 78.3762,
            "accuracyMeters": 12.4,
            "altitudeMeters": 512.3,
            "speedMetersPerSecond": 0.3,
            "headingDegrees": null,
            "recordedAt": "2026-10-07T09:20:00Z"
          }
        ],
        "externalDocs": {
          "description": "The location point object",
          "url": "https://weguard.ai/docs/api/location-history#the-location-point-object"
        }
      },
      "LocationPointList": {
        "type": "object",
        "description": "A list object whose `data` holds `location_point` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocationPoint"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "Me": {
        "type": "object",
        "description": "Identity of the calling API key and the account that owns it.",
        "properties": {
          "object": {
            "type": "string",
            "const": "me",
            "description": "Always `me`."
          },
          "account": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Account id."
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Company name of the account."
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "The WeGuard account the key belongs to. A key can only read this account’s data."
          },
          "apiKey": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Unique id of the API key record (24 hex characters). This is not the `<keyId>` part of the key. To match the key shown in the console, use `prefix`."
              },
              "name": {
                "type": "string",
                "description": "Label given to the key when it was created."
              },
              "prefix": {
                "type": "string",
                "description": "Public, non-secret part of the key: `wgk_<keyId>`. Safe to log."
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Scopes granted to the key, sorted. See [Authorization](https://weguard.ai/docs/authorization)."
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "description": "When the key was created."
              },
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "When the key expires. `null` if it never expires."
              }
            },
            "required": [
              "id",
              "name",
              "prefix",
              "scopes",
              "createdAt",
              "expiresAt"
            ],
            "description": "The key used for this request. The secret is never returned."
          }
        },
        "required": [
          "object",
          "account",
          "apiKey"
        ],
        "examples": [
          {
            "object": "me",
            "account": {
              "id": "5f1d7c0e9b1e8a3f2c4d6e8a",
              "name": "Acme Logistics"
            },
            "apiKey": {
              "id": "6701a2b3c4d5e6f708192a3b",
              "name": "CMDB sync",
              "prefix": "wgk_1a2b3c4d5e6f7a8b",
              "scopes": [
                "devices:read"
              ],
              "createdAt": "2026-10-01T10:00:00Z",
              "expiresAt": "2026-12-30T10:00:00Z"
            }
          }
        ],
        "externalDocs": {
          "description": "The me object",
          "url": "https://weguard.ai/docs/api/me#the-me-object"
        }
      },
      "Policy": {
        "type": "object",
        "description": "Device policies across platforms, how many devices each one manages, and which devices are assigned to it.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique policy id."
          },
          "object": {
            "type": "string",
            "const": "policy",
            "description": "Always `policy`."
          },
          "platform": {
            "type": "string",
            "enum": [
              "android",
              "ios",
              "macos",
              "tvos",
              "windows"
            ],
            "description": "Platform the policy targets. Mac policies are `macos`, Apple TV policies `tvos`."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Policy name as shown in the console. `null` only for malformed legacy records."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description entered in the console."
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Platform-specific policy variant as shown in the console, for example `ANDROID_KIOSK`. For information only. New values may appear."
          },
          "deviceCount": {
            "type": "integer",
            "format": "int64",
            "description": "Number of devices currently assigned to the policy. This is the same count the console shows."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the policy was created."
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the policy was last changed."
          }
        },
        "required": [
          "id",
          "object",
          "platform",
          "name",
          "description",
          "type",
          "deviceCount",
          "createdAt",
          "updatedAt"
        ],
        "examples": [
          {
            "id": "64ff0a1b2c3d4e5f60718293",
            "object": "policy",
            "platform": "android",
            "name": "Kiosk: Scanners",
            "description": "Locked-down scanner devices",
            "type": "ANDROID_KIOSK",
            "deviceCount": 128,
            "createdAt": "2026-01-09T11:00:00Z",
            "updatedAt": "2026-09-30T16:42:10Z"
          }
        ],
        "externalDocs": {
          "description": "The policy object",
          "url": "https://weguard.ai/docs/api/policies#the-policy-object"
        }
      },
      "PolicyList": {
        "type": "object",
        "description": "A list object whose `data` holds `policy` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Policy"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "ProblemDetails": {
        "type": "object",
        "description": "An error: RFC 9457 problem details served as `application/problem+json`, with a stable `code`. Members without a value are omitted. See [Errors](https://weguard.ai/docs/errors).",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI that identifies the problem: `https://weguard.ai/docs/errors#<code>`, which is the code's entry in the docs."
          },
          "title": {
            "type": "string",
            "description": "Short, human-readable summary of the problem type. The same for every occurrence of a code."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code, repeated for convenience."
          },
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code. Branch on this value. Codes are never renamed, but new codes may be added."
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation of this occurrence. The wording may change, so do not parse it."
          },
          "instance": {
            "type": "string",
            "description": "The request path that failed."
          },
          "requestId": {
            "type": "string",
            "description": "Id of the request, also in the `X-Request-Id` header. Quote it when you contact support."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProblemFieldError"
            },
            "description": "Per-parameter problems. Present only when specific parameters are at fault."
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "requestId"
        ],
        "externalDocs": {
          "description": "Errors",
          "url": "https://weguard.ai/docs/errors"
        }
      },
      "ProblemFieldError": {
        "type": "object",
        "description": "A problem with one parameter.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The parameter at fault, for example `limit`."
          },
          "code": {
            "type": "string",
            "description": "Error code for this parameter."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation."
          }
        },
        "required": [
          "field",
          "code",
          "message"
        ]
      },
      "ScreenTimeDay": {
        "type": "object",
        "description": "Screen time and up time of one device on one UTC day.",
        "properties": {
          "object": {
            "type": "string",
            "const": "screen_time_day",
            "description": "Always `screen_time_day`."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The UTC calendar day, `YYYY-MM-DD`."
          },
          "dayStart": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the day, midnight UTC, inclusive."
          },
          "dayEnd": {
            "type": "string",
            "format": "date-time",
            "description": "End of the day, the next midnight UTC, exclusive."
          },
          "screenTimeSeconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0,
            "maximum": 86400,
            "description": "Seconds during which a user was signed in with the session unlocked, from sign-in or unlock until lock, sign-out, sleep or shutdown. Summed over the device’s user sessions and capped at 86400. This is session time, not display-on time or active input, so a kiosk that never locks counts the whole day. `null` when no session was reported for the day, for example when the device was on but nobody signed in."
          },
          "upTimeSeconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0,
            "maximum": 86400,
            "description": "Seconds the device was powered on and not asleep, at most 86400. `null` when no up time was reported for the day."
          },
          "complete": {
            "type": "boolean",
            "description": "`false` for today (UTC). Only sessions that have ended are counted, so today’s values grow during the day. A running session is added when it ends, or at midnight UTC, when the agent splits it. Earlier days are `true`, but a device that was offline can still upload them late."
          }
        },
        "required": [
          "object",
          "date",
          "dayStart",
          "dayEnd",
          "screenTimeSeconds",
          "upTimeSeconds",
          "complete"
        ],
        "examples": [
          {
            "object": "screen_time_day",
            "date": "2026-10-06",
            "dayStart": "2026-10-06T00:00:00Z",
            "dayEnd": "2026-10-07T00:00:00Z",
            "screenTimeSeconds": 27315,
            "upTimeSeconds": 33960,
            "complete": true
          }
        ],
        "externalDocs": {
          "description": "The screen time day object",
          "url": "https://weguard.ai/docs/api/usage#the-screen-time-day-object"
        }
      },
      "ScreenTimeDayList": {
        "type": "object",
        "description": "A list object whose `data` holds `screen_time_day` objects. Not paginated: every item comes back in one response.",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScreenTimeDay"
            },
            "description": "Every matching item."
          },
          "hasMore": {
            "type": "boolean",
            "const": false,
            "description": "Always `false`: this list is not paginated and returns every matching item at once."
          },
          "nextCursor": {
            "type": "null",
            "const": null,
            "description": "Always `null`: this list is not paginated."
          },
          "collection": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "`true` when the device’s policy has Screen Time turned on."
              }
            },
            "required": [
              "enabled"
            ],
            "description": "Whether the device’s current policy collects usage. Days without data are left out of `data`. While `enabled` is `false`, a missing day means that nothing was collected, not that the device was unused. It describes the policy now, not on each listed day. A device picks up a policy change at its next sync."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor",
          "collection"
        ]
      },
      "User": {
        "type": "object",
        "description": "The admins and operators who sign in to your account’s console, with their roles and the policies they can access.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique user id."
          },
          "object": {
            "type": "string",
            "const": "user",
            "description": "Always `user`."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "The email address the user signs in with. `null` only for malformed legacy records."
          },
          "firstName": {
            "type": [
              "string",
              "null"
            ],
            "description": "First name."
          },
          "lastName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last name."
          },
          "role": {
            "type": "string",
            "description": "Console role, for example `customer_admin` (full access), `group_admin` or `observer` (read-only). New roles may appear. Users without a stored role are reported as `customer_admin`, because that is how the console treats them."
          },
          "mfaEnabled": {
            "type": "boolean",
            "description": "`true` when the user has completed multi-factor authentication setup, so it is enforced at sign-in. A setup that was started but not finished does not count."
          },
          "emailVerified": {
            "type": "boolean",
            "description": "`true` when the user verified their email address."
          },
          "ssoLinked": {
            "type": "boolean",
            "description": "`true` when the user’s login is linked to single sign-on."
          },
          "lastLoginAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the user last signed in."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the user was created."
          },
          "policyScope": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "allPolicies": {
                "type": "boolean",
                "description": "`true` when the user can access every policy. `policyIds` is then empty."
              },
              "policyIds": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Ids of the [policies](https://weguard.ai/docs/api/policies) the user can access."
              }
            },
            "required": [
              "allPolicies",
              "policyIds"
            ],
            "description": "For roles limited to specific policies, the policies the user can see and manage. `null` for `customer_admin`, who can access everything, and when no policy assignment is recorded for the user."
          }
        },
        "required": [
          "id",
          "object",
          "email",
          "firstName",
          "lastName",
          "role",
          "mfaEnabled",
          "emailVerified",
          "ssoLinked",
          "lastLoginAt",
          "createdAt",
          "policyScope"
        ],
        "examples": [
          {
            "id": "5f2a9c3e1b7d4a6f8e0c2b41",
            "object": "user",
            "email": "jane@acme.example",
            "firstName": "Jane",
            "lastName": "Doe",
            "role": "group_admin",
            "mfaEnabled": true,
            "emailVerified": true,
            "ssoLinked": false,
            "lastLoginAt": "2026-10-06T14:02:11Z",
            "createdAt": "2025-02-11T09:00:00Z",
            "policyScope": {
              "allPolicies": false,
              "policyIds": [
                "64ff0a1b2c3d4e5f60718293"
              ]
            }
          }
        ],
        "externalDocs": {
          "description": "The user object",
          "url": "https://weguard.ai/docs/api/users#the-user-object"
        }
      },
      "UserList": {
        "type": "object",
        "description": "A list object whose `data` holds `user` objects. See [Pagination](https://weguard.ai/docs/pagination).",
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/User"
            },
            "description": "The items of this page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "`true` when there may be more items after this page. To get the next page, pass `nextCursor` as `cursor`. A page can hold fewer than `limit` items, or none, while `hasMore` is `true`."
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page. `null` when `hasMore` is `false`. Send it back unchanged, with the same filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total number of matching items. Present only when the request sets `includeTotal=true`."
          }
        },
        "required": [
          "object",
          "data",
          "hasMore",
          "nextCursor"
        ]
      },
      "WindowsDetails": {
        "type": "object",
        "description": "`details` when `platform` is `windows`. Inventory values such as storage and memory are strings, exactly as the device reports them.",
        "properties": {
          "deviceId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Windows device identifier the device registered with WeGuard."
          },
          "hardwareDeviceId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Hardware identifier the device reports."
          },
          "osEdition": {
            "type": [
              "string",
              "null"
            ],
            "description": "Windows edition, as the numeric edition id the device reports, for example `48` (Pro), `4` (Enterprise), `121` (Education) or `101` (Home)."
          },
          "dnsComputerName": {
            "type": [
              "string",
              "null"
            ],
            "description": "DNS computer name."
          },
          "processorArchitecture": {
            "type": [
              "string",
              "null"
            ],
            "description": "Processor architecture as the device reports it, usually the numeric Windows value: `9` (x64), `12` (ARM64) or `0` (x86). Devices managed only through the WeGuard agent do not report it."
          },
          "totalStorage": {
            "type": [
              "string",
              "null"
            ],
            "description": "Size of the first internal drive in mebibytes (MiB), as a decimal string, for example `\"242935\"` (about 237 GiB). For every drive and its free space in bytes, see [device status](https://weguard.ai/docs/api/devices#the-device-status-object)."
          },
          "totalRam": {
            "type": [
              "string",
              "null"
            ],
            "description": "Installed memory in mebibytes (MiB), as a decimal string, for example `\"16384\"` (16 GiB)."
          },
          "wlanMacAddress": {
            "type": [
              "string",
              "null"
            ],
            "description": "Wireless LAN MAC address, for example `3C-22-FB-12-34-56`."
          },
          "wlanIpv4Address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Wireless LAN IPv4 address."
          },
          "weshieldInstalled": {
            "type": "boolean",
            "description": "`true` when WeShield is installed."
          },
          "weshieldVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Installed WeShield version."
          },
          "wesupportVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Installed WeSupport version."
          },
          "weguardRmmVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Installed WeGuard RMM version."
          },
          "batteryLevel": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0,
            "maximum": 100,
            "description": "Battery charge in percent, from 0 to 100. `null` when the device has not reported a level or has no battery. Desktops and virtual machines report no battery."
          },
          "batteryCharging": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "`true` when the device is on external power, whether or not the battery is still charging. `null` when `batteryLevel` is `null`."
          },
          "batteryReportedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last reported its battery level. `null` when `batteryLevel` is `null`."
          },
          "managementMode": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "mdm",
              "agent",
              null
            ],
            "description": "How WeGuard manages the device. `mdm`: through Windows MDM (OMA-DM). Devices enrolled before agent mode existed are all `mdm`. `agent`: only through the WeGuard agent, for example on Windows Home. `null` when the device record is incomplete."
          },
          "enrollmentType": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "enrollment_code",
              "entra_id",
              "provisioning_package",
              "agent",
              null
            ],
            "description": "How the device enrolled. `enrollment_code`: from Windows Settings with a WeGuard enrollment code address. `entra_id`: through Microsoft Entra ID, including Entra join and Windows Autopilot. `provisioning_package`: bulk enrollment with a provisioning package. `agent`: registered by the WeGuard agent without MDM. WeGuard records the value at enrollment. For devices that enrolled before WeGuard recorded it, the value was filled in later from other enrollment data and can be wrong. `null` when no value was recorded."
          },
          "lastMdmSessionAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last had an MDM session with WeGuard. For `agent` devices, when the agent last checked for commands."
          },
          "kioskStatus": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "none",
              "sent",
              "rejected",
              null
            ],
            "description": "Where kiosk delivery stands. It describes what WeGuard sent, not what the device did. `none`: WeGuard currently sends no kiosk configuration. The policy has no kiosk, the kiosk is paused or was removed, WeGuard cannot build one for the device yet, or a configuration waits to be sent again. `sent`: WeGuard queued or delivered a kiosk configuration and the device has not rejected it. This does not confirm that the device applied it: an offline device reads `sent` too, and while the agent removes an agent-enforced kiosk, the value stays `sent` until the agent reports the removal done. `rejected`: the device rejected the current configuration 3 times in a row, and WeGuard stopped sending it until the kiosk policy changes. `null` when the device record is incomplete."
          },
          "kioskPaused": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "`true` while kiosk maintenance mode is on: the kiosk is taken down on the device while the policy keeps it. `false` when never set. `null` when the device record is incomplete."
          },
          "kioskLastVerifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last confirmed that it holds a kiosk configuration: a read-back that matched what WeGuard sent (MDM-enforced kiosks) or the agent’s completion report (agent-enforced kiosks). WeGuard does not reset it when it sends a new configuration or removes the kiosk, so it can belong to an earlier configuration. `null` when the device has never confirmed one."
          }
        },
        "required": [
          "deviceId",
          "hardwareDeviceId",
          "osEdition",
          "dnsComputerName",
          "processorArchitecture",
          "totalStorage",
          "totalRam",
          "wlanMacAddress",
          "wlanIpv4Address",
          "weshieldInstalled",
          "weshieldVersion",
          "wesupportVersion",
          "weguardRmmVersion",
          "batteryLevel",
          "batteryCharging",
          "batteryReportedAt",
          "managementMode",
          "enrollmentType",
          "lastMdmSessionAt",
          "kioskStatus",
          "kioskPaused",
          "kioskLastVerifiedAt"
        ],
        "examples": [
          {
            "deviceId": "A4C123B1612DD272D1371C17149D4395",
            "hardwareDeviceId": "36B3216FDAEEB975729FAE923D5A4FD12AABFE228F219E9CB0EB53F16947CCF2",
            "osEdition": "48",
            "dnsComputerName": "FRONTDESK-07",
            "processorArchitecture": "9",
            "totalStorage": "242935",
            "totalRam": "24576",
            "wlanMacAddress": "3C-22-FB-12-34-56",
            "wlanIpv4Address": "10.20.4.117",
            "weshieldInstalled": true,
            "weshieldVersion": "2.3.1",
            "wesupportVersion": "1.8.0",
            "weguardRmmVersion": "1.2.4",
            "batteryLevel": 87,
            "batteryCharging": true,
            "batteryReportedAt": "2026-10-07T09:29:51Z",
            "managementMode": "mdm",
            "enrollmentType": "entra_id",
            "lastMdmSessionAt": "2026-10-07T09:12:30Z",
            "kioskStatus": "none",
            "kioskPaused": false,
            "kioskLastVerifiedAt": null
          }
        ],
        "externalDocs": {
          "description": "Windows details",
          "url": "https://weguard.ai/docs/api/devices#windows-details"
        }
      }
    }
  }
}
